All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Jim Lin <jilin@nvidia.com>,
	gregkh@linuxfoundation.org, mathias.nyman@intel.com,
	stern@rowland.harvard.edu, kai.heng.feng@canonical.com,
	drinkcat@chromium.org, keescook@chromium.org,
	nsaenzjulienne@suse.de, jflat@chromium.org, malat@debian.org
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v10 2/2] usb: xhci: Add Clear_TT_Buffer
Date: Fri, 17 May 2019 17:10:41 +0300	[thread overview]
Message-ID: <ece2b354-8b3b-6c3d-6e64-5d7e6236148e@linux.intel.com> (raw)
In-Reply-To: <1558017657-13835-3-git-send-email-jilin@nvidia.com>

On 16.5.2019 17.40, Jim Lin wrote:
> USB 2.0 specification chapter 11.17.5 says "as part of endpoint halt
> processing for full-/low-speed endpoints connected via a TT, the host
> software must use the Clear_TT_Buffer request to the TT to ensure
> that the buffer is not in the busy state".
> 
> In our case, a full-speed speaker (ConferenceCam) is behind a high-
> speed hub (ConferenceCam Connect), sometimes once we get STALL on a
> request we may continue to get STALL with the folllowing requests,
> like Set_Interface.
> 
> Here we invoke usb_hub_clear_tt_buffer() to send Clear_TT_Buffer
> request to the hub of the device for the following Set_Interface
> requests to the device to get ACK successfully.
> 
> Signed-off-by: Jim Lin <jilin@nvidia.com>
> ---
> v2: xhci_clear_tt_buffer_complete: add static, shorter indentation
>      , remove its claiming in xhci.h
> v3: Add description for clearing_tt (xhci.h)
> v4: Remove clearing_tt flag because hub_tt_work has hub->tt.lock
>      to protect for Clear_TT_Buffer to be run serially.
>      Remove xhci_clear_tt_buffer_complete as it's not necessary.
>      Same reason as the above.
>      Extend usb_hub_clear_tt_buffer parameter
> v5: Not extending usb_hub_clear_tt_buffer parameter
>      Add description.
> v6: Remove unused parameter slot_id from xhci_clear_hub_tt_buffer
> v7: Add devaddr field in "struct usb_device"
> v8: split as two patches
> v9: no change flag
> v10: Add EP_CLEARING_TT flag
> 
>   drivers/usb/host/xhci-ring.c | 27 ++++++++++++++++++++++++++-
>   drivers/usb/host/xhci.c      | 17 +++++++++++++++++
>   drivers/usb/host/xhci.h      |  5 +++++
>   3 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 9215a28dad40..11d498b6c09b 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -399,7 +399,7 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
>   	 * stream once the endpoint is on the HW schedule.
>   	 */
>   	if ((ep_state & EP_STOP_CMD_PENDING) || (ep_state & SET_DEQ_PENDING) ||
> -	    (ep_state & EP_HALTED))
> +	    (ep_state & EP_HALTED) || (ep_state & EP_CLEARING_TT))
>   		return;
>   	writel(DB_VALUE(ep_index, stream_id), db_addr);
>   	/* The CPU has better things to do at this point than wait for a
> @@ -433,6 +433,13 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
>   	}
>   }
>   
> +void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
> +		unsigned int slot_id,
> +		unsigned int ep_index)
> +{
> +	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
> +}
> +
>   /* Get the right ring for the given slot_id, ep_index and stream_id.
>    * If the endpoint supports streams, boundary check the URB's stream ID.
>    * If the endpoint doesn't support streams, return the singular endpoint ring.
> @@ -1786,6 +1793,23 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
>   	return NULL;
>   }
>   
> +static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td,
> +		struct xhci_virt_ep *ep)
> +{
> +	/*
> +	 * As part of low/full-speed endpoint-halt processing
> +	 * we must clear the TT buffer (USB 2.0 specification 11.17.5).
> +	 */
> +	if (td->urb->dev->tt && !usb_pipeint(td->urb->pipe) &&
> +	    (td->urb->dev->tt->hub != xhci_to_hcd(xhci)->self.root_hub) &&
> +	    !(ep->ep_state & EP_CLEARING_TT)) {
> +		ep->ep_state |= EP_CLEARING_TT;
> +		td->urb->ep->hcpriv = td->urb->dev;
> +		if (usb_hub_clear_tt_buffer(td->urb))
> +			ep->ep_state &= ~EP_CLEARING_TT;
> +	}
> +}
> +
>   static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
>   		unsigned int slot_id, unsigned int ep_index,
>   		unsigned int stream_id, struct xhci_td *td,
> @@ -1804,6 +1828,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
>   	if (reset_type == EP_HARD_RESET) {
>   		ep->ep_state |= EP_HARD_CLEAR_TOGGLE;
>   		xhci_cleanup_stalled_ring(xhci, ep_index, stream_id, td);
> +		xhci_clear_hub_tt_buffer(xhci, td, ep);
>   	}
>   	xhci_ring_cmd_db(xhci);
>   }
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 68b393e5a453..0dc108e61a89 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -5133,6 +5133,22 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
>   }
>   EXPORT_SYMBOL_GPL(xhci_gen_setup);
>   
> +static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd,
> +		struct usb_host_endpoint *ep)
> +{
> +	struct xhci_hcd *xhci;
> +	struct usb_device *udev;
> +	unsigned int slot_id;
> +	unsigned int ep_index;
> +
> +	xhci = hcd_to_xhci(hcd);
> +	udev = (struct usb_device *)ep->hcpriv;
> +	slot_id = udev->slot_id;
> +	ep_index = xhci_get_endpoint_index(&ep->desc);


spin_lock_irqsave(&xhci->lock, flags);  (protecting ep_state)

> +	xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT;
> +	xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index);

unlock

note:
lock is already taken in xhci_cleanup_halted_endpoint()
so no need to take lock for xhci_clear_hub_tt_buffer()
  

Other than that this looks good to me.

-Mathias

      reply	other threads:[~2019-05-17 14:08 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-16 14:40 [PATCH v10 0/2] usb: xhci: Add Clear_TT_Buffer Jim Lin
2019-05-16 14:40 ` [PATCH v10 1/2] usb: xhci : Add devaddr in struct usb_device Jim Lin
2019-05-16 14:56   ` Alan Stern
2019-05-17 13:37     ` Jim Lin
2019-05-16 14:40 ` [PATCH v10 2/2] usb: xhci: Add Clear_TT_Buffer Jim Lin
2019-05-17 14:10   ` Mathias Nyman [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ece2b354-8b3b-6c3d-6e64-5d7e6236148e@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=drinkcat@chromium.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jflat@chromium.org \
    --cc=jilin@nvidia.com \
    --cc=kai.heng.feng@canonical.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=malat@debian.org \
    --cc=mathias.nyman@intel.com \
    --cc=nsaenzjulienne@suse.de \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.