Commit 43d9d604 authored by Gerd Hoffmann's avatar Gerd Hoffmann

xhci: prepare xhci_runtime_{read,write} for multiple interrupters

Prepare xhci runtime register access function for multiple interrupters.
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 962d11e1
...@@ -2586,37 +2586,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) ...@@ -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) static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
{ {
XHCIInterrupter *intr = &xhci->intr[0]; uint32_t ret = 0;
uint32_t ret;
switch (reg) { if (reg < 0x20) {
case 0x00: /* MFINDEX */ switch (reg) {
ret = xhci_mfindex_get(xhci) & 0x3fff; case 0x00: /* MFINDEX */
break; ret = xhci_mfindex_get(xhci) & 0x3fff;
case 0x20: /* IMAN */ break;
ret = intr->iman; default:
break; fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
case 0x24: /* IMOD */ break;
ret = intr->imod; }
break; } else {
case 0x28: /* ERSTSZ */ int v = (reg - 0x20) / 0x20;
ret = intr->erstsz; XHCIInterrupter *intr = &xhci->intr[v];
break; switch (reg & 0x1f) {
case 0x30: /* ERSTBA low */ case 0x00: /* IMAN */
ret = intr->erstba_low; ret = intr->iman;
break; break;
case 0x34: /* ERSTBA high */ case 0x04: /* IMOD */
ret = intr->erstba_high; ret = intr->imod;
break; break;
case 0x38: /* ERDP low */ case 0x08: /* ERSTSZ */
ret = intr->erdp_low; ret = intr->erstsz;
break; break;
case 0x3c: /* ERDP high */ case 0x10: /* ERSTBA low */
ret = intr->erdp_high; ret = intr->erstba_low;
break; break;
default: case 0x14: /* ERSTBA high */
fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); ret = intr->erstba_high;
ret = 0; 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); trace_usb_xhci_runtime_read(reg, ret);
...@@ -2625,43 +2631,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) ...@@ -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) 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); trace_usb_xhci_runtime_write(reg, val);
switch (reg) { if (reg < 0x20) {
case 0x20: /* IMAN */ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
return;
}
switch (reg & 0x1f) {
case 0x00: /* IMAN */
if (val & IMAN_IP) { if (val & IMAN_IP) {
intr->iman &= ~IMAN_IP; intr->iman &= ~IMAN_IP;
} }
intr->iman &= ~IMAN_IE; intr->iman &= ~IMAN_IE;
intr->iman |= val & IMAN_IE; intr->iman |= val & IMAN_IE;
xhci_intx_update(xhci); if (v == 0) {
xhci_msix_update(xhci, 0); xhci_intx_update(xhci);
}
xhci_msix_update(xhci, v);
break; break;
case 0x24: /* IMOD */ case 0x04: /* IMOD */
intr->imod = val; intr->imod = val;
break; break;
case 0x28: /* ERSTSZ */ case 0x08: /* ERSTSZ */
intr->erstsz = val & 0xffff; intr->erstsz = val & 0xffff;
break; break;
case 0x30: /* ERSTBA low */ case 0x10: /* ERSTBA low */
/* XXX NEC driver bug: it doesn't align this to 64 bytes /* XXX NEC driver bug: it doesn't align this to 64 bytes
intr->erstba_low = val & 0xffffffc0; */ intr->erstba_low = val & 0xffffffc0; */
intr->erstba_low = val & 0xfffffff0; intr->erstba_low = val & 0xfffffff0;
break; break;
case 0x34: /* ERSTBA high */ case 0x14: /* ERSTBA high */
intr->erstba_high = val; intr->erstba_high = val;
xhci_er_reset(xhci, 0); xhci_er_reset(xhci, v);
break; break;
case 0x38: /* ERDP low */ case 0x18: /* ERDP low */
if (val & ERDP_EHB) { if (val & ERDP_EHB) {
intr->erdp_low &= ~ERDP_EHB; intr->erdp_low &= ~ERDP_EHB;
} }
intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB);
break; break;
case 0x3c: /* ERDP high */ case 0x1c: /* ERDP high */
intr->erdp_high = val; intr->erdp_high = val;
xhci_events_update(xhci, 0); xhci_events_update(xhci, v);
break; break;
default: default:
fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment