Re: [PATCH 1/3] musb: NAK timeout scheme on bulk reserved ep

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

 



On Thu, Oct 30, 2008 at 02:42:22PM +0530, Ajay Kumar Gupta wrote:
> Fixes endpoint starvation issue when more than one bulk qhs
> are multiplexed on reserved bulk endpoint.NAK timeout interval
> is set for such qhs and next qh is scheduled when NAK timeout
> occurs.
> This scheme doesn't work for devices which are connected to a
> high to full speed tree as there is no NAK timeout interrupt
> at musb controller from such devices.
> A module parameter 'bulk_nak_timeout' is added so that this feature
> can be disabled if not required.

then if the user sets the parameter wrongly, it would break
communication, right ?

unless you can come up with a way to figure out if bulk_nak_timeout
could be set automatically, let's drop this patch.

> Signed-off-by: Ravi Babu <ravibabu@xxxxxx>
> Signed-off-by: Swaminathan S <swami.iyer@xxxxxx>
> Signed-off-by: Thomas Abraham <t-abraham@xxxxxx>
> Signed-off-by: Ajay Kumar Gupta <ajay.gupta@xxxxxx>
> ---
> These patches have been created against latest omap git and Felipe's
> musb .28 patch series at,
> http://marc.info/?l=linux-usb&m=122528597116718&w=2
> 
>  drivers/usb/musb/musb_host.c |   70 ++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> index 30b5685..b77ca0b 100644
> --- a/drivers/usb/musb/musb_host.c
> +++ b/drivers/usb/musb/musb_host.c
> @@ -100,6 +100,10 @@
>   * of transfers between endpoints, or anything clever.
>   */
>  
> +static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep);

please, reorganize the code so we don't need this prototype here.

> +static int bulk_nak_timeout = 1;
> +module_param(bulk_nak_timeout, bool, 0);
> +MODULE_PARM_DESC(bulk_nak_timeout, "enable/disable use of bulk nak timeout");
>  
>  static void musb_ep_program(struct musb *musb, u8 epnum,
>  			struct urb *urb, unsigned int nOut,
> @@ -1449,10 +1453,15 @@ void musb_host_rx(struct musb *musb, u8 epnum)
>  			 * we have a candidate... NAKing is *NOT* an error
>  			 */
>  			DBG(6, "RX end %d NAK timeout\n", epnum);
> +			if (usb_pipebulk(urb->pipe) && qh->mux == 1 &&
> +				(musb->in_bulk.next->next != &musb->in_bulk) &&
> +					bulk_nak_timeout) {
> +				musb_bulk_nak_timeout(musb, hw_ep);
> +				return;
> +			}
>  			musb_ep_select(mbase, epnum);
> -			musb_writew(epio, MUSB_RXCSR,
> -					MUSB_RXCSR_H_WZC_BITS
> -					| MUSB_RXCSR_H_REQPKT);
> +			rx_csr &= ~MUSB_RXCSR_DATAERROR;
> +			musb_writew(epio, MUSB_RXCSR, rx_csr);
>  
>  			goto finish;
>  		} else {
> @@ -1802,6 +1811,9 @@ static int musb_schedule(
>  
>  	idle = 1;
>  	qh->mux = 0;
> +	/* disable NAK scheme when bulk is not multiplexed */
> +	if (is_in && qh->type == USB_ENDPOINT_XFER_BULK && bulk_nak_timeout)
> +		qh->intv_reg = 0;
>  	hw_ep = musb->endpoints + best_end;
>  	if (is_in)
>  		musb->in[best_end] = qh;
> @@ -1912,6 +1924,17 @@ static int musb_urb_enqueue(
>  	case USB_ENDPOINT_XFER_ISOC:
>  		/* iso always uses log encoding */
>  		break;
> +	case USB_ENDPOINT_XFER_BULK:
> +		/* Enable bulk NAK time out scheme when bulk requests are
> +		 * multiplxed.This scheme doen't work in high speed to full
> +		 * speed scenario as NAK interrupts are not coming from a
> +		 * full speed device connected to a high speed device.
> +		 */
> +		if (usb_pipein(urb->pipe) && bulk_nak_timeout) {
> +			interval = 8;
> +			break;
> +		}
> +		/* FALLTHROUGH */
>  	default:
>  		/* REVISIT we actually want to use NAK limits, hinting to the
>  		 * transfer scheduling logic to try some other qh, e.g. try
> @@ -2265,6 +2288,47 @@ static int musb_bus_resume(struct usb_hcd *hcd)
>  	return 0;
>  }
>  
> +static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
> +{
> +	struct dma_channel	*dma;
> +	struct urb	*urb;
> +	void __iomem	*mbase = musb->mregs;
> +	void __iomem	*epio = ep->regs;
> +	struct musb_qh	*cur_qh, *next_qh;
> +	u16	rx_csr;
> +
> +	musb_ep_select(mbase, ep->epnum);
> +	dma = is_dma_capable() ? ep->rx_channel : NULL;
> +
> +	/* clear nak timeout bit */
> +	rx_csr = musb_readw(epio, MUSB_RXCSR);
> +	rx_csr &= ~MUSB_RXCSR_DATAERROR;
> +	musb_writew(epio, MUSB_RXCSR, rx_csr);
> +
> +	cur_qh = first_qh(&musb->in_bulk);
> +	if (cur_qh) {
> +		urb = next_urb(cur_qh);
> +		if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
> +			dma->status = MUSB_DMA_STATUS_CORE_ABORT;
> +			musb->dma_controller->channel_abort(dma);
> +			urb->actual_length += dma->actual_len;
> +			dma->actual_len = 0L;
> +		}
> +		musb_save_toggle(ep, 1, urb);
> +
> +		/* delete cur_qh and add to tail to musb->in_bulk */
> +		list_del(&cur_qh->ring);
> +		list_add_tail(&cur_qh->ring, &musb->in_bulk);
> +
> +		/* get the next qh from musb->in_bulk */
> +		next_qh = first_qh(&musb->in_bulk);
> +
> +		/* set rx_reinit and schedule the next qh */
> +		ep->rx_reinit = 1;
> +		musb_start_urb(musb, 1, next_qh);
> +	}
> +}
> +
>  const struct hc_driver musb_hc_driver = {
>  	.description		= "musb-hcd",
>  	.product_desc		= "MUSB HDRC host driver",
> -- 
> 1.5.6

-- 
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux