Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22a0d6f1 authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Greg Kroah-Hartman
Browse files

musb_host: simplify check for active URB



The existance of the scheduling list shouldn't matter in
determining whether there's currectly an URB executing on a
hardware endpoint. What should actually matter is the 'in_qh'
or 'out_qh' fields of the 'struct musb_hw_ep' -- those are
set in musb_start_urb() and cleared in musb_giveback() when
the endpoint's URB list drains. Hence we should be able to
replace the big *switch* statements in musb_urb_dequeue()
and musb_h_disable() with mere musb_ep_get_qh() calls...

While at it, do some more changes:

 - add 'is_in' variable to musb_urb_dequeue();

 - remove the unnecessary 'epnum' variable from musb_h_disable();

 - fix the comment style in the vicinity.

This is a minor shrink of source and object code.

Signed-off-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3e5c6dc7
Loading
Loading
Loading
Loading
+14 −58
Original line number Diff line number Diff line
@@ -2089,14 +2089,14 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
{
	struct musb		*musb = hcd_to_musb(hcd);
	struct musb_qh		*qh;
	struct list_head	*sched;
	unsigned long		flags;
	int			is_in  = usb_pipein(urb->pipe);
	int			ret;

	DBG(4, "urb=%p, dev%d ep%d%s\n", urb,
			usb_pipedevice(urb->pipe),
			usb_pipeendpoint(urb->pipe),
			usb_pipein(urb->pipe) ? "in" : "out");
			is_in ? "in" : "out");

	spin_lock_irqsave(&musb->lock, flags);
	ret = usb_hcd_check_unlink_urb(hcd, urb, status);
@@ -2107,45 +2107,23 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
	if (!qh)
		goto done;

	/* Any URB not actively programmed into endpoint hardware can be
	/*
	 * Any URB not actively programmed into endpoint hardware can be
	 * immediately given back; that's any URB not at the head of an
	 * endpoint queue, unless someday we get real DMA queues.  And even
	 * if it's at the head, it might not be known to the hardware...
	 *
	 * Otherwise abort current transfer, pending dma, etc.; urb->status
	 * Otherwise abort current transfer, pending DMA, etc.; urb->status
	 * has already been updated.  This is a synchronous abort; it'd be
	 * OK to hold off until after some IRQ, though.
	 *
	 * NOTE: qh is invalid unless !list_empty(&hep->urb_list)
	 */
	if (!qh->is_ready || urb->urb_list.prev != &qh->hep->urb_list)
		ret = -EINPROGRESS;
	else {
		switch (qh->type) {
		case USB_ENDPOINT_XFER_CONTROL:
			sched = &musb->control;
			break;
		case USB_ENDPOINT_XFER_BULK:
			if (qh->mux == 1) {
				if (usb_pipein(urb->pipe))
					sched = &musb->in_bulk;
				else
					sched = &musb->out_bulk;
				break;
			}
		default:
			/* REVISIT when we get a schedule tree, periodic
			 * transfers won't always be at the head of a
			 * singleton queue...
			 */
			sched = NULL;
			break;
		}
	}

	/* NOTE:  qh is invalid unless !list_empty(&hep->urb_list) */
	if (ret < 0 || (sched && qh != first_qh(sched))) {
	if (!qh->is_ready
			|| urb->urb_list.prev != &qh->hep->urb_list
			|| musb_ep_get_qh(qh->hw_ep, is_in) != qh) {
		int	ready = qh->is_ready;

		ret = 0;
		qh->is_ready = 0;
		__musb_giveback(musb, urb, 0);
		qh->is_ready = ready;
@@ -2169,13 +2147,11 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
static void
musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
{
	u8			epnum = hep->desc.bEndpointAddress;
	u8			is_in = hep->desc.bEndpointAddress & USB_DIR_IN;
	unsigned long		flags;
	struct musb		*musb = hcd_to_musb(hcd);
	u8			is_in = epnum & USB_DIR_IN;
	struct musb_qh		*qh;
	struct urb		*urb;
	struct list_head	*sched;

	spin_lock_irqsave(&musb->lock, flags);

@@ -2183,31 +2159,11 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
	if (qh == NULL)
		goto exit;

	switch (qh->type) {
	case USB_ENDPOINT_XFER_CONTROL:
		sched = &musb->control;
		break;
	case USB_ENDPOINT_XFER_BULK:
		if (qh->mux == 1) {
			if (is_in)
				sched = &musb->in_bulk;
			else
				sched = &musb->out_bulk;
			break;
		}
	default:
		/* REVISIT when we get a schedule tree, periodic transfers
		 * won't always be at the head of a singleton queue...
		 */
		sched = NULL;
		break;
	}

	/* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */

	/* kick first urb off the hardware, if needed */
	/* Kick the first URB off the hardware, if needed */
	qh->is_ready = 0;
	if (!sched || qh == first_qh(sched)) {
	if (musb_ep_get_qh(qh->hw_ep, is_in) == qh) {
		urb = next_urb(qh);

		/* make software (then hardware) stop ASAP */