public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: linux-usb-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] More USB fixes for 2.5.67
Date: Wed, 16 Apr 2003 23:05:05 -0700	[thread overview]
Message-ID: <1050559505786@kroah.com> (raw)
In-Reply-To: <10505595041530@kroah.com>

ChangeSet 1.1063, 2003/04/14 10:26:02-07:00, david-b@pacbell.net

[PATCH] USB: EHCI disconnect cleanup

So here's the EHCI implementation of that new callback,
morphed/simplified from the old "free_config" one (which
is now gone).  It looks almost identical to the OHCI
version, except the dummy TDs work a bit differently.

Again, drivers that clean themselves up in disconnect()
shouldn't notice this change.  I didn't re-test this;
I don't have devices with the other kind of driver.  You
should do so with one of yours (high speed hub and TT).

There are still about half a dozen places in usbcore
and the HCDs that would benefit from using this new
callback, FWIW.  I'd call them non-critical bugfixes
that should wait a bit, while this batch shakes out.


diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Wed Apr 16 10:48:49 2003
+++ b/drivers/usb/core/hcd.c	Wed Apr 16 10:48:49 2003
@@ -1353,9 +1353,6 @@
 		return -EINVAL;
 	}
 
-	if (hcd->driver->free_config)
-		hcd->driver->free_config (hcd, udev);
-
 	spin_lock_irqsave (&hcd_data_lock, flags);
 	list_del (&dev->dev_list);
 	udev->hcpriv = NULL;
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Wed Apr 16 10:48:48 2003
+++ b/drivers/usb/core/hcd.h	Wed Apr 16 10:48:48 2003
@@ -196,11 +196,6 @@
 					int mem_flags);
 	int	(*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
 
-	// frees configuration resources -- allocated as needed during
-	// urb_enqueue, and not freed by urb_dequeue
-	void		(*free_config) (struct usb_hcd *hcd,
-				struct usb_device *dev);
-
 	/* hw synch, freeing endpoint resources that urb_dequeue can't */
 	void 	(*endpoint_disable)(struct usb_hcd *hcd,
 			struct hcd_dev *dev, int bEndpointAddress);
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Wed Apr 16 10:48:49 2003
+++ b/drivers/usb/host/ehci-hcd.c	Wed Apr 16 10:48:49 2003
@@ -870,80 +870,55 @@
 
 // bulk qh holds the data toggle
 
-static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev)
+static void
+ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
 {
-	struct hcd_dev		*dev = (struct hcd_dev *)udev->hcpriv;
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
-	int			i;
+	int			epnum;
 	unsigned long		flags;
+	struct ehci_qh		*qh;
 
-	/* ASSERT:  no requests/urbs are still linked (so no TDs) */
+	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 
-	ehci_dbg (ehci, "free_config %s devnum %d\n",
-			udev->devpath, udev->devnum);
+	ehci_dbg (ehci, "ep %02x disable\n", ep);
+	epnum = ep & USB_ENDPOINT_NUMBER_MASK;
+	if (epnum != 0 && (ep & USB_DIR_IN))
+		epnum |= 0x10;
 
+rescan:
 	spin_lock_irqsave (&ehci->lock, flags);
-	for (i = 0; i < 32; i++) {
-		if (dev->ep [i]) {
-			struct ehci_qh		*qh;
-			char			*why;
-
-			/* dev->ep never has ITDs or SITDs */
-			qh = (struct ehci_qh *) dev->ep [i];
-
-			/* detect/report non-recoverable errors */
-			if (in_interrupt ()) 
-				why = "disconnect() didn't";
-			else if ((qh->hw_info2 & cpu_to_le32 (0xffff)) != 0
-					&& qh->qh_state != QH_STATE_IDLE)
-				why = "(active periodic)";
-			else
-				why = 0;
-			if (why) {
-				err ("dev %s-%s ep %d-%s error: %s",
-					hcd_to_bus (hcd)->bus_name,
-					udev->devpath,
-					i & 0xf, (i & 0x10) ? "IN" : "OUT",
-					why);
-				BUG ();
-			}
-
-			dev->ep [i] = 0;
-			if (qh->qh_state == QH_STATE_IDLE)
-				goto idle;
-			ehci_dbg (ehci, "free_config, async ep 0x%02x qh %p",
-					i, qh);
-
-			/* scan_async() empties the ring as it does its work,
-			 * using IAA, but doesn't (yet?) turn it off.  if it
-			 * doesn't empty this qh, likely it's the last entry.
-			 */
-			while (qh->qh_state == QH_STATE_LINKED
-					&& ehci->reclaim
-					&& HCD_IS_RUNNING (ehci->hcd.state)
-					) {
-				spin_unlock_irqrestore (&ehci->lock, flags);
-				/* wait_ms() won't spin, we're a thread;
-				 * and we know IRQ/timer/... can progress
-				 */
-				wait_ms (1);
-				spin_lock_irqsave (&ehci->lock, flags);
-			}
-			if (qh->qh_state == QH_STATE_LINKED)
-				start_unlink_async (ehci, qh);
-			while (qh->qh_state != QH_STATE_IDLE
-					&& ehci->hcd.state != USB_STATE_HALT) {
-				spin_unlock_irqrestore (&ehci->lock, flags);
-				wait_ms (1);
-				spin_lock_irqsave (&ehci->lock, flags);
-			}
-idle:
+	qh = (struct ehci_qh *) dev->ep [epnum];
+	if (!qh)
+		goto done;
+
+	if (!HCD_IS_RUNNING (ehci->hcd.state))
+		qh->qh_state = QH_STATE_IDLE;
+	switch (qh->qh_state) {
+	case QH_STATE_UNLINK:		/* wait for hw to finish? */
+		spin_unlock_irqrestore (&ehci->lock, flags);
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		schedule_timeout (1);
+		goto rescan;
+	case QH_STATE_IDLE:		/* fully unlinked */
+		if (list_empty (&qh->qtd_list)) {
 			qh_put (ehci, qh);
+			break;
 		}
+		/* else FALL THROUGH */
+	default:
+		/* caller was supposed to have unlinked any requests;
+		 * that's not our job.  just leak this memory.
+		 */
+		ehci_err (ehci, "qh %p (#%d) state %d%s\n",
+			qh, epnum, qh->qh_state,
+			list_empty (&qh->qtd_list) ? "" : "(has tds)");
+		break;
 	}
-
+	dev->ep [epnum] = 0;
+done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
+	return;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -978,7 +953,7 @@
 	 */
 	.urb_enqueue =		ehci_urb_enqueue,
 	.urb_dequeue =		ehci_urb_dequeue,
-	.free_config =		ehci_free_config,
+	.endpoint_disable =	ehci_endpoint_disable,
 
 	/*
 	 * scheduling support


  reply	other threads:[~2003-04-17  5:51 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-04-17  6:03 [BK PATCH] More USB fixes for 2.5.67 Greg KH
2003-04-17  6:05 ` [PATCH] " Greg KH
2003-04-17  6:05   ` Greg KH
2003-04-17  6:05     ` Greg KH
2003-04-17  6:05       ` Greg KH
2003-04-17  6:05         ` Greg KH
2003-04-17  6:05           ` Greg KH
2003-04-17  6:05             ` Greg KH
2003-04-17  6:05               ` Greg KH
2003-04-17  6:05                 ` Greg KH [this message]
2003-04-17  6:05                   ` Greg KH
2003-04-17  6:05                     ` Greg KH
2003-04-17  6:05                       ` Greg KH
2003-04-17  6:05                         ` Greg KH
2003-04-17 15:18                     ` Matthew Dharm
2003-04-17 17:10                       ` Greg KH

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=1050559505786@kroah.com \
    --to=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox