diff --git a/qemu-testsuite.changes b/qemu-testsuite.changes index b28b92e1..b6f3764d 100644 --- a/qemu-testsuite.changes +++ b/qemu-testsuite.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Nov 28 20:21:27 UTC 2016 - afaerber@suse.de + +- slof_xhci.patch: XHCI fixes (boo#977027) + ------------------------------------------------------------------- Mon Nov 28 18:18:56 UTC 2016 - afaerber@suse.de diff --git a/qemu-testsuite.spec b/qemu-testsuite.spec index 73ac4c65..4f525dc4 100644 --- a/qemu-testsuite.spec +++ b/qemu-testsuite.spec @@ -179,7 +179,8 @@ Patch1200: sgabios-stable-buildid.patch %if %{build_slof_from_source} # SLOF -# (currently no patches) +# PATCH-FIX-UPSTREAM slof_xhci.patch afaerber@suse.de -- XHCI fixes +Patch1300: slof_xhci.patch %endif # this is to make lint happy @@ -846,7 +847,7 @@ done %if %{build_slof_from_source} pushd roms/SLOF -# (currently no patches) +%patch1300 -p1 popd rm -f pc-bios/slof.bin %endif diff --git a/qemu.changes b/qemu.changes index b28b92e1..b6f3764d 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Nov 28 20:21:27 UTC 2016 - afaerber@suse.de + +- slof_xhci.patch: XHCI fixes (boo#977027) + ------------------------------------------------------------------- Mon Nov 28 18:18:56 UTC 2016 - afaerber@suse.de diff --git a/qemu.spec b/qemu.spec index c1a64172..cfc6cc61 100644 --- a/qemu.spec +++ b/qemu.spec @@ -179,7 +179,8 @@ Patch1200: sgabios-stable-buildid.patch %if %{build_slof_from_source} # SLOF -# (currently no patches) +# PATCH-FIX-UPSTREAM slof_xhci.patch afaerber@suse.de -- XHCI fixes +Patch1300: slof_xhci.patch %endif # this is to make lint happy @@ -846,7 +847,7 @@ done %if %{build_slof_from_source} pushd roms/SLOF -# (currently no patches) +%patch1300 -p1 popd rm -f pc-bios/slof.bin %endif diff --git a/qemu.spec.in b/qemu.spec.in index 9d6a1cf2..84b96c5c 100644 --- a/qemu.spec.in +++ b/qemu.spec.in @@ -111,7 +111,8 @@ Patch1200: sgabios-stable-buildid.patch %if %{build_slof_from_source} # SLOF -# (currently no patches) +# PATCH-FIX-UPSTREAM slof_xhci.patch afaerber@suse.de -- XHCI fixes +Patch1300: slof_xhci.patch %endif # this is to make lint happy @@ -710,7 +711,7 @@ done %if %{build_slof_from_source} pushd roms/SLOF -# (currently no patches) +%patch1300 -p1 popd rm -f pc-bios/slof.bin %endif diff --git a/slof_xhci.patch b/slof_xhci.patch new file mode 100644 index 00000000..f04e3888 --- /dev/null +++ b/slof_xhci.patch @@ -0,0 +1,155 @@ +From ca8fb51e05feca057721d72cb194cd0636c73847 Mon Sep 17 00:00:00 2001 +From: Nikunj A Dadhania +Date: Mon, 2 May 2016 10:16:44 +0530 +Subject: [PATCH] xhci: fix missing keys from keyboard + +Current handling of the keyboard polling was very slow and +keys were getting dropped. Done following for fixing this: + +* Use multiple buffers per TRB +* Allocate buffers in xhci according to the number of TRBS. + +This reduces the delay of key? processing by getting rid of wait in +the polling routine. + +Reported-by: Dinar Valeev +Signed-off-by: Nikunj A Dadhania +Tested-by: Dinar Valeev +Tested-by: Thomas Huth +Signed-off-by: Alexey Kardashevskiy +--- + lib/libusb/usb-xhci.c | 51 +++++++++++++++++++++++++++++++++++++----------- + lib/libusb/usb-xhci.h | 2 + + 2 files changed, 41 insertions(+), 12 deletions(-) + +diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c +index 070c2ef..3bbc9af 100644 +--- a/lib/libusb/usb-xhci.c ++++ b/lib/libusb/usb-xhci.c +@@ -238,7 +238,7 @@ static uint64_t xhci_poll_event(struct xhci_hcd *xhcd, + flags = le32_to_cpu(event->flags); + + dprintf("Reading from event ptr %p %08x\n", event, flags); +- time = SLOF_GetTimer() + USB_TIMEOUT; ++ time = SLOF_GetTimer() + ((event_type == XHCI_POLL_NO_WAIT)? 0: USB_TIMEOUT); + + while ((flags & TRB_CYCLE_STATE) != xhcd->ering.cycle_state) { + mb(); +@@ -1148,11 +1148,36 @@ static inline void *xhci_get_trb(struct xhci_seg *seg) + return (void *)enq; + } + ++static inline void *xhci_get_trb_deq(struct xhci_seg *seg) ++{ ++ uint64_t deq_next, deq; ++ int index; ++ ++ deq = seg->deq; ++ deq_next = deq + XHCI_TRB_SIZE; ++ index = (deq - (uint64_t)seg->trbs) / XHCI_TRB_SIZE + 1; ++ dprintf("%s: deq %llx, deq_next %llx index %x\n", __func__, deq, deq_next, index); ++ /* TRBs being a cyclic buffer, here we cycle back to beginning. */ ++ if (index == (seg->size - 1)) { ++ dprintf("%s: rounding \n", __func__); ++ seg->deq = (uint64_t)seg->trbs; ++ } ++ else { ++ seg->deq = deq_next; ++ } ++ return (void *)deq; ++} ++ + static uint64_t xhci_get_trb_phys(struct xhci_seg *seg, uint64_t trb) + { + return seg->trbs_dma + (trb - (uint64_t)seg->trbs); + } + ++static uint32_t xhci_trb_get_index(struct xhci_seg *seg, struct xhci_transfer_trb *trb) ++{ ++ return trb - (struct xhci_transfer_trb *)seg->trbs; ++} ++ + static int usb_kb = false; + static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys, + void *data, int datalen) +@@ -1332,9 +1357,9 @@ static int xhci_get_pipe_intr(struct usb_pipe *pipe, + xhci_init_seg(seg, XHCI_EVENT_TRBS_SIZE, TYPE_BULK); + } + +- xpipe->buf = buf; +- xpipe->buf_phys = SLOF_dma_map_in(buf, len, false); +- xpipe->buflen = len; ++ xpipe->buflen = pipe->mps * XHCI_INTR_TRBS_SIZE/(sizeof(struct xhci_transfer_trb)); ++ xpipe->buf = SLOF_dma_alloc(xpipe->buflen); ++ xpipe->buf_phys = SLOF_dma_map_in(xpipe->buf, xpipe->buflen, false); + + ctrl = xhci_get_control_ctx(&xdev->in_ctx); + x_epno = xhci_get_epno(pipe); +@@ -1350,7 +1375,8 @@ static int xhci_get_pipe_intr(struct usb_pipe *pipe, + xpipe->seg = seg; + + trb = xhci_get_trb(seg); +- fill_normal_trb(trb, (void *)xpipe->buf_phys, pipe->mps); ++ buf = (char *)(xpipe->buf_phys + xhci_trb_get_index(seg, trb) * pipe->mps); ++ fill_normal_trb(trb, (void *)buf, pipe->mps); + return true; + } + +@@ -1412,6 +1438,7 @@ static void xhci_put_pipe(struct usb_pipe *pipe) + } else if (pipe->type == USB_EP_TYPE_INTR) { + xpipe = xhci_pipe_get_xpipe(pipe); + SLOF_dma_map_out(xpipe->buf_phys, xpipe->buf, xpipe->buflen); ++ SLOF_dma_free(xpipe->buf, xpipe->buflen); + xpipe->seg = NULL; + } + if (xhcd->end) +@@ -1449,26 +1476,26 @@ static int xhci_poll_intr(struct usb_pipe *pipe, uint8_t *data) + if (usb_kb == true) { + /* This event was consumed by bulk transfer */ + usb_kb = false; ++ xhci_get_trb_deq(seg); + goto skip_poll; + } +- buf = xpipe->buf; +- memset(buf, 0, 8); + +- mb(); + /* Ring the doorbell - x_epno */ + dbr = xhcd->db_regs; + write_reg32(&dbr->db[xdev->slot_id], x_epno); +- if (!xhci_poll_event(xhcd, 0)) { +- printf("poll intr failed\n"); ++ if (!xhci_poll_event(xhcd, XHCI_POLL_NO_WAIT)) { + return 0; + } + mb(); ++ trb = xhci_get_trb_deq(seg); ++ buf = xpipe->buf + xhci_trb_get_index(seg, trb) * pipe->mps; + memcpy(data, buf, 8); ++ memset(buf, 0, 8); + + skip_poll: + trb = xhci_get_trb(seg); +- fill_normal_trb(trb, (void *)xpipe->buf_phys, pipe->mps); +- mb(); ++ buf = (uint8_t *)(xpipe->buf_phys + xhci_trb_get_index(seg, trb) * pipe->mps); ++ fill_normal_trb(trb, (void *)buf, pipe->mps); + return ret; + } + +diff --git a/lib/libusb/usb-xhci.h b/lib/libusb/usb-xhci.h +index 3fc7e78..8172a37 100644 +--- a/lib/libusb/usb-xhci.h ++++ b/lib/libusb/usb-xhci.h +@@ -269,6 +269,8 @@ struct xhci_seg { + #define XHCI_INTR_TRBS_SIZE 4096 + #define XHCI_ERST_NUM_SEGS 1 + ++#define XHCI_POLL_NO_WAIT 1 ++ + #define XHCI_MAX_BULK_SIZE 0xF000 + + struct xhci_erst_entry { +-- +1.7.0.4 +