[PATCH] UHCI: use one QH per endpoint, not per URB

This patch (as623) changes the uhci-hcd driver to make it use one QH per
device endpoint, instead of a QH per URB as it does now.  Numerous areas
of the code are affected by this.  For example, the distinction between
"queued" URBs and non-"queued" URBs no longer exists; all URBs belong to
a queue and some just happen to be at the queue's head.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 7823980..b1b551a 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -13,13 +13,9 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu
  */
 
-static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
-static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb);
-static void uhci_remove_pending_urbps(struct uhci_hcd *uhci);
-static void uhci_free_pending_qhs(struct uhci_hcd *uhci);
 static void uhci_free_pending_tds(struct uhci_hcd *uhci);
 
 /*
@@ -30,7 +26,7 @@
  * games with the FSBR code to make sure we get the correct order in all
  * the cases. I don't think it's worth the effort
  */
-static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
+static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
 {
 	if (uhci->is_stopped)
 		mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
@@ -42,12 +38,6 @@
 	uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
 }
 
-static inline void uhci_moveto_complete(struct uhci_hcd *uhci, 
-					struct urb_priv *urbp)
-{
-	list_move_tail(&urbp->urb_list, &uhci->complete_list);
-}
-
 static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
 {
 	dma_addr_t dma_handle;
@@ -71,6 +61,18 @@
 	return td;
 }
 
+static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
+{
+	if (!list_empty(&td->list))
+		dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
+	if (!list_empty(&td->remove_list))
+		dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
+	if (!list_empty(&td->fl_list))
+		dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
+
+	dma_pool_free(uhci->td_pool, td, td->dma_handle);
+}
+
 static inline void uhci_fill_td(struct uhci_td *td, u32 status,
 		u32 token, u32 buffer)
 {
@@ -82,7 +84,8 @@
 /*
  * We insert Isochronous URBs directly into the frame list at the beginning
  */
-static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum)
+static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
+		struct uhci_td *td, unsigned framenum)
 {
 	framenum &= (UHCI_NUMFRAMES - 1);
 
@@ -108,7 +111,7 @@
 	}
 }
 
-static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci,
+static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
 		struct uhci_td *td)
 {
 	/* If it's not inserted, don't remove it */
@@ -139,48 +142,68 @@
 	td->frame = -1;
 }
 
-static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
+/*
+ * Remove all the TDs for an Isochronous URB from the frame list
+ */
+static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
 {
 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
 	struct uhci_td *td;
 
 	list_for_each_entry(td, &urbp->td_list, list)
-		uhci_remove_td_frame_list(uhci, td);
+		uhci_remove_td_from_frame_list(uhci, td);
 	wmb();
 }
 
 /*
- * Inserts a td list into qh.
+ * Remove an URB's TDs from the hardware schedule
  */
-static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, __le32 breadth)
+static void uhci_remove_tds_from_schedule(struct uhci_hcd *uhci,
+		struct urb *urb, int status)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-	struct uhci_td *td;
-	__le32 *plink;
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
 
-	/* Ordering isn't important here yet since the QH hasn't been */
-	/* inserted into the schedule yet */
-	plink = &qh->element;
-	list_for_each_entry(td, &urbp->td_list, list) {
-		*plink = cpu_to_le32(td->dma_handle) | breadth;
-		plink = &td->link;
+	/* Isochronous TDs get unlinked directly from the frame list */
+	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+		uhci_unlink_isochronous_tds(uhci, urb);
+		return;
 	}
-	*plink = UHCI_PTR_TERM;
+
+	/* If the URB isn't first on its queue, adjust the link pointer
+	 * of the last TD in the previous URB. */
+	if (urbp->node.prev != &urbp->qh->queue) {
+		struct urb_priv *purbp;
+		struct uhci_td *ptd, *ltd;
+
+		if (status == -EINPROGRESS)
+			status = 0;
+		purbp = list_entry(urbp->node.prev, struct urb_priv, node);
+		ptd = list_entry(purbp->td_list.prev, struct uhci_td,
+				list);
+		ltd = list_entry(urbp->td_list.prev, struct uhci_td,
+				list);
+		ptd->link = ltd->link;
+	}
+
+	/* If the URB completed with an error, then the QH element certainly
+	 * points to one of the URB's TDs.  If it completed normally then
+	 * the QH element has certainly moved on to the next URB.  And if
+	 * the URB is still in progress then it must have been dequeued.
+	 * The QH element either hasn't reached it yet or is somewhere in
+	 * the middle.  If the URB wasn't first we can assume that it
+	 * hasn't started yet (see above): Otherwise all the preceding URBs
+	 * would have completed and been removed from the queue, so this one
+	 * _would_ be first.
+	 *
+	 * If the QH element is inside this URB, clear it.  It will be
+	 * set properly when the QH is activated.
+	 */
+	if (status < 0)
+		urbp->qh->element = UHCI_PTR_TERM;
 }
 
-static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
-{
-	if (!list_empty(&td->list))
-		dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
-	if (!list_empty(&td->remove_list))
-		dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
-	if (!list_empty(&td->fl_list))
-		dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
-
-	dma_pool_free(uhci->td_pool, td, td->dma_handle);
-}
-
-static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci)
+static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
+		struct usb_device *udev, struct usb_host_endpoint *hep)
 {
 	dma_addr_t dma_handle;
 	struct uhci_qh *qh;
@@ -194,256 +217,120 @@
 	qh->element = UHCI_PTR_TERM;
 	qh->link = UHCI_PTR_TERM;
 
-	qh->urbp = NULL;
+	INIT_LIST_HEAD(&qh->queue);
+	INIT_LIST_HEAD(&qh->node);
 
-	INIT_LIST_HEAD(&qh->list);
-	INIT_LIST_HEAD(&qh->remove_list);
+	if (udev) {		/* Normal QH */
+		qh->state = QH_STATE_IDLE;
+		qh->hep = hep;
+		qh->udev = udev;
+		hep->hcpriv = qh;
+		usb_get_dev(udev);
 
+	} else {		/* Skeleton QH */
+		qh->state = QH_STATE_ACTIVE;
+		qh->udev = NULL;
+	}
 	return qh;
 }
 
 static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	if (!list_empty(&qh->list))
+	WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
+	if (!list_empty(&qh->queue))
 		dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
-	if (!list_empty(&qh->remove_list))
-		dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh);
 
+	list_del(&qh->node);
+	if (qh->udev) {
+		qh->hep->hcpriv = NULL;
+		usb_put_dev(qh->udev);
+	}
 	dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
 }
 
 /*
- * Append this urb's qh after the last qh in skelqh->list
- *
- * Note that urb_priv.queue_list doesn't have a separate queue head;
- * it's a ring with every element "live".
+ * Put a QH on the schedule in both hardware and software
  */
-static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct urb *urb)
+static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-	struct urb_priv *turbp;
-	struct uhci_qh *lqh;
+	struct uhci_qh *pqh;
 
-	/* Grab the last QH */
-	lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);
+	WARN_ON(list_empty(&qh->queue));
 
-	/* Point to the next skelqh */
-	urbp->qh->link = lqh->link;
-	wmb();				/* Ordering is important */
+	/* Set the element pointer if it isn't set already.
+	 * This isn't needed for Isochronous queues, but it doesn't hurt. */
+	if (qh_element(qh) == UHCI_PTR_TERM) {
+		struct urb_priv *urbp = list_entry(qh->queue.next,
+				struct urb_priv, node);
+		struct uhci_td *td = list_entry(urbp->td_list.next,
+				struct uhci_td, list);
 
-	/*
-	 * Patch QHs for previous endpoint's queued URBs?  HC goes
-	 * here next, not to the next skelqh it now points to.
-	 *
-	 *    lqh --> td ... --> qh ... --> td --> qh ... --> td
-	 *     |                 |                 |
-	 *     v                 v                 v
-	 *     +<----------------+-----------------+
-	 *     v
-	 *    newqh --> td ... --> td
-	 *     |
-	 *     v
-	 *    ...
-	 *
-	 * The HC could see (and use!) any of these as we write them.
-	 */
-	lqh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
-	if (lqh->urbp) {
-		list_for_each_entry(turbp, &lqh->urbp->queue_list, queue_list)
-			turbp->qh->link = lqh->link;
+		qh->element = cpu_to_le32(td->dma_handle);
 	}
 
-	list_add_tail(&urbp->qh->list, &skelqh->list);
+	if (qh->state == QH_STATE_ACTIVE)
+		return;
+	qh->state = QH_STATE_ACTIVE;
+
+	/* Move the QH from its old list to the end of the appropriate
+	 * skeleton's list */
+	list_move_tail(&qh->node, &qh->skel->node);
+
+	/* Link it into the schedule */
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	qh->link = pqh->link;
+	wmb();
+	pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
 }
 
 /*
- * Start removal of QH from schedule; it finishes next frame.
- * TDs should be unlinked before this is called.
+ * Take a QH off the hardware schedule
  */
-static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
 	struct uhci_qh *pqh;
-	__le32 newlink;
 
-	if (!qh)
+	if (qh->state == QH_STATE_UNLINKING)
 		return;
+	WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
+	qh->state = QH_STATE_UNLINKING;
 
-	/*
-	 * Only go through the hoops if it's actually linked in
-	 */
-	if (!list_empty(&qh->list)) {
-
-		/* If our queue is nonempty, make the next URB the head */
-		if (!list_empty(&qh->urbp->queue_list)) {
-			struct urb_priv *nurbp;
-
-			nurbp = list_entry(qh->urbp->queue_list.next,
-					struct urb_priv, queue_list);
-			nurbp->queued = 0;
-			list_add(&nurbp->qh->list, &qh->list);
-			newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
-		} else
-			newlink = qh->link;
-
-		/* Fix up the previous QH's queue to link to either
-		 * the new head of this queue or the start of the
-		 * next endpoint's queue. */
-		pqh = list_entry(qh->list.prev, struct uhci_qh, list);
-		pqh->link = newlink;
-		if (pqh->urbp) {
-			struct urb_priv *turbp;
-
-			list_for_each_entry(turbp, &pqh->urbp->queue_list,
-					queue_list)
-				turbp->qh->link = newlink;
-		}
-		wmb();
-
-		/* Leave qh->link in case the HC is on the QH now, it will */
-		/* continue the rest of the schedule */
-		qh->element = UHCI_PTR_TERM;
-
-		list_del_init(&qh->list);
-	}
-
-	list_del_init(&qh->urbp->queue_list);
-	qh->urbp = NULL;
+	/* Unlink the QH from the schedule and record when we did it */
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	pqh->link = qh->link;
+	mb();
 
 	uhci_get_current_frame_number(uhci);
-	if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) {
-		uhci_free_pending_qhs(uhci);
-		uhci->qh_remove_age = uhci->frame_number;
-	}
+	qh->unlink_frame = uhci->frame_number;
 
-	/* Check to see if the remove list is empty. Set the IOC bit */
-	/* to force an interrupt so we can remove the QH */
-	if (list_empty(&uhci->qh_remove_list))
+	/* Force an interrupt so we know when the QH is fully unlinked */
+	if (list_empty(&uhci->skel_unlink_qh->node))
 		uhci_set_next_interrupt(uhci);
 
-	list_add(&qh->remove_list, &uhci->qh_remove_list);
+	/* Move the QH from its old list to the end of the unlinking list */
+	list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
 }
 
-static int uhci_fixup_toggle(struct urb *urb, unsigned int toggle)
+/*
+ * When we and the controller are through with a QH, it becomes IDLE.
+ * This happens when a QH has been off the schedule (on the unlinking
+ * list) for more than one frame, or when an error occurs while adding
+ * the first URB onto a new QH.
+ */
+static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-	struct uhci_td *td;
+	WARN_ON(qh->state == QH_STATE_ACTIVE);
 
-	list_for_each_entry(td, &urbp->td_list, list) {
-		if (toggle)
-			td->token |= cpu_to_le32(TD_TOKEN_TOGGLE);
-		else
-			td->token &= ~cpu_to_le32(TD_TOKEN_TOGGLE);
+	list_move(&qh->node, &uhci->idle_qh_list);
+	qh->state = QH_STATE_IDLE;
 
-		toggle ^= 1;
-	}
-
-	return toggle;
+	/* If anyone is waiting for a QH to become idle, wake them up */
+	if (uhci->num_waiting)
+		wake_up_all(&uhci->waitqh);
 }
 
-/* This function will append one URB's QH to another URB's QH. This is for */
-/* queuing interrupt, control or bulk transfers */
-static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, struct urb *urb)
-{
-	struct urb_priv *eurbp, *urbp, *furbp, *lurbp;
-	struct uhci_td *lltd;
-
-	eurbp = eurb->hcpriv;
-	urbp = urb->hcpriv;
-
-	/* Find the first URB in the queue */
-	furbp = eurbp;
-	if (eurbp->queued) {
-		list_for_each_entry(furbp, &eurbp->queue_list, queue_list)
-			if (!furbp->queued)
-				break;
-	}
-
-	lurbp = list_entry(furbp->queue_list.prev, struct urb_priv, queue_list);
-
-	lltd = list_entry(lurbp->td_list.prev, struct uhci_td, list);
-
-	/* Control transfers always start with toggle 0 */
-	if (!usb_pipecontrol(urb->pipe))
-		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-				usb_pipeout(urb->pipe),
-				uhci_fixup_toggle(urb,
-					uhci_toggle(td_token(lltd)) ^ 1));
-
-	/* All qhs in the queue need to link to the next queue */
-	urbp->qh->link = eurbp->qh->link;
-
-	wmb();			/* Make sure we flush everything */
-
-	lltd->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
-
-	list_add_tail(&urbp->queue_list, &furbp->queue_list);
-
-	urbp->queued = 1;
-}
-
-static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb)
-{
-	struct urb_priv *urbp, *nurbp, *purbp, *turbp;
-	struct uhci_td *pltd;
-	unsigned int toggle;
-
-	urbp = urb->hcpriv;
-
-	if (list_empty(&urbp->queue_list))
-		return;
-
-	nurbp = list_entry(urbp->queue_list.next, struct urb_priv, queue_list);
-
-	/*
-	 * Fix up the toggle for the following URBs in the queue.
-	 * Only needed for bulk and interrupt: control and isochronous
-	 * endpoints don't propagate toggles between messages.
-	 */
-	if (usb_pipebulk(urb->pipe) || usb_pipeint(urb->pipe)) {
-		if (!urbp->queued)
-			/* We just set the toggle in uhci_unlink_generic */
-			toggle = usb_gettoggle(urb->dev,
-					usb_pipeendpoint(urb->pipe),
-					usb_pipeout(urb->pipe));
-		else {
-			/* If we're in the middle of the queue, grab the */
-			/* toggle from the TD previous to us */
-			purbp = list_entry(urbp->queue_list.prev,
-					struct urb_priv, queue_list);
-			pltd = list_entry(purbp->td_list.prev,
-					struct uhci_td, list);
-			toggle = uhci_toggle(td_token(pltd)) ^ 1;
-		}
-
-		list_for_each_entry(turbp, &urbp->queue_list, queue_list) {
-			if (!turbp->queued)
-				break;
-			toggle = uhci_fixup_toggle(turbp->urb, toggle);
-		}
-
-		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-				usb_pipeout(urb->pipe), toggle);
-	}
-
-	if (urbp->queued) {
-		/* We're somewhere in the middle (or end).  The case where
-		 * we're at the head is handled in uhci_remove_qh(). */
-		purbp = list_entry(urbp->queue_list.prev, struct urb_priv,
-				queue_list);
-
-		pltd = list_entry(purbp->td_list.prev, struct uhci_td, list);
-		if (nurbp->queued)
-			pltd->link = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
-		else
-			/* The next URB happens to be the beginning, so */
-			/*  we're the last, end the chain */
-			pltd->link = UHCI_PTR_TERM;
-	}
-
-	/* urbp->queue_list is handled in uhci_remove_qh() */
-}
-
-static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
+static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
+		struct urb *urb)
 {
 	struct urb_priv *urbp;
 
@@ -453,16 +340,13 @@
 
 	memset((void *)urbp, 0, sizeof(*urbp));
 
-	urbp->fsbrtime = jiffies;
 	urbp->urb = urb;
-	
-	INIT_LIST_HEAD(&urbp->td_list);
-	INIT_LIST_HEAD(&urbp->queue_list);
-	INIT_LIST_HEAD(&urbp->urb_list);
-
-	list_add_tail(&urbp->urb_list, &uhci->urb_list);
-
 	urb->hcpriv = urbp;
+	urbp->fsbrtime = jiffies;
+	
+	INIT_LIST_HEAD(&urbp->node);
+	INIT_LIST_HEAD(&urbp->td_list);
+	INIT_LIST_HEAD(&urbp->urb_list);
 
 	return urbp;
 }
@@ -482,18 +366,17 @@
 	list_del_init(&td->list);
 }
 
-static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
+static void uhci_free_urb_priv(struct uhci_hcd *uhci,
+		struct urb_priv *urbp)
 {
 	struct uhci_td *td, *tmp;
-	struct urb_priv *urbp;
-
-	urbp = (struct urb_priv *)urb->hcpriv;
-	if (!urbp)
-		return;
 
 	if (!list_empty(&urbp->urb_list))
-		dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list "
-				"or uhci->remove_list!\n", urb);
+		dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list!\n",
+				urbp->urb);
+	if (!list_empty(&urbp->node))
+		dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
+				urbp->urb);
 
 	uhci_get_current_frame_number(uhci);
 	if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) {
@@ -502,7 +385,7 @@
 	}
 
 	/* Check to see if the remove list is empty. Set the IOC bit */
-	/* to force an interrupt so we can remove the TDs*/
+	/* to force an interrupt so we can remove the TDs. */
 	if (list_empty(&uhci->td_remove_list))
 		uhci_set_next_interrupt(uhci);
 
@@ -511,7 +394,7 @@
 		list_add(&td->remove_list, &uhci->td_remove_list);
 	}
 
-	urb->hcpriv = NULL;
+	urbp->urb->hcpriv = NULL;
 	kmem_cache_free(uhci_up_cachep, urbp);
 }
 
@@ -568,17 +451,82 @@
 }
 
 /*
+ * Fix up the data toggles for URBs in a queue, when one of them
+ * terminates early (short transfer, error, or dequeued).
+ */
+static void uhci_fixup_toggles(struct urb *urb)
+{
+	struct list_head *head;
+	struct uhci_td *td;
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+	int prevactive = 0;
+	unsigned int toggle = 0;
+	struct urb_priv *turbp, *list_end;
+
+	/*
+	 * We need to find out what the last successful toggle was so
+	 * we can update the data toggles for the following transfers.
+	 *
+	 * There are 2 ways the last successful completed TD is found:
+	 *
+	 * 1) The TD is NOT active and the actual length < expected length
+	 * 2) The TD is NOT active and it's the last TD in the chain
+	 *
+	 * and a third way the first uncompleted TD is found:
+	 *
+	 * 3) The TD is active and the previous TD is NOT active
+	 */
+	head = &urbp->td_list;
+	list_for_each_entry(td, head, list) {
+		unsigned int ctrlstat = td_status(td);
+
+		if (!(ctrlstat & TD_CTRL_ACTIVE) &&
+				(uhci_actual_length(ctrlstat) <
+				 uhci_expected_length(td_token(td)) ||
+				td->list.next == head))
+			toggle = uhci_toggle(td_token(td)) ^ 1;
+		else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
+			toggle = uhci_toggle(td_token(td));
+
+		prevactive = ctrlstat & TD_CTRL_ACTIVE;
+	}
+
+	/*
+	 * Fix up the toggle for the following URBs in the queue.
+	 *
+	 * We can stop as soon as we find an URB with toggles set correctly,
+	 * because then all the following URBs will be correct also.
+	 */
+	list_end = list_entry(&urbp->qh->queue, struct urb_priv, node);
+	turbp = urbp;
+	while ((turbp = list_entry(turbp->node.next, struct urb_priv, node))
+			!= list_end) {
+		td = list_entry(turbp->td_list.next, struct uhci_td, list);
+		if (uhci_toggle(td_token(td)) == toggle)
+			return;
+
+		list_for_each_entry(td, &turbp->td_list, list) {
+			td->token ^= __constant_cpu_to_le32(TD_TOKEN_TOGGLE);
+			toggle ^= 1;
+		}
+	}
+
+	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			usb_pipeout(urb->pipe), toggle);
+}
+
+/*
  * Control transfers
  */
-static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
+static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
 {
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	struct uhci_td *td;
-	struct uhci_qh *qh, *skelqh;
 	unsigned long destination, status;
-	int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
 	int len = urb->transfer_buffer_length;
 	dma_addr_t data = urb->transfer_dma;
+	__le32 *plink;
 
 	/* The "pipe" thing contains the destination in bits 8--18 */
 	destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -597,7 +545,8 @@
 
 	uhci_add_td_to_urb(urb, td);
 	uhci_fill_td(td, status, destination | uhci_explen(8),
-		urb->setup_dma);
+			urb->setup_dma);
+	plink = &td->link;
 
 	/*
 	 * If direction is "send", change the packet ID from SETUP (0x2D)
@@ -615,21 +564,20 @@
 	 * Build the DATA TDs
 	 */
 	while (len > 0) {
-		int pktsze = len;
-
-		if (pktsze > maxsze)
-			pktsze = maxsze;
+		int pktsze = min(len, maxsze);
 
 		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
+		*plink = cpu_to_le32(td->dma_handle);
 
 		/* Alternate Data0/1 (start with Data1) */
 		destination ^= TD_TOKEN_TOGGLE;
 	
 		uhci_add_td_to_urb(urb, td);
 		uhci_fill_td(td, status, destination | uhci_explen(pktsze),
-			data);
+				data);
+		plink = &td->link;
 
 		data += pktsze;
 		len -= pktsze;
@@ -641,6 +589,7 @@
 	td = uhci_alloc_td(uhci);
 	if (!td)
 		return -ENOMEM;
+	*plink = cpu_to_le32(td->dma_handle);
 
 	/*
 	 * It's IN if the pipe is an output pipe or we're not expecting
@@ -658,16 +607,7 @@
 
 	uhci_add_td_to_urb(urb, td);
 	uhci_fill_td(td, status | TD_CTRL_IOC,
-		destination | uhci_explen(0), 0);
-
-	qh = uhci_alloc_qh(uhci);
-	if (!qh)
-		return -ENOMEM;
-
-	urbp->qh = qh;
-	qh->urbp = urbp;
-
-	uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
+			destination | uhci_explen(0), 0);
 
 	/* Low-speed transfers get a different queue, and won't hog the bus.
 	 * Also, some devices enumerate better without FSBR; the easiest way
@@ -675,18 +615,13 @@
 	 * isn't in the CONFIGURED state. */
 	if (urb->dev->speed == USB_SPEED_LOW ||
 			urb->dev->state != USB_STATE_CONFIGURED)
-		skelqh = uhci->skel_ls_control_qh;
+		qh->skel = uhci->skel_ls_control_qh;
 	else {
-		skelqh = uhci->skel_fs_control_qh;
+		qh->skel = uhci->skel_fs_control_qh;
 		uhci_inc_fsbr(uhci, urb);
 	}
 
-	if (eurb)
-		uhci_append_queued_urb(uhci, eurb, urb);
-	else
-		uhci_insert_qh(uhci, skelqh, urb);
-
-	return -EINPROGRESS;
+	return 0;
 }
 
 /*
@@ -703,7 +638,7 @@
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	struct uhci_td *td;
 
-	urbp->short_control_packet = 1;
+	urbp->short_transfer = 1;
 
 	td = list_entry(urbp->td_list.prev, struct uhci_td, list);
 	urbp->qh->element = cpu_to_le32(td->dma_handle);
@@ -720,16 +655,14 @@
 	unsigned int status;
 	int ret = 0;
 
-	if (list_empty(&urbp->td_list))
-		return -EINVAL;
-
 	head = &urbp->td_list;
-
-	if (urbp->short_control_packet) {
+	if (urbp->short_transfer) {
 		tmp = head->prev;
 		goto status_stage;
 	}
 
+	urb->actual_length = 0;
+
 	tmp = head->next;
 	td = list_entry(tmp, struct uhci_td, list);
 
@@ -742,8 +675,6 @@
 	if (status)
 		goto td_error;
 
-	urb->actual_length = 0;
-
 	/* The rest of the TDs (but the last) are data */
 	tmp = tmp->next;
 	while (tmp != head && tmp->next != head) {
@@ -770,10 +701,7 @@
 				goto err;
 			}
 
-			if (uhci_packetid(td_token(td)) == USB_PID_IN)
-				return usb_control_retrigger_status(uhci, urb);
-			else
-				return 0;
+			return usb_control_retrigger_status(uhci, urb);
 		}
 	}
 
@@ -825,15 +753,15 @@
 /*
  * Common submit for bulk and interrupt
  */
-static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb, struct uhci_qh *skelqh)
+static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
 {
 	struct uhci_td *td;
-	struct uhci_qh *qh;
 	unsigned long destination, status;
-	int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
 	int len = urb->transfer_buffer_length;
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	dma_addr_t data = urb->transfer_dma;
+	__le32 *plink, fake_link;
 
 	if (len < 0)
 		return -EINVAL;
@@ -841,7 +769,8 @@
 	/* The "pipe" thing contains the destination in bits 8--18 */
 	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
 
-	status = uhci_maxerr(3) | TD_CTRL_ACTIVE;
+	/* 3 errors */
+	status = TD_CTRL_ACTIVE | uhci_maxerr(3);
 	if (urb->dev->speed == USB_SPEED_LOW)
 		status |= TD_CTRL_LS;
 	if (usb_pipein(urb->pipe))
@@ -850,10 +779,11 @@
 	/*
 	 * Build the DATA TDs
 	 */
+	plink = &fake_link;
 	do {	/* Allow zero length packets */
 		int pktsze = maxsze;
 
-		if (pktsze >= len) {
+		if (len <= pktsze) {		/* The last packet */
 			pktsze = len;
 			if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
 				status &= ~TD_CTRL_SPD;
@@ -862,12 +792,15 @@
 		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
+		*plink = cpu_to_le32(td->dma_handle);
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(pktsze) |
+		uhci_fill_td(td, status,
+			destination | uhci_explen(pktsze) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
 			data);
+		plink = &td->link;
 
 		data += pktsze;
 		len -= maxsze;
@@ -883,11 +816,13 @@
 	 * however, if transfer_length == 0, the zero packet was already
 	 * prepared above.
 	 */
-	if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) &&
-	    !len && urb->transfer_buffer_length) {
+	if ((urb->transfer_flags & URB_ZERO_PACKET) &&
+			usb_pipeout(urb->pipe) && len == 0 &&
+			urb->transfer_buffer_length > 0) {
 		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
+		*plink = cpu_to_le32(td->dma_handle);
 
 		uhci_add_td_to_urb(urb, td);
 		uhci_fill_td(td, status, destination | uhci_explen(0) |
@@ -905,24 +840,9 @@
 	 * fast side but not enough to justify delaying an interrupt
 	 * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
 	 * flag setting. */
-	td->status |= cpu_to_le32(TD_CTRL_IOC);
+	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
 
-	qh = uhci_alloc_qh(uhci);
-	if (!qh)
-		return -ENOMEM;
-
-	urbp->qh = qh;
-	qh->urbp = urbp;
-
-	/* Always breadth first */
-	uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
-
-	if (eurb)
-		uhci_append_queued_urb(uhci, eurb, urb);
-	else
-		uhci_insert_qh(uhci, skelqh, urb);
-
-	return -EINPROGRESS;
+	return 0;
 }
 
 /*
@@ -954,8 +874,24 @@
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				ret = -EREMOTEIO;
 				goto err;
-			} else
-				return 0;
+			}
+
+			/*
+			 * This URB stopped short of its end.  We have to
+			 * fix up the toggles of the following URBs on the
+			 * queue and restart the queue.
+			 *
+			 * Do this only the first time we encounter the
+			 * short URB.
+			 */
+			if (!urbp->short_transfer) {
+				urbp->short_transfer = 1;
+				uhci_fixup_toggles(urb);
+				td = list_entry(urbp->td_list.prev,
+						struct uhci_td, list);
+				urbp->qh->element = td->link;
+			}
+			break;
 		}
 	}
 
@@ -988,7 +924,8 @@
 	return ret;
 }
 
-static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
+static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
 {
 	int ret;
 
@@ -996,21 +933,22 @@
 	if (urb->dev->speed == USB_SPEED_LOW)
 		return -EINVAL;
 
-	ret = uhci_submit_common(uhci, urb, eurb, uhci->skel_bulk_qh);
-	if (ret == -EINPROGRESS)
+	qh->skel = uhci->skel_bulk_qh;
+	ret = uhci_submit_common(uhci, urb, qh);
+	if (ret == 0)
 		uhci_inc_fsbr(uhci, urb);
-
 	return ret;
 }
 
-static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
+static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
 {
-	/* USB 1.1 interrupt transfers only involve one packet per interval;
-	 * that's the uhci_submit_common() "breadth first" policy.  Drivers
-	 * can submit urbs of any length, but longer ones might need many
-	 * intervals to complete.
+	/* USB 1.1 interrupt transfers only involve one packet per interval.
+	 * Drivers can submit URBs of any length, but longer ones will need
+	 * multiple intervals to complete.
 	 */
-	return uhci_submit_common(uhci, urb, eurb, uhci->skelqh[__interval_to_skel(urb->interval)]);
+	qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)];
+	return uhci_submit_common(uhci, urb, qh);
 }
 
 /*
@@ -1072,11 +1010,12 @@
 /*
  * Isochronous transfers
  */
-static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
+static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
+		struct uhci_qh *qh)
 {
-	struct uhci_td *td;
+	struct uhci_td *td = NULL;	/* Since urb->number_of_packets > 0 */
 	int i, ret, frame;
-	int status, destination;
+	unsigned long destination, status;
 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
 
 	status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
@@ -1092,20 +1031,25 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length),
-			urb->transfer_dma + urb->iso_frame_desc[i].offset);
-
-		if (i + 1 >= urb->number_of_packets)
-			td->status |= cpu_to_le32(TD_CTRL_IOC);
+		uhci_fill_td(td, status, destination |
+				uhci_explen(urb->iso_frame_desc[i].length),
+				urb->transfer_dma +
+					urb->iso_frame_desc[i].offset);
 	}
 
+	/* Set the interrupt-on-completion flag on the last packet. */
+	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+
+	qh->skel = uhci->skel_iso_qh;
+
+	/* Add the TDs to the frame list */
 	frame = urb->start_frame;
 	list_for_each_entry(td, &urbp->td_list, list) {
-		uhci_insert_td_frame_list(uhci, td, frame);
+		uhci_insert_td_in_frame_list(uhci, td, frame);
 		frame += urb->interval;
 	}
 
-	return -EINPROGRESS;
+	return 0;
 }
 
 static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
@@ -1139,80 +1083,67 @@
 
 		i++;
 	}
-	unlink_isochronous_tds(uhci, urb);
 
 	return ret;
 }
 
-static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb)
-{
-	struct urb_priv *up;
-
-	/* We don't match Isoc transfers since they are special */
-	if (usb_pipeisoc(urb->pipe))
-		return NULL;
-
-	list_for_each_entry(up, &uhci->urb_list, urb_list) {
-		struct urb *u = up->urb;
-
-		if (u->dev == urb->dev && u->status == -EINPROGRESS) {
-			/* For control, ignore the direction */
-			if (usb_pipecontrol(urb->pipe) &&
-			    (u->pipe & ~USB_DIR_IN) == (urb->pipe & ~USB_DIR_IN))
-				return u;
-			else if (u->pipe == urb->pipe)
-				return u;
-		}
-	}
-
-	return NULL;
-}
-
 static int uhci_urb_enqueue(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep,
+		struct usb_host_endpoint *hep,
 		struct urb *urb, gfp_t mem_flags)
 {
 	int ret;
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	unsigned long flags;
-	struct urb *eurb;
+	struct urb_priv *urbp;
+	struct uhci_qh *qh;
 	int bustime;
 
 	spin_lock_irqsave(&uhci->lock, flags);
 
 	ret = urb->status;
 	if (ret != -EINPROGRESS)		/* URB already unlinked! */
-		goto out;
+		goto done;
 
-	eurb = uhci_find_urb_ep(uhci, urb);
+	ret = -ENOMEM;
+	urbp = uhci_alloc_urb_priv(uhci, urb);
+	if (!urbp)
+		goto done;
 
-	if (!uhci_alloc_urb_priv(uhci, urb)) {
-		ret = -ENOMEM;
-		goto out;
+	if (hep->hcpriv)
+		qh = (struct uhci_qh *) hep->hcpriv;
+	else {
+		qh = uhci_alloc_qh(uhci, urb->dev, hep);
+		if (!qh)
+			goto err_no_qh;
 	}
+	urbp->qh = qh;
 
 	switch (usb_pipetype(urb->pipe)) {
 	case PIPE_CONTROL:
-		ret = uhci_submit_control(uhci, urb, eurb);
+		ret = uhci_submit_control(uhci, urb, qh);
+		break;
+	case PIPE_BULK:
+		ret = uhci_submit_bulk(uhci, urb, qh);
 		break;
 	case PIPE_INTERRUPT:
-		if (!eurb) {
+		if (list_empty(&qh->queue)) {
 			bustime = usb_check_bandwidth(urb->dev, urb);
 			if (bustime < 0)
 				ret = bustime;
 			else {
-				ret = uhci_submit_interrupt(uhci, urb, eurb);
-				if (ret == -EINPROGRESS)
+				ret = uhci_submit_interrupt(uhci, urb, qh);
+				if (ret == 0)
 					usb_claim_bandwidth(urb->dev, urb, bustime, 0);
 			}
 		} else {	/* inherit from parent */
-			urb->bandwidth = eurb->bandwidth;
-			ret = uhci_submit_interrupt(uhci, urb, eurb);
+			struct urb_priv *eurbp;
+
+			eurbp = list_entry(qh->queue.prev, struct urb_priv,
+					node);
+			urb->bandwidth = eurbp->urb->bandwidth;
+			ret = uhci_submit_interrupt(uhci, urb, qh);
 		}
 		break;
-	case PIPE_BULK:
-		ret = uhci_submit_bulk(uhci, urb, eurb);
-		break;
 	case PIPE_ISOCHRONOUS:
 		bustime = usb_check_bandwidth(urb->dev, urb);
 		if (bustime < 0) {
@@ -1220,22 +1151,59 @@
 			break;
 		}
 
-		ret = uhci_submit_isochronous(uhci, urb);
-		if (ret == -EINPROGRESS)
+		ret = uhci_submit_isochronous(uhci, urb, qh);
+		if (ret == 0)
 			usb_claim_bandwidth(urb->dev, urb, bustime, 1);
 		break;
 	}
+	if (ret != 0)
+		goto err_submit_failed;
 
-	if (ret != -EINPROGRESS) {
-		/* Submit failed, so delete it from the urb_list */
-		struct urb_priv *urbp = urb->hcpriv;
+	/* Add this URB to the QH */
+	urbp->qh = qh;
+	list_add_tail(&urbp->node, &qh->queue);
+	list_add_tail(&urbp->urb_list, &uhci->urb_list);
 
-		list_del_init(&urbp->urb_list);
-		uhci_destroy_urb_priv(uhci, urb);
-	} else
-		ret = 0;
+	/* If the new URB is the first and only one on this QH then either
+	 * the QH is new and idle or else it's unlinked and waiting to
+	 * become idle, so we can activate it right away. */
+	if (qh->queue.next == &urbp->node)
+		uhci_activate_qh(uhci, qh);
 
-out:
+	/* If the QH is already active, we have a race with the hardware.
+	 * This won't get fixed until dummy TDs are added. */
+	else if (qh->state == QH_STATE_ACTIVE) {
+
+		/* If the URB isn't first on its queue, adjust the link pointer
+		 * of the last TD in the previous URB. */
+		if (urbp->node.prev != &urbp->qh->queue) {
+			struct urb_priv *purbp = list_entry(urbp->node.prev,
+					struct urb_priv, node);
+			struct uhci_td *ptd = list_entry(purbp->td_list.prev,
+					struct uhci_td, list);
+			struct uhci_td *td = list_entry(urbp->td_list.next,
+					struct uhci_td, list);
+
+			ptd->link = cpu_to_le32(td->dma_handle);
+
+		}
+		if (qh_element(qh) == UHCI_PTR_TERM) {
+			struct uhci_td *td = list_entry(urbp->td_list.next,
+					struct uhci_td, list);
+
+			qh->element = cpu_to_le32(td->dma_handle);
+		}
+	}
+	goto done;
+
+err_submit_failed:
+	if (qh->state == QH_STATE_IDLE)
+		uhci_make_qh_idle(uhci, qh);	/* Reclaim unused QH */
+
+err_no_qh:
+	uhci_free_urb_priv(uhci, urbp);
+
+done:
 	spin_unlock_irqrestore(&uhci->lock, flags);
 	return ret;
 }
@@ -1245,119 +1213,115 @@
  */
 static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb)
 {
-	int ret = -EINPROGRESS;
-	struct urb_priv *urbp;
-
-	spin_lock(&urb->lock);
-
-	urbp = (struct urb_priv *)urb->hcpriv;
-
-	if (urb->status != -EINPROGRESS)	/* URB already dequeued */
-		goto out;
+	int status;
+	int okay_to_giveback = 0;
+	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
 
 	switch (usb_pipetype(urb->pipe)) {
 	case PIPE_CONTROL:
-		ret = uhci_result_control(uhci, urb);
-		break;
-	case PIPE_BULK:
-	case PIPE_INTERRUPT:
-		ret = uhci_result_common(uhci, urb);
+		status = uhci_result_control(uhci, urb);
 		break;
 	case PIPE_ISOCHRONOUS:
-		ret = uhci_result_isochronous(uhci, urb);
+		status = uhci_result_isochronous(uhci, urb);
+		break;
+	default:	/* PIPE_BULK or PIPE_INTERRUPT */
+		status = uhci_result_common(uhci, urb);
 		break;
 	}
 
-	if (ret == -EINPROGRESS)
-		goto out;
-	urb->status = ret;
+	spin_lock(&urb->lock);
+	if (urb->status == -EINPROGRESS) {	/* Not yet dequeued */
+		if (status != -EINPROGRESS) {	/* URB has completed */
+			urb->status = status;
+
+			/* If the URB got a real error (as opposed to
+			 * simply being dequeued), we don't have to
+			 * unlink the QH.  Fix this later... */
+			if (status < 0)
+				uhci_unlink_qh(uhci, urbp->qh);
+			else
+				okay_to_giveback = 1;
+		}
+	} else {				/* Already dequeued */
+		if (urbp->qh->state == QH_STATE_UNLINKING &&
+				uhci->frame_number + uhci->is_stopped !=
+				urbp->qh->unlink_frame)
+			okay_to_giveback = 1;
+	}
+	spin_unlock(&urb->lock);
+	if (!okay_to_giveback)
+		return;
 
 	switch (usb_pipetype(urb->pipe)) {
-	case PIPE_CONTROL:
-	case PIPE_BULK:
 	case PIPE_ISOCHRONOUS:
 		/* Release bandwidth for Interrupt or Isoc. transfers */
 		if (urb->bandwidth)
 			usb_release_bandwidth(urb->dev, urb, 1);
-		uhci_unlink_generic(uhci, urb);
 		break;
 	case PIPE_INTERRUPT:
 		/* Release bandwidth for Interrupt or Isoc. transfers */
 		/* Make sure we don't release if we have a queued URB */
-		if (list_empty(&urbp->queue_list) && urb->bandwidth)
+		if (list_empty(&urbp->qh->queue) && urb->bandwidth)
 			usb_release_bandwidth(urb->dev, urb, 0);
 		else
 			/* bandwidth was passed on to queued URB, */
 			/* so don't let usb_unlink_urb() release it */
 			urb->bandwidth = 0;
-		uhci_unlink_generic(uhci, urb);
+		/* Falls through */
+	case PIPE_BULK:
+		if (status < 0)
+			uhci_fixup_toggles(urb);
 		break;
-	default:
-		dev_info(uhci_dev(uhci), "%s: unknown pipe type %d "
-				"for urb %p\n",
-				__FUNCTION__, usb_pipetype(urb->pipe), urb);
+	default:	/* PIPE_CONTROL */
+		break;
 	}
 
-	/* Move it from uhci->urb_list to uhci->complete_list */
-	uhci_moveto_complete(uhci, urbp);
+	/* Take the URB's TDs off the hardware schedule */
+	uhci_remove_tds_from_schedule(uhci, urb, status);
 
-out:
-	spin_unlock(&urb->lock);
-}
-
-static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb)
-{
-	struct list_head *head;
-	struct uhci_td *td;
-	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-	int prevactive = 0;
+	/* Take the URB off the QH's queue and see if the QH is now unused */
+	list_del_init(&urbp->node);
+	if (list_empty(&urbp->qh->queue))
+		uhci_unlink_qh(uhci, urbp->qh);
 
 	uhci_dec_fsbr(uhci, urb);	/* Safe since it checks */
 
-	/*
-	 * Now we need to find out what the last successful toggle was
-	 * so we can update the local data toggle for the next transfer
-	 *
-	 * There are 2 ways the last successful completed TD is found:
-	 *
-	 * 1) The TD is NOT active and the actual length < expected length
-	 * 2) The TD is NOT active and it's the last TD in the chain
-	 *
-	 * and a third way the first uncompleted TD is found:
-	 *
-	 * 3) The TD is active and the previous TD is NOT active
-	 *
-	 * Control and Isochronous ignore the toggle, so this is safe
-	 * for all types
-	 *
-	 * FIXME: The toggle fixups won't be 100% reliable until we
-	 * change over to using a single queue for each endpoint and
-	 * stop the queue before unlinking.
-	 */
-	head = &urbp->td_list;
-	list_for_each_entry(td, head, list) {
-		unsigned int ctrlstat = td_status(td);
+	/* Queue it for giving back */
+	list_move_tail(&urbp->urb_list, &uhci->complete_list);
+}
 
-		if (!(ctrlstat & TD_CTRL_ACTIVE) &&
-				(uhci_actual_length(ctrlstat) <
-				 uhci_expected_length(td_token(td)) ||
-				td->list.next == head))
-			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
-				uhci_packetout(td_token(td)),
-				uhci_toggle(td_token(td)) ^ 1);
-		else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
-			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
-				uhci_packetout(td_token(td)),
-				uhci_toggle(td_token(td)));
+/*
+ * Check out the QHs waiting to be fully unlinked
+ */
+static void uhci_scan_unlinking_qhs(struct uhci_hcd *uhci)
+{
+	struct uhci_qh *qh, *tmp;
 
-		prevactive = ctrlstat & TD_CTRL_ACTIVE;
+	list_for_each_entry_safe(qh, tmp, &uhci->skel_unlink_qh->node, node) {
+
+		/* If the queue is empty and the QH is fully unlinked then
+		 * it can become IDLE. */
+		if (list_empty(&qh->queue)) {
+			if (uhci->frame_number + uhci->is_stopped !=
+					qh->unlink_frame)
+				uhci_make_qh_idle(uhci, qh);
+
+		/* If none of the QH's URBs have been dequeued then the QH
+		 * should be re-activated. */
+		} else {
+			struct urb_priv *urbp;
+			int any_dequeued = 0;
+
+			list_for_each_entry(urbp, &qh->queue, node) {
+				if (urbp->urb->status != -EINPROGRESS) {
+					any_dequeued = 1;
+					break;
+				}
+			}
+			if (!any_dequeued)
+				uhci_activate_qh(uhci, qh);
+		}
 	}
-
-	uhci_delete_queued_urb(uhci, urb);
-
-	/* The interrupt loop will reclaim the QHs */
-	uhci_remove_qh(uhci, urbp->qh);
-	urbp->qh = NULL;
 }
 
 static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
@@ -1370,22 +1334,11 @@
 	urbp = urb->hcpriv;
 	if (!urbp)			/* URB was never linked! */
 		goto done;
-	list_del_init(&urbp->urb_list);
 
+	/* Remove Isochronous TDs from the frame list ASAP */
 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
-		unlink_isochronous_tds(uhci, urb);
-	uhci_unlink_generic(uhci, urb);
-
-	uhci_get_current_frame_number(uhci);
-	if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age) {
-		uhci_remove_pending_urbps(uhci);
-		uhci->urb_remove_age = uhci->frame_number;
-	}
-
-	/* If we're the first, set the next interrupt bit */
-	if (list_empty(&uhci->urb_remove_list))
-		uhci_set_next_interrupt(uhci);
-	list_add_tail(&urbp->urb_list, &uhci->urb_remove_list);
+		uhci_unlink_isochronous_tds(uhci, urb);
+	uhci_unlink_qh(uhci, urbp->qh);
 
 done:
 	spin_unlock_irqrestore(&uhci->lock, flags);
@@ -1426,17 +1379,6 @@
 	return 0;
 }
 
-static void uhci_free_pending_qhs(struct uhci_hcd *uhci)
-{
-	struct uhci_qh *qh, *tmp;
-
-	list_for_each_entry_safe(qh, tmp, &uhci->qh_remove_list, remove_list) {
-		list_del_init(&qh->remove_list);
-
-		uhci_free_qh(uhci, qh);
-	}
-}
-
 static void uhci_free_pending_tds(struct uhci_hcd *uhci)
 {
 	struct uhci_td *td, *tmp;
@@ -1455,7 +1397,7 @@
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
-	uhci_destroy_urb_priv(uhci, urb);
+	uhci_free_urb_priv(uhci, (struct urb_priv *) (urb->hcpriv));
 
 	spin_unlock(&uhci->lock);
 	usb_hcd_giveback_urb(hcd, urb, regs);
@@ -1474,13 +1416,6 @@
 	}
 }
 
-static void uhci_remove_pending_urbps(struct uhci_hcd *uhci)
-{
-
-	/* Splice the urb_remove_list onto the end of the complete_list */
-	list_splice_init(&uhci->urb_remove_list, uhci->complete_list.prev);
-}
-
 /* Process events in the schedule, but only in one thread at a time */
 static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
 {
@@ -1498,12 +1433,8 @@
 	uhci_clear_next_interrupt(uhci);
 	uhci_get_current_frame_number(uhci);
 
-	if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age)
-		uhci_free_pending_qhs(uhci);
 	if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age)
 		uhci_free_pending_tds(uhci);
-	if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age)
-		uhci_remove_pending_urbps(uhci);
 
 	/* Walk the list of pending URBs to see which ones completed
 	 * (must be _safe because uhci_transfer_result() dequeues URBs) */
@@ -1516,25 +1447,21 @@
 	uhci_finish_completion(uhci, regs);
 
 	/* If the controller is stopped, we can finish these off right now */
-	if (uhci->is_stopped) {
-		uhci_free_pending_qhs(uhci);
+	if (uhci->is_stopped)
 		uhci_free_pending_tds(uhci);
-		uhci_remove_pending_urbps(uhci);
-	}
 
 	if (uhci->need_rescan)
 		goto rescan;
 	uhci->scan_in_progress = 0;
 
-	if (list_empty(&uhci->urb_remove_list) &&
-	    list_empty(&uhci->td_remove_list) &&
-	    list_empty(&uhci->qh_remove_list))
+	/* Check out the QHs waiting for unlinking */
+	uhci_scan_unlinking_qhs(uhci);
+
+	if (list_empty(&uhci->td_remove_list) &&
+			list_empty(&uhci->skel_unlink_qh->node))
 		uhci_clear_next_interrupt(uhci);
 	else
 		uhci_set_next_interrupt(uhci);
-
-	/* Wake up anyone waiting for an URB to complete */
-	wake_up_all(&uhci->waitqh);
 }
 
 static void check_fsbr(struct uhci_hcd *uhci)