qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/2] usb: implement XHCI underrun/overrun events


From: Dmitry Fleytman
Subject: Re: [Qemu-devel] [PATCH 2/2] usb: implement XHCI underrun/overrun events
Date: Wed, 30 Jan 2019 08:35:58 +0000


> On 28 Jan 2019, at 22:05, Yuri Benditovich <address@hidden> wrote:
> 
> Implement underrun/overrun events of isochronous endpoints
> according to XHCI spec (4.10.3.1)
> Guest software restarts data streaming when receives these events.
> The XHCI reports these events using interrupter assigned
> to the slot (as these events do not have TRB), so current
> commit adds the field of assigned interrupter to the
> XHCISlot structure. Guest software assigns interrupter to the
> slot on 'Address Device' and 'Evaluate Context' commands.
> 
> Signed-off-by: Yuri Benditovich <address@hidden>

Reviewed-by: Dmitry Fleytman <address@hidden>

> ---
> hw/usb/hcd-xhci.c | 17 +++++++++++++++--
> hw/usb/hcd-xhci.h |  1 +
> 2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
> index 1a8fd96..19c64f7 100644
> --- a/hw/usb/hcd-xhci.c
> +++ b/hw/usb/hcd-xhci.c
> @@ -1949,6 +1949,16 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, 
> unsigned int streamid)
>     while (1) {
>         length = xhci_ring_chain_length(xhci, ring);
>         if (length <= 0) {
> +            if (epctx->type == ET_ISO_OUT || epctx->type == ET_ISO_IN) {
> +                /* 4.10.3.1 */
> +                XHCIEvent ev = { ER_TRANSFER };
> +                ev.ccode  = epctx->type == ET_ISO_IN ?
> +                    CC_RING_OVERRUN : CC_RING_UNDERRUN;
> +                ev.slotid = epctx->slotid;
> +                ev.epid   = epctx->epid;
> +                ev.ptr    = epctx->ring.dequeue;
> +                xhci_event(xhci, &ev, xhci->slots[epctx->slotid-1].intr);
> +            }
>             break;
>         }
>         xfer = xhci_ep_alloc_xfer(epctx, length);
> @@ -2028,6 +2038,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, 
> unsigned int slotid)
>     xhci->slots[slotid-1].enabled = 0;
>     xhci->slots[slotid-1].addressed = 0;
>     xhci->slots[slotid-1].uport = NULL;
> +    xhci->slots[slotid-1].intr = 0;
>     return CC_SUCCESS;
> }
> 
> @@ -2127,6 +2138,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, 
> unsigned int slotid,
>     slot = &xhci->slots[slotid-1];
>     slot->uport = uport;
>     slot->ctx = octx;
> +    slot->intr = get_field(slot_ctx[2], TRB_INTR);
> 
>     /* Make sure device is in USB_STATE_DEFAULT state */
>     usb_device_reset(dev);
> @@ -2300,8 +2312,9 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, 
> unsigned int slotid,
> 
>         slot_ctx[1] &= ~0xFFFF; /* max exit latency */
>         slot_ctx[1] |= islot_ctx[1] & 0xFFFF;
> -        slot_ctx[2] &= ~0xFF00000; /* interrupter target */
> -        slot_ctx[2] |= islot_ctx[2] & 0xFF000000;
> +        /* update interrupter target field */
> +        xhci->slots[slotid-1].intr = get_field(islot_ctx[2], TRB_INTR);
> +        set_field(&slot_ctx[2], xhci->slots[slotid-1].intr, TRB_INTR);
> 
>         DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
>                 slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
> diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
> index fc36a4c..240caa4 100644
> --- a/hw/usb/hcd-xhci.h
> +++ b/hw/usb/hcd-xhci.h
> @@ -140,6 +140,7 @@ typedef struct XHCIPort {
> typedef struct XHCISlot {
>     bool enabled;
>     bool addressed;
> +    uint16_t intr;
>     dma_addr_t ctx;
>     USBPort *uport;
>     XHCIEPContext *eps[31];
> -- 
> 2.9.5
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]