xref: /openbmc/linux/drivers/usb/host/uhci-q.c (revision af0bb5998abe8ed28ee354dd4c71689cacdc91e9)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Universal Host Controller Interface driver for USB.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Maintainer: Alan Stern <stern@rowland.harvard.edu>
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * (C) Copyright 1999 Linus Torvalds
71da177e4SLinus Torvalds  * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
81da177e4SLinus Torvalds  * (C) Copyright 1999 Randy Dunlap
91da177e4SLinus Torvalds  * (C) Copyright 1999 Georg Acher, acher@in.tum.de
101da177e4SLinus Torvalds  * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
111da177e4SLinus Torvalds  * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch
121da177e4SLinus Torvalds  * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at
131da177e4SLinus Torvalds  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
141da177e4SLinus Torvalds  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
151da177e4SLinus Torvalds  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
16dccf4a48SAlan Stern  * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds static void uhci_free_pending_tds(struct uhci_hcd *uhci);
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds /*
221da177e4SLinus Torvalds  * Technically, updating td->status here is a race, but it's not really a
231da177e4SLinus Torvalds  * problem. The worst that can happen is that we set the IOC bit again
241da177e4SLinus Torvalds  * generating a spurious interrupt. We could fix this by creating another
251da177e4SLinus Torvalds  * QH and leaving the IOC bit always set, but then we would have to play
261da177e4SLinus Torvalds  * games with the FSBR code to make sure we get the correct order in all
271da177e4SLinus Torvalds  * the cases. I don't think it's worth the effort
281da177e4SLinus Torvalds  */
29dccf4a48SAlan Stern static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
301da177e4SLinus Torvalds {
316c1b445cSAlan Stern 	if (uhci->is_stopped)
321f09df8bSAlan Stern 		mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
331da177e4SLinus Torvalds 	uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
341da177e4SLinus Torvalds }
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
371da177e4SLinus Torvalds {
381da177e4SLinus Torvalds 	uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds 
412532178aSAlan Stern static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
421da177e4SLinus Torvalds {
431da177e4SLinus Torvalds 	dma_addr_t dma_handle;
441da177e4SLinus Torvalds 	struct uhci_td *td;
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds 	td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
471da177e4SLinus Torvalds 	if (!td)
481da177e4SLinus Torvalds 		return NULL;
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds 	td->dma_handle = dma_handle;
511da177e4SLinus Torvalds 	td->frame = -1;
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds 	INIT_LIST_HEAD(&td->list);
541da177e4SLinus Torvalds 	INIT_LIST_HEAD(&td->remove_list);
551da177e4SLinus Torvalds 	INIT_LIST_HEAD(&td->fl_list);
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds 	return td;
581da177e4SLinus Torvalds }
591da177e4SLinus Torvalds 
60dccf4a48SAlan Stern static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
61dccf4a48SAlan Stern {
62dccf4a48SAlan Stern 	if (!list_empty(&td->list))
63dccf4a48SAlan Stern 		dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
64dccf4a48SAlan Stern 	if (!list_empty(&td->remove_list))
65dccf4a48SAlan Stern 		dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
66dccf4a48SAlan Stern 	if (!list_empty(&td->fl_list))
67dccf4a48SAlan Stern 		dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
68dccf4a48SAlan Stern 
69dccf4a48SAlan Stern 	dma_pool_free(uhci->td_pool, td, td->dma_handle);
70dccf4a48SAlan Stern }
71dccf4a48SAlan Stern 
721da177e4SLinus Torvalds static inline void uhci_fill_td(struct uhci_td *td, u32 status,
731da177e4SLinus Torvalds 		u32 token, u32 buffer)
741da177e4SLinus Torvalds {
751da177e4SLinus Torvalds 	td->status = cpu_to_le32(status);
761da177e4SLinus Torvalds 	td->token = cpu_to_le32(token);
771da177e4SLinus Torvalds 	td->buffer = cpu_to_le32(buffer);
781da177e4SLinus Torvalds }
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds /*
81687f5f34SAlan Stern  * We insert Isochronous URBs directly into the frame list at the beginning
821da177e4SLinus Torvalds  */
83dccf4a48SAlan Stern static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
84dccf4a48SAlan Stern 		struct uhci_td *td, unsigned framenum)
851da177e4SLinus Torvalds {
861da177e4SLinus Torvalds 	framenum &= (UHCI_NUMFRAMES - 1);
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds 	td->frame = framenum;
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds 	/* Is there a TD already mapped there? */
91a1d59ce8SAlan Stern 	if (uhci->frame_cpu[framenum]) {
921da177e4SLinus Torvalds 		struct uhci_td *ftd, *ltd;
931da177e4SLinus Torvalds 
94a1d59ce8SAlan Stern 		ftd = uhci->frame_cpu[framenum];
951da177e4SLinus Torvalds 		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds 		list_add_tail(&td->fl_list, &ftd->fl_list);
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds 		td->link = ltd->link;
1001da177e4SLinus Torvalds 		wmb();
1011da177e4SLinus Torvalds 		ltd->link = cpu_to_le32(td->dma_handle);
1021da177e4SLinus Torvalds 	} else {
103a1d59ce8SAlan Stern 		td->link = uhci->frame[framenum];
1041da177e4SLinus Torvalds 		wmb();
105a1d59ce8SAlan Stern 		uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
106a1d59ce8SAlan Stern 		uhci->frame_cpu[framenum] = td;
1071da177e4SLinus Torvalds 	}
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds 
110dccf4a48SAlan Stern static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
111b81d3436SAlan Stern 		struct uhci_td *td)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	/* If it's not inserted, don't remove it */
114b81d3436SAlan Stern 	if (td->frame == -1) {
115b81d3436SAlan Stern 		WARN_ON(!list_empty(&td->fl_list));
1161da177e4SLinus Torvalds 		return;
117b81d3436SAlan Stern 	}
1181da177e4SLinus Torvalds 
119b81d3436SAlan Stern 	if (uhci->frame_cpu[td->frame] == td) {
1201da177e4SLinus Torvalds 		if (list_empty(&td->fl_list)) {
121a1d59ce8SAlan Stern 			uhci->frame[td->frame] = td->link;
122a1d59ce8SAlan Stern 			uhci->frame_cpu[td->frame] = NULL;
1231da177e4SLinus Torvalds 		} else {
1241da177e4SLinus Torvalds 			struct uhci_td *ntd;
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds 			ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
127a1d59ce8SAlan Stern 			uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
128a1d59ce8SAlan Stern 			uhci->frame_cpu[td->frame] = ntd;
1291da177e4SLinus Torvalds 		}
1301da177e4SLinus Torvalds 	} else {
1311da177e4SLinus Torvalds 		struct uhci_td *ptd;
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 		ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list);
1341da177e4SLinus Torvalds 		ptd->link = td->link;
1351da177e4SLinus Torvalds 	}
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	list_del_init(&td->fl_list);
1381da177e4SLinus Torvalds 	td->frame = -1;
1391da177e4SLinus Torvalds }
1401da177e4SLinus Torvalds 
141dccf4a48SAlan Stern /*
142dccf4a48SAlan Stern  * Remove all the TDs for an Isochronous URB from the frame list
143dccf4a48SAlan Stern  */
144dccf4a48SAlan Stern static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
145b81d3436SAlan Stern {
146b81d3436SAlan Stern 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
147b81d3436SAlan Stern 	struct uhci_td *td;
148b81d3436SAlan Stern 
149b81d3436SAlan Stern 	list_for_each_entry(td, &urbp->td_list, list)
150dccf4a48SAlan Stern 		uhci_remove_td_from_frame_list(uhci, td);
151b81d3436SAlan Stern 	wmb();
152b81d3436SAlan Stern }
153b81d3436SAlan Stern 
1541da177e4SLinus Torvalds /*
155dccf4a48SAlan Stern  * Remove an URB's TDs from the hardware schedule
1561da177e4SLinus Torvalds  */
157dccf4a48SAlan Stern static void uhci_remove_tds_from_schedule(struct uhci_hcd *uhci,
158dccf4a48SAlan Stern 		struct urb *urb, int status)
1591da177e4SLinus Torvalds {
1601da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
1611da177e4SLinus Torvalds 
162dccf4a48SAlan Stern 	/* Isochronous TDs get unlinked directly from the frame list */
163dccf4a48SAlan Stern 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
164dccf4a48SAlan Stern 		uhci_unlink_isochronous_tds(uhci, urb);
165dccf4a48SAlan Stern 		return;
1661da177e4SLinus Torvalds 	}
1671da177e4SLinus Torvalds 
168dccf4a48SAlan Stern 	/* If the URB isn't first on its queue, adjust the link pointer
169dccf4a48SAlan Stern 	 * of the last TD in the previous URB. */
170dccf4a48SAlan Stern 	if (urbp->node.prev != &urbp->qh->queue) {
171dccf4a48SAlan Stern 		struct urb_priv *purbp;
172dccf4a48SAlan Stern 		struct uhci_td *ptd, *ltd;
1731da177e4SLinus Torvalds 
174dccf4a48SAlan Stern 		if (status == -EINPROGRESS)
175dccf4a48SAlan Stern 			status = 0;
176dccf4a48SAlan Stern 		purbp = list_entry(urbp->node.prev, struct urb_priv, node);
177dccf4a48SAlan Stern 		ptd = list_entry(purbp->td_list.prev, struct uhci_td,
178dccf4a48SAlan Stern 				list);
179dccf4a48SAlan Stern 		ltd = list_entry(urbp->td_list.prev, struct uhci_td,
180dccf4a48SAlan Stern 				list);
181dccf4a48SAlan Stern 		ptd->link = ltd->link;
1821da177e4SLinus Torvalds 	}
1831da177e4SLinus Torvalds 
184dccf4a48SAlan Stern 	/* If the URB completed with an error, then the QH element certainly
185dccf4a48SAlan Stern 	 * points to one of the URB's TDs.  If it completed normally then
186dccf4a48SAlan Stern 	 * the QH element has certainly moved on to the next URB.  And if
187dccf4a48SAlan Stern 	 * the URB is still in progress then it must have been dequeued.
188dccf4a48SAlan Stern 	 * The QH element either hasn't reached it yet or is somewhere in
189dccf4a48SAlan Stern 	 * the middle.  If the URB wasn't first we can assume that it
190dccf4a48SAlan Stern 	 * hasn't started yet (see above): Otherwise all the preceding URBs
191dccf4a48SAlan Stern 	 * would have completed and been removed from the queue, so this one
192dccf4a48SAlan Stern 	 * _would_ be first.
193dccf4a48SAlan Stern 	 *
194dccf4a48SAlan Stern 	 * If the QH element is inside this URB, clear it.  It will be
195dccf4a48SAlan Stern 	 * set properly when the QH is activated.
196dccf4a48SAlan Stern 	 */
197dccf4a48SAlan Stern 	if (status < 0)
198dccf4a48SAlan Stern 		urbp->qh->element = UHCI_PTR_TERM;
199dccf4a48SAlan Stern }
200dccf4a48SAlan Stern 
201dccf4a48SAlan Stern static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
202dccf4a48SAlan Stern 		struct usb_device *udev, struct usb_host_endpoint *hep)
2031da177e4SLinus Torvalds {
2041da177e4SLinus Torvalds 	dma_addr_t dma_handle;
2051da177e4SLinus Torvalds 	struct uhci_qh *qh;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
2081da177e4SLinus Torvalds 	if (!qh)
2091da177e4SLinus Torvalds 		return NULL;
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds 	qh->dma_handle = dma_handle;
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	qh->element = UHCI_PTR_TERM;
2141da177e4SLinus Torvalds 	qh->link = UHCI_PTR_TERM;
2151da177e4SLinus Torvalds 
216dccf4a48SAlan Stern 	INIT_LIST_HEAD(&qh->queue);
217dccf4a48SAlan Stern 	INIT_LIST_HEAD(&qh->node);
2181da177e4SLinus Torvalds 
219dccf4a48SAlan Stern 	if (udev) {		/* Normal QH */
220*af0bb599SAlan Stern 		qh->dummy_td = uhci_alloc_td(uhci);
221*af0bb599SAlan Stern 		if (!qh->dummy_td) {
222*af0bb599SAlan Stern 			dma_pool_free(uhci->qh_pool, qh, dma_handle);
223*af0bb599SAlan Stern 			return NULL;
224*af0bb599SAlan Stern 		}
225dccf4a48SAlan Stern 		qh->state = QH_STATE_IDLE;
226dccf4a48SAlan Stern 		qh->hep = hep;
227dccf4a48SAlan Stern 		qh->udev = udev;
228dccf4a48SAlan Stern 		hep->hcpriv = qh;
229dccf4a48SAlan Stern 		usb_get_dev(udev);
2301da177e4SLinus Torvalds 
231dccf4a48SAlan Stern 	} else {		/* Skeleton QH */
232dccf4a48SAlan Stern 		qh->state = QH_STATE_ACTIVE;
233dccf4a48SAlan Stern 		qh->udev = NULL;
234dccf4a48SAlan Stern 	}
2351da177e4SLinus Torvalds 	return qh;
2361da177e4SLinus Torvalds }
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
2391da177e4SLinus Torvalds {
240dccf4a48SAlan Stern 	WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
241dccf4a48SAlan Stern 	if (!list_empty(&qh->queue))
2421da177e4SLinus Torvalds 		dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
2431da177e4SLinus Torvalds 
244dccf4a48SAlan Stern 	list_del(&qh->node);
245dccf4a48SAlan Stern 	if (qh->udev) {
246dccf4a48SAlan Stern 		qh->hep->hcpriv = NULL;
247dccf4a48SAlan Stern 		usb_put_dev(qh->udev);
248*af0bb599SAlan Stern 		uhci_free_td(uhci, qh->dummy_td);
249dccf4a48SAlan Stern 	}
2501da177e4SLinus Torvalds 	dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
2511da177e4SLinus Torvalds }
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds /*
254dccf4a48SAlan Stern  * Put a QH on the schedule in both hardware and software
2551da177e4SLinus Torvalds  */
256dccf4a48SAlan Stern static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
2571da177e4SLinus Torvalds {
2581da177e4SLinus Torvalds 	struct uhci_qh *pqh;
2591da177e4SLinus Torvalds 
260dccf4a48SAlan Stern 	WARN_ON(list_empty(&qh->queue));
261dccf4a48SAlan Stern 
262dccf4a48SAlan Stern 	/* Set the element pointer if it isn't set already.
263dccf4a48SAlan Stern 	 * This isn't needed for Isochronous queues, but it doesn't hurt. */
264dccf4a48SAlan Stern 	if (qh_element(qh) == UHCI_PTR_TERM) {
265dccf4a48SAlan Stern 		struct urb_priv *urbp = list_entry(qh->queue.next,
266dccf4a48SAlan Stern 				struct urb_priv, node);
267dccf4a48SAlan Stern 		struct uhci_td *td = list_entry(urbp->td_list.next,
268dccf4a48SAlan Stern 				struct uhci_td, list);
269dccf4a48SAlan Stern 
270dccf4a48SAlan Stern 		qh->element = cpu_to_le32(td->dma_handle);
271dccf4a48SAlan Stern 	}
272dccf4a48SAlan Stern 
273dccf4a48SAlan Stern 	if (qh->state == QH_STATE_ACTIVE)
2741da177e4SLinus Torvalds 		return;
275dccf4a48SAlan Stern 	qh->state = QH_STATE_ACTIVE;
276dccf4a48SAlan Stern 
277dccf4a48SAlan Stern 	/* Move the QH from its old list to the end of the appropriate
278dccf4a48SAlan Stern 	 * skeleton's list */
279dccf4a48SAlan Stern 	list_move_tail(&qh->node, &qh->skel->node);
280dccf4a48SAlan Stern 
281dccf4a48SAlan Stern 	/* Link it into the schedule */
282dccf4a48SAlan Stern 	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
283dccf4a48SAlan Stern 	qh->link = pqh->link;
284dccf4a48SAlan Stern 	wmb();
285dccf4a48SAlan Stern 	pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
286dccf4a48SAlan Stern }
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds /*
289dccf4a48SAlan Stern  * Take a QH off the hardware schedule
2901da177e4SLinus Torvalds  */
291dccf4a48SAlan Stern static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
292dccf4a48SAlan Stern {
293dccf4a48SAlan Stern 	struct uhci_qh *pqh;
2941da177e4SLinus Torvalds 
295dccf4a48SAlan Stern 	if (qh->state == QH_STATE_UNLINKING)
296dccf4a48SAlan Stern 		return;
297dccf4a48SAlan Stern 	WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
298dccf4a48SAlan Stern 	qh->state = QH_STATE_UNLINKING;
2991da177e4SLinus Torvalds 
300dccf4a48SAlan Stern 	/* Unlink the QH from the schedule and record when we did it */
301dccf4a48SAlan Stern 	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
302dccf4a48SAlan Stern 	pqh->link = qh->link;
303dccf4a48SAlan Stern 	mb();
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds 	uhci_get_current_frame_number(uhci);
306dccf4a48SAlan Stern 	qh->unlink_frame = uhci->frame_number;
3071da177e4SLinus Torvalds 
308dccf4a48SAlan Stern 	/* Force an interrupt so we know when the QH is fully unlinked */
309dccf4a48SAlan Stern 	if (list_empty(&uhci->skel_unlink_qh->node))
3101da177e4SLinus Torvalds 		uhci_set_next_interrupt(uhci);
3111da177e4SLinus Torvalds 
312dccf4a48SAlan Stern 	/* Move the QH from its old list to the end of the unlinking list */
313dccf4a48SAlan Stern 	list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
3141da177e4SLinus Torvalds }
3151da177e4SLinus Torvalds 
3161da177e4SLinus Torvalds /*
317dccf4a48SAlan Stern  * When we and the controller are through with a QH, it becomes IDLE.
318dccf4a48SAlan Stern  * This happens when a QH has been off the schedule (on the unlinking
319dccf4a48SAlan Stern  * list) for more than one frame, or when an error occurs while adding
320dccf4a48SAlan Stern  * the first URB onto a new QH.
3211da177e4SLinus Torvalds  */
322dccf4a48SAlan Stern static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
323dccf4a48SAlan Stern {
324dccf4a48SAlan Stern 	WARN_ON(qh->state == QH_STATE_ACTIVE);
325dccf4a48SAlan Stern 
326dccf4a48SAlan Stern 	list_move(&qh->node, &uhci->idle_qh_list);
327dccf4a48SAlan Stern 	qh->state = QH_STATE_IDLE;
328dccf4a48SAlan Stern 
329dccf4a48SAlan Stern 	/* If anyone is waiting for a QH to become idle, wake them up */
330dccf4a48SAlan Stern 	if (uhci->num_waiting)
331dccf4a48SAlan Stern 		wake_up_all(&uhci->waitqh);
3321da177e4SLinus Torvalds }
3331da177e4SLinus Torvalds 
334dccf4a48SAlan Stern static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
335dccf4a48SAlan Stern 		struct urb *urb)
3361da177e4SLinus Torvalds {
3371da177e4SLinus Torvalds 	struct urb_priv *urbp;
3381da177e4SLinus Torvalds 
3391da177e4SLinus Torvalds 	urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC);
3401da177e4SLinus Torvalds 	if (!urbp)
3411da177e4SLinus Torvalds 		return NULL;
3421da177e4SLinus Torvalds 
3431da177e4SLinus Torvalds 	memset((void *)urbp, 0, sizeof(*urbp));
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds 	urbp->urb = urb;
3461da177e4SLinus Torvalds 	urb->hcpriv = urbp;
347dccf4a48SAlan Stern 	urbp->fsbrtime = jiffies;
348dccf4a48SAlan Stern 
349dccf4a48SAlan Stern 	INIT_LIST_HEAD(&urbp->node);
350dccf4a48SAlan Stern 	INIT_LIST_HEAD(&urbp->td_list);
351dccf4a48SAlan Stern 	INIT_LIST_HEAD(&urbp->urb_list);
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds 	return urbp;
3541da177e4SLinus Torvalds }
3551da177e4SLinus Torvalds 
3561da177e4SLinus Torvalds static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
3571da177e4SLinus Torvalds {
3581da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
3591da177e4SLinus Torvalds 
3601da177e4SLinus Torvalds 	list_add_tail(&td->list, &urbp->td_list);
3611da177e4SLinus Torvalds }
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds static void uhci_remove_td_from_urb(struct uhci_td *td)
3641da177e4SLinus Torvalds {
3651da177e4SLinus Torvalds 	if (list_empty(&td->list))
3661da177e4SLinus Torvalds 		return;
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds 	list_del_init(&td->list);
3691da177e4SLinus Torvalds }
3701da177e4SLinus Torvalds 
371dccf4a48SAlan Stern static void uhci_free_urb_priv(struct uhci_hcd *uhci,
372dccf4a48SAlan Stern 		struct urb_priv *urbp)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	struct uhci_td *td, *tmp;
3751da177e4SLinus Torvalds 
3761da177e4SLinus Torvalds 	if (!list_empty(&urbp->urb_list))
377dccf4a48SAlan Stern 		dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list!\n",
378dccf4a48SAlan Stern 				urbp->urb);
379dccf4a48SAlan Stern 	if (!list_empty(&urbp->node))
380dccf4a48SAlan Stern 		dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
381dccf4a48SAlan Stern 				urbp->urb);
3821da177e4SLinus Torvalds 
3831da177e4SLinus Torvalds 	uhci_get_current_frame_number(uhci);
3841da177e4SLinus Torvalds 	if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) {
3851da177e4SLinus Torvalds 		uhci_free_pending_tds(uhci);
3861da177e4SLinus Torvalds 		uhci->td_remove_age = uhci->frame_number;
3871da177e4SLinus Torvalds 	}
3881da177e4SLinus Torvalds 
3891da177e4SLinus Torvalds 	/* Check to see if the remove list is empty. Set the IOC bit */
390dccf4a48SAlan Stern 	/* to force an interrupt so we can remove the TDs. */
3911da177e4SLinus Torvalds 	if (list_empty(&uhci->td_remove_list))
3921da177e4SLinus Torvalds 		uhci_set_next_interrupt(uhci);
3931da177e4SLinus Torvalds 
3941da177e4SLinus Torvalds 	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
3951da177e4SLinus Torvalds 		uhci_remove_td_from_urb(td);
3961da177e4SLinus Torvalds 		list_add(&td->remove_list, &uhci->td_remove_list);
3971da177e4SLinus Torvalds 	}
3981da177e4SLinus Torvalds 
399dccf4a48SAlan Stern 	urbp->urb->hcpriv = NULL;
4001da177e4SLinus Torvalds 	kmem_cache_free(uhci_up_cachep, urbp);
4011da177e4SLinus Torvalds }
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb)
4041da177e4SLinus Torvalds {
4051da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds 	if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) {
4081da177e4SLinus Torvalds 		urbp->fsbr = 1;
4091da177e4SLinus Torvalds 		if (!uhci->fsbr++ && !uhci->fsbrtimeout)
4101da177e4SLinus Torvalds 			uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
4111da177e4SLinus Torvalds 	}
4121da177e4SLinus Torvalds }
4131da177e4SLinus Torvalds 
4141da177e4SLinus Torvalds static void uhci_dec_fsbr(struct uhci_hcd *uhci, struct urb *urb)
4151da177e4SLinus Torvalds {
4161da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds 	if ((!(urb->transfer_flags & URB_NO_FSBR)) && urbp->fsbr) {
4191da177e4SLinus Torvalds 		urbp->fsbr = 0;
4201da177e4SLinus Torvalds 		if (!--uhci->fsbr)
4211da177e4SLinus Torvalds 			uhci->fsbrtimeout = jiffies + FSBR_DELAY;
4221da177e4SLinus Torvalds 	}
4231da177e4SLinus Torvalds }
4241da177e4SLinus Torvalds 
4251da177e4SLinus Torvalds /*
4261da177e4SLinus Torvalds  * Map status to standard result codes
4271da177e4SLinus Torvalds  *
4281da177e4SLinus Torvalds  * <status> is (td_status(td) & 0xF60000), a.k.a.
4291da177e4SLinus Torvalds  * uhci_status_bits(td_status(td)).
4301da177e4SLinus Torvalds  * Note: <status> does not include the TD_CTRL_NAK bit.
4311da177e4SLinus Torvalds  * <dir_out> is True for output TDs and False for input TDs.
4321da177e4SLinus Torvalds  */
4331da177e4SLinus Torvalds static int uhci_map_status(int status, int dir_out)
4341da177e4SLinus Torvalds {
4351da177e4SLinus Torvalds 	if (!status)
4361da177e4SLinus Torvalds 		return 0;
4371da177e4SLinus Torvalds 	if (status & TD_CTRL_BITSTUFF)			/* Bitstuff error */
4381da177e4SLinus Torvalds 		return -EPROTO;
4391da177e4SLinus Torvalds 	if (status & TD_CTRL_CRCTIMEO) {		/* CRC/Timeout */
4401da177e4SLinus Torvalds 		if (dir_out)
4411da177e4SLinus Torvalds 			return -EPROTO;
4421da177e4SLinus Torvalds 		else
4431da177e4SLinus Torvalds 			return -EILSEQ;
4441da177e4SLinus Torvalds 	}
4451da177e4SLinus Torvalds 	if (status & TD_CTRL_BABBLE)			/* Babble */
4461da177e4SLinus Torvalds 		return -EOVERFLOW;
4471da177e4SLinus Torvalds 	if (status & TD_CTRL_DBUFERR)			/* Buffer error */
4481da177e4SLinus Torvalds 		return -ENOSR;
4491da177e4SLinus Torvalds 	if (status & TD_CTRL_STALLED)			/* Stalled */
4501da177e4SLinus Torvalds 		return -EPIPE;
4511da177e4SLinus Torvalds 	WARN_ON(status & TD_CTRL_ACTIVE);		/* Active */
4521da177e4SLinus Torvalds 	return 0;
4531da177e4SLinus Torvalds }
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds /*
456dccf4a48SAlan Stern  * Fix up the data toggles for URBs in a queue, when one of them
457dccf4a48SAlan Stern  * terminates early (short transfer, error, or dequeued).
458dccf4a48SAlan Stern  */
459dccf4a48SAlan Stern static void uhci_fixup_toggles(struct urb *urb)
460dccf4a48SAlan Stern {
461dccf4a48SAlan Stern 	struct list_head *head;
462dccf4a48SAlan Stern 	struct uhci_td *td;
463dccf4a48SAlan Stern 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
464dccf4a48SAlan Stern 	int prevactive = 0;
465dccf4a48SAlan Stern 	unsigned int toggle = 0;
466dccf4a48SAlan Stern 	struct urb_priv *turbp, *list_end;
467dccf4a48SAlan Stern 
468dccf4a48SAlan Stern 	/*
469dccf4a48SAlan Stern 	 * We need to find out what the last successful toggle was so
470dccf4a48SAlan Stern 	 * we can update the data toggles for the following transfers.
471dccf4a48SAlan Stern 	 *
472dccf4a48SAlan Stern 	 * There are 2 ways the last successful completed TD is found:
473dccf4a48SAlan Stern 	 *
474dccf4a48SAlan Stern 	 * 1) The TD is NOT active and the actual length < expected length
475dccf4a48SAlan Stern 	 * 2) The TD is NOT active and it's the last TD in the chain
476dccf4a48SAlan Stern 	 *
477dccf4a48SAlan Stern 	 * and a third way the first uncompleted TD is found:
478dccf4a48SAlan Stern 	 *
479dccf4a48SAlan Stern 	 * 3) The TD is active and the previous TD is NOT active
480dccf4a48SAlan Stern 	 */
481dccf4a48SAlan Stern 	head = &urbp->td_list;
482dccf4a48SAlan Stern 	list_for_each_entry(td, head, list) {
483dccf4a48SAlan Stern 		unsigned int ctrlstat = td_status(td);
484dccf4a48SAlan Stern 
485dccf4a48SAlan Stern 		if (!(ctrlstat & TD_CTRL_ACTIVE) &&
486dccf4a48SAlan Stern 				(uhci_actual_length(ctrlstat) <
487dccf4a48SAlan Stern 				 uhci_expected_length(td_token(td)) ||
488dccf4a48SAlan Stern 				td->list.next == head))
489dccf4a48SAlan Stern 			toggle = uhci_toggle(td_token(td)) ^ 1;
490dccf4a48SAlan Stern 		else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
491dccf4a48SAlan Stern 			toggle = uhci_toggle(td_token(td));
492dccf4a48SAlan Stern 
493dccf4a48SAlan Stern 		prevactive = ctrlstat & TD_CTRL_ACTIVE;
494dccf4a48SAlan Stern 	}
495dccf4a48SAlan Stern 
496dccf4a48SAlan Stern 	/*
497dccf4a48SAlan Stern 	 * Fix up the toggle for the following URBs in the queue.
498dccf4a48SAlan Stern 	 *
499dccf4a48SAlan Stern 	 * We can stop as soon as we find an URB with toggles set correctly,
500dccf4a48SAlan Stern 	 * because then all the following URBs will be correct also.
501dccf4a48SAlan Stern 	 */
502dccf4a48SAlan Stern 	list_end = list_entry(&urbp->qh->queue, struct urb_priv, node);
503dccf4a48SAlan Stern 	turbp = urbp;
504dccf4a48SAlan Stern 	while ((turbp = list_entry(turbp->node.next, struct urb_priv, node))
505dccf4a48SAlan Stern 			!= list_end) {
506dccf4a48SAlan Stern 		td = list_entry(turbp->td_list.next, struct uhci_td, list);
507dccf4a48SAlan Stern 		if (uhci_toggle(td_token(td)) == toggle)
508dccf4a48SAlan Stern 			return;
509dccf4a48SAlan Stern 
510dccf4a48SAlan Stern 		list_for_each_entry(td, &turbp->td_list, list) {
511dccf4a48SAlan Stern 			td->token ^= __constant_cpu_to_le32(TD_TOKEN_TOGGLE);
512dccf4a48SAlan Stern 			toggle ^= 1;
513dccf4a48SAlan Stern 		}
514dccf4a48SAlan Stern 	}
515dccf4a48SAlan Stern 
516dccf4a48SAlan Stern 	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
517dccf4a48SAlan Stern 			usb_pipeout(urb->pipe), toggle);
518dccf4a48SAlan Stern }
519dccf4a48SAlan Stern 
520dccf4a48SAlan Stern /*
5211da177e4SLinus Torvalds  * Control transfers
5221da177e4SLinus Torvalds  */
523dccf4a48SAlan Stern static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
524dccf4a48SAlan Stern 		struct uhci_qh *qh)
5251da177e4SLinus Torvalds {
5261da177e4SLinus Torvalds 	struct uhci_td *td;
5271da177e4SLinus Torvalds 	unsigned long destination, status;
528dccf4a48SAlan Stern 	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
5291da177e4SLinus Torvalds 	int len = urb->transfer_buffer_length;
5301da177e4SLinus Torvalds 	dma_addr_t data = urb->transfer_dma;
531dccf4a48SAlan Stern 	__le32 *plink;
5321da177e4SLinus Torvalds 
5331da177e4SLinus Torvalds 	/* The "pipe" thing contains the destination in bits 8--18 */
5341da177e4SLinus Torvalds 	destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
5351da177e4SLinus Torvalds 
536*af0bb599SAlan Stern 	/* 3 errors, dummy TD remains inactive */
537*af0bb599SAlan Stern 	status = uhci_maxerr(3);
5381da177e4SLinus Torvalds 	if (urb->dev->speed == USB_SPEED_LOW)
5391da177e4SLinus Torvalds 		status |= TD_CTRL_LS;
5401da177e4SLinus Torvalds 
5411da177e4SLinus Torvalds 	/*
5421da177e4SLinus Torvalds 	 * Build the TD for the control request setup packet
5431da177e4SLinus Torvalds 	 */
544*af0bb599SAlan Stern 	td = qh->dummy_td;
5451da177e4SLinus Torvalds 	uhci_add_td_to_urb(urb, td);
546fa346568SAlan Stern 	uhci_fill_td(td, status, destination | uhci_explen(8),
5471da177e4SLinus Torvalds 			urb->setup_dma);
548dccf4a48SAlan Stern 	plink = &td->link;
549*af0bb599SAlan Stern 	status |= TD_CTRL_ACTIVE;
5501da177e4SLinus Torvalds 
5511da177e4SLinus Torvalds 	/*
5521da177e4SLinus Torvalds 	 * If direction is "send", change the packet ID from SETUP (0x2D)
5531da177e4SLinus Torvalds 	 * to OUT (0xE1).  Else change it from SETUP to IN (0x69) and
5541da177e4SLinus Torvalds 	 * set Short Packet Detect (SPD) for all data packets.
5551da177e4SLinus Torvalds 	 */
5561da177e4SLinus Torvalds 	if (usb_pipeout(urb->pipe))
5571da177e4SLinus Torvalds 		destination ^= (USB_PID_SETUP ^ USB_PID_OUT);
5581da177e4SLinus Torvalds 	else {
5591da177e4SLinus Torvalds 		destination ^= (USB_PID_SETUP ^ USB_PID_IN);
5601da177e4SLinus Torvalds 		status |= TD_CTRL_SPD;
5611da177e4SLinus Torvalds 	}
5621da177e4SLinus Torvalds 
5631da177e4SLinus Torvalds 	/*
564687f5f34SAlan Stern 	 * Build the DATA TDs
5651da177e4SLinus Torvalds 	 */
5661da177e4SLinus Torvalds 	while (len > 0) {
567dccf4a48SAlan Stern 		int pktsze = min(len, maxsze);
5681da177e4SLinus Torvalds 
5692532178aSAlan Stern 		td = uhci_alloc_td(uhci);
5701da177e4SLinus Torvalds 		if (!td)
571*af0bb599SAlan Stern 			goto nomem;
572dccf4a48SAlan Stern 		*plink = cpu_to_le32(td->dma_handle);
5731da177e4SLinus Torvalds 
5741da177e4SLinus Torvalds 		/* Alternate Data0/1 (start with Data1) */
5751da177e4SLinus Torvalds 		destination ^= TD_TOKEN_TOGGLE;
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds 		uhci_add_td_to_urb(urb, td);
578fa346568SAlan Stern 		uhci_fill_td(td, status, destination | uhci_explen(pktsze),
5791da177e4SLinus Torvalds 				data);
580dccf4a48SAlan Stern 		plink = &td->link;
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds 		data += pktsze;
5831da177e4SLinus Torvalds 		len -= pktsze;
5841da177e4SLinus Torvalds 	}
5851da177e4SLinus Torvalds 
5861da177e4SLinus Torvalds 	/*
5871da177e4SLinus Torvalds 	 * Build the final TD for control status
5881da177e4SLinus Torvalds 	 */
5892532178aSAlan Stern 	td = uhci_alloc_td(uhci);
5901da177e4SLinus Torvalds 	if (!td)
591*af0bb599SAlan Stern 		goto nomem;
592dccf4a48SAlan Stern 	*plink = cpu_to_le32(td->dma_handle);
5931da177e4SLinus Torvalds 
5941da177e4SLinus Torvalds 	/*
5951da177e4SLinus Torvalds 	 * It's IN if the pipe is an output pipe or we're not expecting
5961da177e4SLinus Torvalds 	 * data back.
5971da177e4SLinus Torvalds 	 */
5981da177e4SLinus Torvalds 	destination &= ~TD_TOKEN_PID_MASK;
5991da177e4SLinus Torvalds 	if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length)
6001da177e4SLinus Torvalds 		destination |= USB_PID_IN;
6011da177e4SLinus Torvalds 	else
6021da177e4SLinus Torvalds 		destination |= USB_PID_OUT;
6031da177e4SLinus Torvalds 
6041da177e4SLinus Torvalds 	destination |= TD_TOKEN_TOGGLE;		/* End in Data1 */
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds 	status &= ~TD_CTRL_SPD;
6071da177e4SLinus Torvalds 
6081da177e4SLinus Torvalds 	uhci_add_td_to_urb(urb, td);
6091da177e4SLinus Torvalds 	uhci_fill_td(td, status | TD_CTRL_IOC,
610fa346568SAlan Stern 			destination | uhci_explen(0), 0);
611*af0bb599SAlan Stern 	plink = &td->link;
612*af0bb599SAlan Stern 
613*af0bb599SAlan Stern 	/*
614*af0bb599SAlan Stern 	 * Build the new dummy TD and activate the old one
615*af0bb599SAlan Stern 	 */
616*af0bb599SAlan Stern 	td = uhci_alloc_td(uhci);
617*af0bb599SAlan Stern 	if (!td)
618*af0bb599SAlan Stern 		goto nomem;
619*af0bb599SAlan Stern 	*plink = cpu_to_le32(td->dma_handle);
620*af0bb599SAlan Stern 
621*af0bb599SAlan Stern 	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
622*af0bb599SAlan Stern 	wmb();
623*af0bb599SAlan Stern 	qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
624*af0bb599SAlan Stern 	qh->dummy_td = td;
6251da177e4SLinus Torvalds 
6261da177e4SLinus Torvalds 	/* Low-speed transfers get a different queue, and won't hog the bus.
6271da177e4SLinus Torvalds 	 * Also, some devices enumerate better without FSBR; the easiest way
6281da177e4SLinus Torvalds 	 * to do that is to put URBs on the low-speed queue while the device
629630aa3cfSAlan Stern 	 * isn't in the CONFIGURED state. */
6301da177e4SLinus Torvalds 	if (urb->dev->speed == USB_SPEED_LOW ||
631630aa3cfSAlan Stern 			urb->dev->state != USB_STATE_CONFIGURED)
632dccf4a48SAlan Stern 		qh->skel = uhci->skel_ls_control_qh;
6331da177e4SLinus Torvalds 	else {
634dccf4a48SAlan Stern 		qh->skel = uhci->skel_fs_control_qh;
6351da177e4SLinus Torvalds 		uhci_inc_fsbr(uhci, urb);
6361da177e4SLinus Torvalds 	}
637dccf4a48SAlan Stern 	return 0;
638*af0bb599SAlan Stern 
639*af0bb599SAlan Stern nomem:
640*af0bb599SAlan Stern 	/* Remove the dummy TD from the td_list so it doesn't get freed */
641*af0bb599SAlan Stern 	uhci_remove_td_from_urb(qh->dummy_td);
642*af0bb599SAlan Stern 	return -ENOMEM;
6431da177e4SLinus Torvalds }
6441da177e4SLinus Torvalds 
6451da177e4SLinus Torvalds /*
6461da177e4SLinus Torvalds  * If control-IN transfer was short, the status packet wasn't sent.
6471da177e4SLinus Torvalds  * This routine changes the element pointer in the QH to point at the
6481da177e4SLinus Torvalds  * status TD.  It's safe to do this even while the QH is live, because
6491da177e4SLinus Torvalds  * the hardware only updates the element pointer following a successful
6501da177e4SLinus Torvalds  * transfer.  The inactive TD for the short packet won't cause an update,
6511da177e4SLinus Torvalds  * so the pointer won't get overwritten.  The next time the controller
6521da177e4SLinus Torvalds  * sees this QH, it will send the status packet.
6531da177e4SLinus Torvalds  */
6541da177e4SLinus Torvalds static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb)
6551da177e4SLinus Torvalds {
6561da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
6571da177e4SLinus Torvalds 	struct uhci_td *td;
6581da177e4SLinus Torvalds 
659dccf4a48SAlan Stern 	urbp->short_transfer = 1;
6601da177e4SLinus Torvalds 
6611da177e4SLinus Torvalds 	td = list_entry(urbp->td_list.prev, struct uhci_td, list);
6621da177e4SLinus Torvalds 	urbp->qh->element = cpu_to_le32(td->dma_handle);
6631da177e4SLinus Torvalds 
6641da177e4SLinus Torvalds 	return -EINPROGRESS;
6651da177e4SLinus Torvalds }
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 
6681da177e4SLinus Torvalds static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb)
6691da177e4SLinus Torvalds {
6701da177e4SLinus Torvalds 	struct list_head *tmp, *head;
6711da177e4SLinus Torvalds 	struct urb_priv *urbp = urb->hcpriv;
6721da177e4SLinus Torvalds 	struct uhci_td *td;
6731da177e4SLinus Torvalds 	unsigned int status;
6741da177e4SLinus Torvalds 	int ret = 0;
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds 	head = &urbp->td_list;
677dccf4a48SAlan Stern 	if (urbp->short_transfer) {
6781da177e4SLinus Torvalds 		tmp = head->prev;
6791da177e4SLinus Torvalds 		goto status_stage;
6801da177e4SLinus Torvalds 	}
6811da177e4SLinus Torvalds 
682dccf4a48SAlan Stern 	urb->actual_length = 0;
683dccf4a48SAlan Stern 
6841da177e4SLinus Torvalds 	tmp = head->next;
6851da177e4SLinus Torvalds 	td = list_entry(tmp, struct uhci_td, list);
6861da177e4SLinus Torvalds 
6871da177e4SLinus Torvalds 	/* The first TD is the SETUP stage, check the status, but skip */
6881da177e4SLinus Torvalds 	/*  the count */
6891da177e4SLinus Torvalds 	status = uhci_status_bits(td_status(td));
6901da177e4SLinus Torvalds 	if (status & TD_CTRL_ACTIVE)
6911da177e4SLinus Torvalds 		return -EINPROGRESS;
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds 	if (status)
6941da177e4SLinus Torvalds 		goto td_error;
6951da177e4SLinus Torvalds 
696687f5f34SAlan Stern 	/* The rest of the TDs (but the last) are data */
6971da177e4SLinus Torvalds 	tmp = tmp->next;
6981da177e4SLinus Torvalds 	while (tmp != head && tmp->next != head) {
6991da177e4SLinus Torvalds 		unsigned int ctrlstat;
7001da177e4SLinus Torvalds 
7011da177e4SLinus Torvalds 		td = list_entry(tmp, struct uhci_td, list);
7021da177e4SLinus Torvalds 		tmp = tmp->next;
7031da177e4SLinus Torvalds 
7041da177e4SLinus Torvalds 		ctrlstat = td_status(td);
7051da177e4SLinus Torvalds 		status = uhci_status_bits(ctrlstat);
7061da177e4SLinus Torvalds 		if (status & TD_CTRL_ACTIVE)
7071da177e4SLinus Torvalds 			return -EINPROGRESS;
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 		urb->actual_length += uhci_actual_length(ctrlstat);
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds 		if (status)
7121da177e4SLinus Torvalds 			goto td_error;
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds 		/* Check to see if we received a short packet */
7151da177e4SLinus Torvalds 		if (uhci_actual_length(ctrlstat) <
7161da177e4SLinus Torvalds 				uhci_expected_length(td_token(td))) {
7171da177e4SLinus Torvalds 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
7181da177e4SLinus Torvalds 				ret = -EREMOTEIO;
7191da177e4SLinus Torvalds 				goto err;
7201da177e4SLinus Torvalds 			}
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 			return usb_control_retrigger_status(uhci, urb);
7231da177e4SLinus Torvalds 		}
7241da177e4SLinus Torvalds 	}
7251da177e4SLinus Torvalds 
7261da177e4SLinus Torvalds status_stage:
7271da177e4SLinus Torvalds 	td = list_entry(tmp, struct uhci_td, list);
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds 	/* Control status stage */
7301da177e4SLinus Torvalds 	status = td_status(td);
7311da177e4SLinus Torvalds 
7321da177e4SLinus Torvalds #ifdef I_HAVE_BUGGY_APC_BACKUPS
7331da177e4SLinus Torvalds 	/* APC BackUPS Pro kludge */
7341da177e4SLinus Torvalds 	/* It tries to send all of the descriptor instead of the amount */
7351da177e4SLinus Torvalds 	/*  we requested */
7361da177e4SLinus Torvalds 	if (status & TD_CTRL_IOC &&	/* IOC is masked out by uhci_status_bits */
7371da177e4SLinus Torvalds 	    status & TD_CTRL_ACTIVE &&
7381da177e4SLinus Torvalds 	    status & TD_CTRL_NAK)
7391da177e4SLinus Torvalds 		return 0;
7401da177e4SLinus Torvalds #endif
7411da177e4SLinus Torvalds 
7421da177e4SLinus Torvalds 	status = uhci_status_bits(status);
7431da177e4SLinus Torvalds 	if (status & TD_CTRL_ACTIVE)
7441da177e4SLinus Torvalds 		return -EINPROGRESS;
7451da177e4SLinus Torvalds 
7461da177e4SLinus Torvalds 	if (status)
7471da177e4SLinus Torvalds 		goto td_error;
7481da177e4SLinus Torvalds 
7491da177e4SLinus Torvalds 	return 0;
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds td_error:
7521da177e4SLinus Torvalds 	ret = uhci_map_status(status, uhci_packetout(td_token(td)));
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds err:
7551da177e4SLinus Torvalds 	if ((debug == 1 && ret != -EPIPE) || debug > 1) {
7561da177e4SLinus Torvalds 		/* Some debugging code */
7571da177e4SLinus Torvalds 		dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
7581da177e4SLinus Torvalds 				__FUNCTION__, status);
7591da177e4SLinus Torvalds 
7601da177e4SLinus Torvalds 		if (errbuf) {
7611da177e4SLinus Torvalds 			/* Print the chain for debugging purposes */
7621da177e4SLinus Torvalds 			uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 			lprintk(errbuf);
7651da177e4SLinus Torvalds 		}
7661da177e4SLinus Torvalds 	}
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	return ret;
7691da177e4SLinus Torvalds }
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds /*
7721da177e4SLinus Torvalds  * Common submit for bulk and interrupt
7731da177e4SLinus Torvalds  */
774dccf4a48SAlan Stern static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
775dccf4a48SAlan Stern 		struct uhci_qh *qh)
7761da177e4SLinus Torvalds {
7771da177e4SLinus Torvalds 	struct uhci_td *td;
7781da177e4SLinus Torvalds 	unsigned long destination, status;
779dccf4a48SAlan Stern 	int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
7801da177e4SLinus Torvalds 	int len = urb->transfer_buffer_length;
7811da177e4SLinus Torvalds 	dma_addr_t data = urb->transfer_dma;
782*af0bb599SAlan Stern 	__le32 *plink;
783*af0bb599SAlan Stern 	unsigned int toggle;
7841da177e4SLinus Torvalds 
7851da177e4SLinus Torvalds 	if (len < 0)
7861da177e4SLinus Torvalds 		return -EINVAL;
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 	/* The "pipe" thing contains the destination in bits 8--18 */
7891da177e4SLinus Torvalds 	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
790*af0bb599SAlan Stern 	toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
791*af0bb599SAlan Stern 			 usb_pipeout(urb->pipe));
7921da177e4SLinus Torvalds 
793*af0bb599SAlan Stern 	/* 3 errors, dummy TD remains inactive */
794*af0bb599SAlan Stern 	status = uhci_maxerr(3);
7951da177e4SLinus Torvalds 	if (urb->dev->speed == USB_SPEED_LOW)
7961da177e4SLinus Torvalds 		status |= TD_CTRL_LS;
7971da177e4SLinus Torvalds 	if (usb_pipein(urb->pipe))
7981da177e4SLinus Torvalds 		status |= TD_CTRL_SPD;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	/*
801687f5f34SAlan Stern 	 * Build the DATA TDs
8021da177e4SLinus Torvalds 	 */
803*af0bb599SAlan Stern 	plink = NULL;
804*af0bb599SAlan Stern 	td = qh->dummy_td;
8051da177e4SLinus Torvalds 	do {	/* Allow zero length packets */
8061da177e4SLinus Torvalds 		int pktsze = maxsze;
8071da177e4SLinus Torvalds 
808dccf4a48SAlan Stern 		if (len <= pktsze) {		/* The last packet */
8091da177e4SLinus Torvalds 			pktsze = len;
8101da177e4SLinus Torvalds 			if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
8111da177e4SLinus Torvalds 				status &= ~TD_CTRL_SPD;
8121da177e4SLinus Torvalds 		}
8131da177e4SLinus Torvalds 
814*af0bb599SAlan Stern 		if (plink) {
8152532178aSAlan Stern 			td = uhci_alloc_td(uhci);
8161da177e4SLinus Torvalds 			if (!td)
817*af0bb599SAlan Stern 				goto nomem;
818dccf4a48SAlan Stern 			*plink = cpu_to_le32(td->dma_handle);
819*af0bb599SAlan Stern 		}
8201da177e4SLinus Torvalds 		uhci_add_td_to_urb(urb, td);
821dccf4a48SAlan Stern 		uhci_fill_td(td, status,
822dccf4a48SAlan Stern 				destination | uhci_explen(pktsze) |
823*af0bb599SAlan Stern 					(toggle << TD_TOKEN_TOGGLE_SHIFT),
8241da177e4SLinus Torvalds 				data);
825dccf4a48SAlan Stern 		plink = &td->link;
826*af0bb599SAlan Stern 		status |= TD_CTRL_ACTIVE;
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds 		data += pktsze;
8291da177e4SLinus Torvalds 		len -= maxsze;
830*af0bb599SAlan Stern 		toggle ^= 1;
8311da177e4SLinus Torvalds 	} while (len > 0);
8321da177e4SLinus Torvalds 
8331da177e4SLinus Torvalds 	/*
8341da177e4SLinus Torvalds 	 * URB_ZERO_PACKET means adding a 0-length packet, if direction
8351da177e4SLinus Torvalds 	 * is OUT and the transfer_length was an exact multiple of maxsze,
8361da177e4SLinus Torvalds 	 * hence (len = transfer_length - N * maxsze) == 0
8371da177e4SLinus Torvalds 	 * however, if transfer_length == 0, the zero packet was already
8381da177e4SLinus Torvalds 	 * prepared above.
8391da177e4SLinus Torvalds 	 */
840dccf4a48SAlan Stern 	if ((urb->transfer_flags & URB_ZERO_PACKET) &&
841dccf4a48SAlan Stern 			usb_pipeout(urb->pipe) && len == 0 &&
842dccf4a48SAlan Stern 			urb->transfer_buffer_length > 0) {
8432532178aSAlan Stern 		td = uhci_alloc_td(uhci);
8441da177e4SLinus Torvalds 		if (!td)
845*af0bb599SAlan Stern 			goto nomem;
846dccf4a48SAlan Stern 		*plink = cpu_to_le32(td->dma_handle);
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 		uhci_add_td_to_urb(urb, td);
849*af0bb599SAlan Stern 		uhci_fill_td(td, status,
850*af0bb599SAlan Stern 				destination | uhci_explen(0) |
851*af0bb599SAlan Stern 					(toggle << TD_TOKEN_TOGGLE_SHIFT),
8521da177e4SLinus Torvalds 				data);
853*af0bb599SAlan Stern 		plink = &td->link;
8541da177e4SLinus Torvalds 
855*af0bb599SAlan Stern 		toggle ^= 1;
8561da177e4SLinus Torvalds 	}
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	/* Set the interrupt-on-completion flag on the last packet.
8591da177e4SLinus Torvalds 	 * A more-or-less typical 4 KB URB (= size of one memory page)
8601da177e4SLinus Torvalds 	 * will require about 3 ms to transfer; that's a little on the
8611da177e4SLinus Torvalds 	 * fast side but not enough to justify delaying an interrupt
8621da177e4SLinus Torvalds 	 * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
8631da177e4SLinus Torvalds 	 * flag setting. */
864dccf4a48SAlan Stern 	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
8651da177e4SLinus Torvalds 
866*af0bb599SAlan Stern 	/*
867*af0bb599SAlan Stern 	 * Build the new dummy TD and activate the old one
868*af0bb599SAlan Stern 	 */
869*af0bb599SAlan Stern 	td = uhci_alloc_td(uhci);
870*af0bb599SAlan Stern 	if (!td)
871*af0bb599SAlan Stern 		goto nomem;
872*af0bb599SAlan Stern 	*plink = cpu_to_le32(td->dma_handle);
873*af0bb599SAlan Stern 
874*af0bb599SAlan Stern 	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
875*af0bb599SAlan Stern 	wmb();
876*af0bb599SAlan Stern 	qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
877*af0bb599SAlan Stern 	qh->dummy_td = td;
878*af0bb599SAlan Stern 
879*af0bb599SAlan Stern 	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
880*af0bb599SAlan Stern 			usb_pipeout(urb->pipe), toggle);
881dccf4a48SAlan Stern 	return 0;
882*af0bb599SAlan Stern 
883*af0bb599SAlan Stern nomem:
884*af0bb599SAlan Stern 	/* Remove the dummy TD from the td_list so it doesn't get freed */
885*af0bb599SAlan Stern 	uhci_remove_td_from_urb(qh->dummy_td);
886*af0bb599SAlan Stern 	return -ENOMEM;
8871da177e4SLinus Torvalds }
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds /*
8901da177e4SLinus Torvalds  * Common result for bulk and interrupt
8911da177e4SLinus Torvalds  */
8921da177e4SLinus Torvalds static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
8931da177e4SLinus Torvalds {
8941da177e4SLinus Torvalds 	struct urb_priv *urbp = urb->hcpriv;
8951da177e4SLinus Torvalds 	struct uhci_td *td;
8961da177e4SLinus Torvalds 	unsigned int status = 0;
8971da177e4SLinus Torvalds 	int ret = 0;
8981da177e4SLinus Torvalds 
8991da177e4SLinus Torvalds 	urb->actual_length = 0;
9001da177e4SLinus Torvalds 
9011da177e4SLinus Torvalds 	list_for_each_entry(td, &urbp->td_list, list) {
9021da177e4SLinus Torvalds 		unsigned int ctrlstat = td_status(td);
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 		status = uhci_status_bits(ctrlstat);
9051da177e4SLinus Torvalds 		if (status & TD_CTRL_ACTIVE)
9061da177e4SLinus Torvalds 			return -EINPROGRESS;
9071da177e4SLinus Torvalds 
9081da177e4SLinus Torvalds 		urb->actual_length += uhci_actual_length(ctrlstat);
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 		if (status)
9111da177e4SLinus Torvalds 			goto td_error;
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds 		if (uhci_actual_length(ctrlstat) <
9141da177e4SLinus Torvalds 				uhci_expected_length(td_token(td))) {
9151da177e4SLinus Torvalds 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
9161da177e4SLinus Torvalds 				ret = -EREMOTEIO;
9171da177e4SLinus Torvalds 				goto err;
918dccf4a48SAlan Stern 			}
919dccf4a48SAlan Stern 
920dccf4a48SAlan Stern 			/*
921dccf4a48SAlan Stern 			 * This URB stopped short of its end.  We have to
922dccf4a48SAlan Stern 			 * fix up the toggles of the following URBs on the
923dccf4a48SAlan Stern 			 * queue and restart the queue.
924dccf4a48SAlan Stern 			 *
925dccf4a48SAlan Stern 			 * Do this only the first time we encounter the
926dccf4a48SAlan Stern 			 * short URB.
927dccf4a48SAlan Stern 			 */
928dccf4a48SAlan Stern 			if (!urbp->short_transfer) {
929dccf4a48SAlan Stern 				urbp->short_transfer = 1;
930dccf4a48SAlan Stern 				uhci_fixup_toggles(urb);
931dccf4a48SAlan Stern 				td = list_entry(urbp->td_list.prev,
932dccf4a48SAlan Stern 						struct uhci_td, list);
933dccf4a48SAlan Stern 				urbp->qh->element = td->link;
934dccf4a48SAlan Stern 			}
935dccf4a48SAlan Stern 			break;
9361da177e4SLinus Torvalds 		}
9371da177e4SLinus Torvalds 	}
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds 	return 0;
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds td_error:
9421da177e4SLinus Torvalds 	ret = uhci_map_status(status, uhci_packetout(td_token(td)));
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds err:
9451da177e4SLinus Torvalds 	/*
9461da177e4SLinus Torvalds 	 * Enable this chunk of code if you want to see some more debugging.
9471da177e4SLinus Torvalds 	 * But be careful, it has the tendancy to starve out khubd and prevent
9481da177e4SLinus Torvalds 	 * disconnects from happening successfully if you have a slow debug
9491da177e4SLinus Torvalds 	 * log interface (like a serial console.
9501da177e4SLinus Torvalds 	 */
9511da177e4SLinus Torvalds #if 0
9521da177e4SLinus Torvalds 	if ((debug == 1 && ret != -EPIPE) || debug > 1) {
9531da177e4SLinus Torvalds 		/* Some debugging code */
9541da177e4SLinus Torvalds 		dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
9551da177e4SLinus Torvalds 				__FUNCTION__, status);
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 		if (errbuf) {
9581da177e4SLinus Torvalds 			/* Print the chain for debugging purposes */
9591da177e4SLinus Torvalds 			uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
9601da177e4SLinus Torvalds 
9611da177e4SLinus Torvalds 			lprintk(errbuf);
9621da177e4SLinus Torvalds 		}
9631da177e4SLinus Torvalds 	}
9641da177e4SLinus Torvalds #endif
9651da177e4SLinus Torvalds 	return ret;
9661da177e4SLinus Torvalds }
9671da177e4SLinus Torvalds 
968dccf4a48SAlan Stern static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
969dccf4a48SAlan Stern 		struct uhci_qh *qh)
9701da177e4SLinus Torvalds {
9711da177e4SLinus Torvalds 	int ret;
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds 	/* Can't have low-speed bulk transfers */
9741da177e4SLinus Torvalds 	if (urb->dev->speed == USB_SPEED_LOW)
9751da177e4SLinus Torvalds 		return -EINVAL;
9761da177e4SLinus Torvalds 
977dccf4a48SAlan Stern 	qh->skel = uhci->skel_bulk_qh;
978dccf4a48SAlan Stern 	ret = uhci_submit_common(uhci, urb, qh);
979dccf4a48SAlan Stern 	if (ret == 0)
9801da177e4SLinus Torvalds 		uhci_inc_fsbr(uhci, urb);
9811da177e4SLinus Torvalds 	return ret;
9821da177e4SLinus Torvalds }
9831da177e4SLinus Torvalds 
984dccf4a48SAlan Stern static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
985dccf4a48SAlan Stern 		struct uhci_qh *qh)
9861da177e4SLinus Torvalds {
987dccf4a48SAlan Stern 	/* USB 1.1 interrupt transfers only involve one packet per interval.
988dccf4a48SAlan Stern 	 * Drivers can submit URBs of any length, but longer ones will need
989dccf4a48SAlan Stern 	 * multiple intervals to complete.
9901da177e4SLinus Torvalds 	 */
991dccf4a48SAlan Stern 	qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)];
992dccf4a48SAlan Stern 	return uhci_submit_common(uhci, urb, qh);
9931da177e4SLinus Torvalds }
9941da177e4SLinus Torvalds 
9951da177e4SLinus Torvalds /*
9961da177e4SLinus Torvalds  * Isochronous transfers
9971da177e4SLinus Torvalds  */
9981da177e4SLinus Torvalds static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsigned int *start, unsigned int *end)
9991da177e4SLinus Torvalds {
10001da177e4SLinus Torvalds 	struct urb *last_urb = NULL;
10011da177e4SLinus Torvalds 	struct urb_priv *up;
10021da177e4SLinus Torvalds 	int ret = 0;
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds 	list_for_each_entry(up, &uhci->urb_list, urb_list) {
10051da177e4SLinus Torvalds 		struct urb *u = up->urb;
10061da177e4SLinus Torvalds 
1007687f5f34SAlan Stern 		/* look for pending URBs with identical pipe handle */
10081da177e4SLinus Torvalds 		if ((urb->pipe == u->pipe) && (urb->dev == u->dev) &&
10091da177e4SLinus Torvalds 		    (u->status == -EINPROGRESS) && (u != urb)) {
10101da177e4SLinus Torvalds 			if (!last_urb)
10111da177e4SLinus Torvalds 				*start = u->start_frame;
10121da177e4SLinus Torvalds 			last_urb = u;
10131da177e4SLinus Torvalds 		}
10141da177e4SLinus Torvalds 	}
10151da177e4SLinus Torvalds 
10161da177e4SLinus Torvalds 	if (last_urb) {
10171da177e4SLinus Torvalds 		*end = (last_urb->start_frame + last_urb->number_of_packets *
10181da177e4SLinus Torvalds 				last_urb->interval) & (UHCI_NUMFRAMES-1);
10191da177e4SLinus Torvalds 		ret = 0;
10201da177e4SLinus Torvalds 	} else
10211da177e4SLinus Torvalds 		ret = -1;	/* no previous urb found */
10221da177e4SLinus Torvalds 
10231da177e4SLinus Torvalds 	return ret;
10241da177e4SLinus Torvalds }
10251da177e4SLinus Torvalds 
10261da177e4SLinus Torvalds static int isochronous_find_start(struct uhci_hcd *uhci, struct urb *urb)
10271da177e4SLinus Torvalds {
10281da177e4SLinus Torvalds 	int limits;
10291da177e4SLinus Torvalds 	unsigned int start = 0, end = 0;
10301da177e4SLinus Torvalds 
10311da177e4SLinus Torvalds 	if (urb->number_of_packets > 900)	/* 900? Why? */
10321da177e4SLinus Torvalds 		return -EFBIG;
10331da177e4SLinus Torvalds 
10341da177e4SLinus Torvalds 	limits = isochronous_find_limits(uhci, urb, &start, &end);
10351da177e4SLinus Torvalds 
10361da177e4SLinus Torvalds 	if (urb->transfer_flags & URB_ISO_ASAP) {
10371da177e4SLinus Torvalds 		if (limits) {
10381da177e4SLinus Torvalds 			uhci_get_current_frame_number(uhci);
10391da177e4SLinus Torvalds 			urb->start_frame = (uhci->frame_number + 10)
10401da177e4SLinus Torvalds 					& (UHCI_NUMFRAMES - 1);
10411da177e4SLinus Torvalds 		} else
10421da177e4SLinus Torvalds 			urb->start_frame = end;
10431da177e4SLinus Torvalds 	} else {
10441da177e4SLinus Torvalds 		urb->start_frame &= (UHCI_NUMFRAMES - 1);
10451da177e4SLinus Torvalds 		/* FIXME: Sanity check */
10461da177e4SLinus Torvalds 	}
10471da177e4SLinus Torvalds 
10481da177e4SLinus Torvalds 	return 0;
10491da177e4SLinus Torvalds }
10501da177e4SLinus Torvalds 
10511da177e4SLinus Torvalds /*
10521da177e4SLinus Torvalds  * Isochronous transfers
10531da177e4SLinus Torvalds  */
1054dccf4a48SAlan Stern static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1055dccf4a48SAlan Stern 		struct uhci_qh *qh)
10561da177e4SLinus Torvalds {
1057dccf4a48SAlan Stern 	struct uhci_td *td = NULL;	/* Since urb->number_of_packets > 0 */
10581da177e4SLinus Torvalds 	int i, ret, frame;
1059dccf4a48SAlan Stern 	unsigned long destination, status;
1060b81d3436SAlan Stern 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
10611da177e4SLinus Torvalds 
10621da177e4SLinus Torvalds 	status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
10631da177e4SLinus Torvalds 	destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
10641da177e4SLinus Torvalds 
10651da177e4SLinus Torvalds 	ret = isochronous_find_start(uhci, urb);
10661da177e4SLinus Torvalds 	if (ret)
10671da177e4SLinus Torvalds 		return ret;
10681da177e4SLinus Torvalds 
1069b81d3436SAlan Stern 	for (i = 0; i < urb->number_of_packets; i++) {
10702532178aSAlan Stern 		td = uhci_alloc_td(uhci);
10711da177e4SLinus Torvalds 		if (!td)
10721da177e4SLinus Torvalds 			return -ENOMEM;
10731da177e4SLinus Torvalds 
10741da177e4SLinus Torvalds 		uhci_add_td_to_urb(urb, td);
1075dccf4a48SAlan Stern 		uhci_fill_td(td, status, destination |
1076dccf4a48SAlan Stern 				uhci_explen(urb->iso_frame_desc[i].length),
1077dccf4a48SAlan Stern 				urb->transfer_dma +
1078dccf4a48SAlan Stern 					urb->iso_frame_desc[i].offset);
1079b81d3436SAlan Stern 	}
10801da177e4SLinus Torvalds 
1081dccf4a48SAlan Stern 	/* Set the interrupt-on-completion flag on the last packet. */
1082dccf4a48SAlan Stern 	td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
1083dccf4a48SAlan Stern 
1084dccf4a48SAlan Stern 	qh->skel = uhci->skel_iso_qh;
1085dccf4a48SAlan Stern 
1086dccf4a48SAlan Stern 	/* Add the TDs to the frame list */
1087b81d3436SAlan Stern 	frame = urb->start_frame;
1088b81d3436SAlan Stern 	list_for_each_entry(td, &urbp->td_list, list) {
1089dccf4a48SAlan Stern 		uhci_insert_td_in_frame_list(uhci, td, frame);
1090b81d3436SAlan Stern 		frame += urb->interval;
10911da177e4SLinus Torvalds 	}
10921da177e4SLinus Torvalds 
1093dccf4a48SAlan Stern 	return 0;
10941da177e4SLinus Torvalds }
10951da177e4SLinus Torvalds 
10961da177e4SLinus Torvalds static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
10971da177e4SLinus Torvalds {
10981da177e4SLinus Torvalds 	struct uhci_td *td;
10991da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
11001da177e4SLinus Torvalds 	int status;
11011da177e4SLinus Torvalds 	int i, ret = 0;
11021da177e4SLinus Torvalds 
1103b81d3436SAlan Stern 	urb->actual_length = urb->error_count = 0;
11041da177e4SLinus Torvalds 
11051da177e4SLinus Torvalds 	i = 0;
11061da177e4SLinus Torvalds 	list_for_each_entry(td, &urbp->td_list, list) {
11071da177e4SLinus Torvalds 		int actlength;
11081da177e4SLinus Torvalds 		unsigned int ctrlstat = td_status(td);
11091da177e4SLinus Torvalds 
11101da177e4SLinus Torvalds 		if (ctrlstat & TD_CTRL_ACTIVE)
11111da177e4SLinus Torvalds 			return -EINPROGRESS;
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 		actlength = uhci_actual_length(ctrlstat);
11141da177e4SLinus Torvalds 		urb->iso_frame_desc[i].actual_length = actlength;
11151da177e4SLinus Torvalds 		urb->actual_length += actlength;
11161da177e4SLinus Torvalds 
11171da177e4SLinus Torvalds 		status = uhci_map_status(uhci_status_bits(ctrlstat),
11181da177e4SLinus Torvalds 				usb_pipeout(urb->pipe));
11191da177e4SLinus Torvalds 		urb->iso_frame_desc[i].status = status;
11201da177e4SLinus Torvalds 		if (status) {
11211da177e4SLinus Torvalds 			urb->error_count++;
11221da177e4SLinus Torvalds 			ret = status;
11231da177e4SLinus Torvalds 		}
11241da177e4SLinus Torvalds 
11251da177e4SLinus Torvalds 		i++;
11261da177e4SLinus Torvalds 	}
11271da177e4SLinus Torvalds 
11281da177e4SLinus Torvalds 	return ret;
11291da177e4SLinus Torvalds }
11301da177e4SLinus Torvalds 
11311da177e4SLinus Torvalds static int uhci_urb_enqueue(struct usb_hcd *hcd,
1132dccf4a48SAlan Stern 		struct usb_host_endpoint *hep,
113355016f10SAl Viro 		struct urb *urb, gfp_t mem_flags)
11341da177e4SLinus Torvalds {
11351da177e4SLinus Torvalds 	int ret;
11361da177e4SLinus Torvalds 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
11371da177e4SLinus Torvalds 	unsigned long flags;
1138dccf4a48SAlan Stern 	struct urb_priv *urbp;
1139dccf4a48SAlan Stern 	struct uhci_qh *qh;
11401da177e4SLinus Torvalds 	int bustime;
11411da177e4SLinus Torvalds 
11421da177e4SLinus Torvalds 	spin_lock_irqsave(&uhci->lock, flags);
11431da177e4SLinus Torvalds 
11441da177e4SLinus Torvalds 	ret = urb->status;
11451da177e4SLinus Torvalds 	if (ret != -EINPROGRESS)		/* URB already unlinked! */
1146dccf4a48SAlan Stern 		goto done;
11471da177e4SLinus Torvalds 
11481da177e4SLinus Torvalds 	ret = -ENOMEM;
1149dccf4a48SAlan Stern 	urbp = uhci_alloc_urb_priv(uhci, urb);
1150dccf4a48SAlan Stern 	if (!urbp)
1151dccf4a48SAlan Stern 		goto done;
1152dccf4a48SAlan Stern 
1153dccf4a48SAlan Stern 	if (hep->hcpriv)
1154dccf4a48SAlan Stern 		qh = (struct uhci_qh *) hep->hcpriv;
1155dccf4a48SAlan Stern 	else {
1156dccf4a48SAlan Stern 		qh = uhci_alloc_qh(uhci, urb->dev, hep);
1157dccf4a48SAlan Stern 		if (!qh)
1158dccf4a48SAlan Stern 			goto err_no_qh;
11591da177e4SLinus Torvalds 	}
1160dccf4a48SAlan Stern 	urbp->qh = qh;
11611da177e4SLinus Torvalds 
11621da177e4SLinus Torvalds 	switch (usb_pipetype(urb->pipe)) {
11631da177e4SLinus Torvalds 	case PIPE_CONTROL:
1164dccf4a48SAlan Stern 		ret = uhci_submit_control(uhci, urb, qh);
1165dccf4a48SAlan Stern 		break;
1166dccf4a48SAlan Stern 	case PIPE_BULK:
1167dccf4a48SAlan Stern 		ret = uhci_submit_bulk(uhci, urb, qh);
11681da177e4SLinus Torvalds 		break;
11691da177e4SLinus Torvalds 	case PIPE_INTERRUPT:
1170dccf4a48SAlan Stern 		if (list_empty(&qh->queue)) {
11711da177e4SLinus Torvalds 			bustime = usb_check_bandwidth(urb->dev, urb);
11721da177e4SLinus Torvalds 			if (bustime < 0)
11731da177e4SLinus Torvalds 				ret = bustime;
11741da177e4SLinus Torvalds 			else {
1175dccf4a48SAlan Stern 				ret = uhci_submit_interrupt(uhci, urb, qh);
1176dccf4a48SAlan Stern 				if (ret == 0)
11771da177e4SLinus Torvalds 					usb_claim_bandwidth(urb->dev, urb, bustime, 0);
11781da177e4SLinus Torvalds 			}
11791da177e4SLinus Torvalds 		} else {	/* inherit from parent */
1180dccf4a48SAlan Stern 			struct urb_priv *eurbp;
1181dccf4a48SAlan Stern 
1182dccf4a48SAlan Stern 			eurbp = list_entry(qh->queue.prev, struct urb_priv,
1183dccf4a48SAlan Stern 					node);
1184dccf4a48SAlan Stern 			urb->bandwidth = eurbp->urb->bandwidth;
1185dccf4a48SAlan Stern 			ret = uhci_submit_interrupt(uhci, urb, qh);
11861da177e4SLinus Torvalds 		}
11871da177e4SLinus Torvalds 		break;
11881da177e4SLinus Torvalds 	case PIPE_ISOCHRONOUS:
11891da177e4SLinus Torvalds 		bustime = usb_check_bandwidth(urb->dev, urb);
11901da177e4SLinus Torvalds 		if (bustime < 0) {
11911da177e4SLinus Torvalds 			ret = bustime;
11921da177e4SLinus Torvalds 			break;
11931da177e4SLinus Torvalds 		}
11941da177e4SLinus Torvalds 
1195dccf4a48SAlan Stern 		ret = uhci_submit_isochronous(uhci, urb, qh);
1196dccf4a48SAlan Stern 		if (ret == 0)
11971da177e4SLinus Torvalds 			usb_claim_bandwidth(urb->dev, urb, bustime, 1);
11981da177e4SLinus Torvalds 		break;
11991da177e4SLinus Torvalds 	}
1200dccf4a48SAlan Stern 	if (ret != 0)
1201dccf4a48SAlan Stern 		goto err_submit_failed;
12021da177e4SLinus Torvalds 
1203dccf4a48SAlan Stern 	/* Add this URB to the QH */
1204dccf4a48SAlan Stern 	urbp->qh = qh;
1205dccf4a48SAlan Stern 	list_add_tail(&urbp->node, &qh->queue);
1206dccf4a48SAlan Stern 	list_add_tail(&urbp->urb_list, &uhci->urb_list);
12071da177e4SLinus Torvalds 
1208dccf4a48SAlan Stern 	/* If the new URB is the first and only one on this QH then either
1209dccf4a48SAlan Stern 	 * the QH is new and idle or else it's unlinked and waiting to
1210dccf4a48SAlan Stern 	 * become idle, so we can activate it right away. */
1211dccf4a48SAlan Stern 	if (qh->queue.next == &urbp->node)
1212dccf4a48SAlan Stern 		uhci_activate_qh(uhci, qh);
1213dccf4a48SAlan Stern 	goto done;
1214dccf4a48SAlan Stern 
1215dccf4a48SAlan Stern err_submit_failed:
1216dccf4a48SAlan Stern 	if (qh->state == QH_STATE_IDLE)
1217dccf4a48SAlan Stern 		uhci_make_qh_idle(uhci, qh);	/* Reclaim unused QH */
1218dccf4a48SAlan Stern 
1219dccf4a48SAlan Stern err_no_qh:
1220dccf4a48SAlan Stern 	uhci_free_urb_priv(uhci, urbp);
1221dccf4a48SAlan Stern 
1222dccf4a48SAlan Stern done:
12231da177e4SLinus Torvalds 	spin_unlock_irqrestore(&uhci->lock, flags);
12241da177e4SLinus Torvalds 	return ret;
12251da177e4SLinus Torvalds }
12261da177e4SLinus Torvalds 
12271da177e4SLinus Torvalds /*
12281da177e4SLinus Torvalds  * Return the result of a transfer
12291da177e4SLinus Torvalds  */
12301da177e4SLinus Torvalds static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb)
12311da177e4SLinus Torvalds {
1232dccf4a48SAlan Stern 	int status;
1233dccf4a48SAlan Stern 	int okay_to_giveback = 0;
1234dccf4a48SAlan Stern 	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
12351da177e4SLinus Torvalds 
12361da177e4SLinus Torvalds 	switch (usb_pipetype(urb->pipe)) {
12371da177e4SLinus Torvalds 	case PIPE_CONTROL:
1238dccf4a48SAlan Stern 		status = uhci_result_control(uhci, urb);
12391da177e4SLinus Torvalds 		break;
12401da177e4SLinus Torvalds 	case PIPE_ISOCHRONOUS:
1241dccf4a48SAlan Stern 		status = uhci_result_isochronous(uhci, urb);
1242dccf4a48SAlan Stern 		break;
1243dccf4a48SAlan Stern 	default:	/* PIPE_BULK or PIPE_INTERRUPT */
1244dccf4a48SAlan Stern 		status = uhci_result_common(uhci, urb);
12451da177e4SLinus Torvalds 		break;
12461da177e4SLinus Torvalds 	}
12471da177e4SLinus Torvalds 
1248dccf4a48SAlan Stern 	spin_lock(&urb->lock);
1249dccf4a48SAlan Stern 	if (urb->status == -EINPROGRESS) {	/* Not yet dequeued */
1250dccf4a48SAlan Stern 		if (status != -EINPROGRESS) {	/* URB has completed */
1251dccf4a48SAlan Stern 			urb->status = status;
1252dccf4a48SAlan Stern 
1253dccf4a48SAlan Stern 			/* If the URB got a real error (as opposed to
1254dccf4a48SAlan Stern 			 * simply being dequeued), we don't have to
1255dccf4a48SAlan Stern 			 * unlink the QH.  Fix this later... */
1256dccf4a48SAlan Stern 			if (status < 0)
1257dccf4a48SAlan Stern 				uhci_unlink_qh(uhci, urbp->qh);
1258dccf4a48SAlan Stern 			else
1259dccf4a48SAlan Stern 				okay_to_giveback = 1;
1260dccf4a48SAlan Stern 		}
1261dccf4a48SAlan Stern 	} else {				/* Already dequeued */
1262dccf4a48SAlan Stern 		if (urbp->qh->state == QH_STATE_UNLINKING &&
1263dccf4a48SAlan Stern 				uhci->frame_number + uhci->is_stopped !=
1264dccf4a48SAlan Stern 				urbp->qh->unlink_frame)
1265dccf4a48SAlan Stern 			okay_to_giveback = 1;
1266dccf4a48SAlan Stern 	}
1267dccf4a48SAlan Stern 	spin_unlock(&urb->lock);
1268dccf4a48SAlan Stern 	if (!okay_to_giveback)
1269dccf4a48SAlan Stern 		return;
12701da177e4SLinus Torvalds 
12711da177e4SLinus Torvalds 	switch (usb_pipetype(urb->pipe)) {
12721da177e4SLinus Torvalds 	case PIPE_ISOCHRONOUS:
12731da177e4SLinus Torvalds 		/* Release bandwidth for Interrupt or Isoc. transfers */
12741da177e4SLinus Torvalds 		if (urb->bandwidth)
12751da177e4SLinus Torvalds 			usb_release_bandwidth(urb->dev, urb, 1);
12761da177e4SLinus Torvalds 		break;
12771da177e4SLinus Torvalds 	case PIPE_INTERRUPT:
12781da177e4SLinus Torvalds 		/* Release bandwidth for Interrupt or Isoc. transfers */
12791da177e4SLinus Torvalds 		/* Make sure we don't release if we have a queued URB */
1280dccf4a48SAlan Stern 		if (list_empty(&urbp->qh->queue) && urb->bandwidth)
12811da177e4SLinus Torvalds 			usb_release_bandwidth(urb->dev, urb, 0);
12821da177e4SLinus Torvalds 		else
12831da177e4SLinus Torvalds 			/* bandwidth was passed on to queued URB, */
12841da177e4SLinus Torvalds 			/* so don't let usb_unlink_urb() release it */
12851da177e4SLinus Torvalds 			urb->bandwidth = 0;
1286dccf4a48SAlan Stern 		/* Falls through */
1287dccf4a48SAlan Stern 	case PIPE_BULK:
1288dccf4a48SAlan Stern 		if (status < 0)
1289dccf4a48SAlan Stern 			uhci_fixup_toggles(urb);
12901da177e4SLinus Torvalds 		break;
1291dccf4a48SAlan Stern 	default:	/* PIPE_CONTROL */
1292dccf4a48SAlan Stern 		break;
12931da177e4SLinus Torvalds 	}
12941da177e4SLinus Torvalds 
1295dccf4a48SAlan Stern 	/* Take the URB's TDs off the hardware schedule */
1296dccf4a48SAlan Stern 	uhci_remove_tds_from_schedule(uhci, urb, status);
12971da177e4SLinus Torvalds 
1298dccf4a48SAlan Stern 	/* Take the URB off the QH's queue and see if the QH is now unused */
1299dccf4a48SAlan Stern 	list_del_init(&urbp->node);
1300dccf4a48SAlan Stern 	if (list_empty(&urbp->qh->queue))
1301dccf4a48SAlan Stern 		uhci_unlink_qh(uhci, urbp->qh);
13021da177e4SLinus Torvalds 
13031da177e4SLinus Torvalds 	uhci_dec_fsbr(uhci, urb);	/* Safe since it checks */
13041da177e4SLinus Torvalds 
1305dccf4a48SAlan Stern 	/* Queue it for giving back */
1306dccf4a48SAlan Stern 	list_move_tail(&urbp->urb_list, &uhci->complete_list);
13071da177e4SLinus Torvalds }
13081da177e4SLinus Torvalds 
1309dccf4a48SAlan Stern /*
1310dccf4a48SAlan Stern  * Check out the QHs waiting to be fully unlinked
1311dccf4a48SAlan Stern  */
1312dccf4a48SAlan Stern static void uhci_scan_unlinking_qhs(struct uhci_hcd *uhci)
1313dccf4a48SAlan Stern {
1314dccf4a48SAlan Stern 	struct uhci_qh *qh, *tmp;
13151da177e4SLinus Torvalds 
1316dccf4a48SAlan Stern 	list_for_each_entry_safe(qh, tmp, &uhci->skel_unlink_qh->node, node) {
1317dccf4a48SAlan Stern 
1318dccf4a48SAlan Stern 		/* If the queue is empty and the QH is fully unlinked then
1319dccf4a48SAlan Stern 		 * it can become IDLE. */
1320dccf4a48SAlan Stern 		if (list_empty(&qh->queue)) {
1321dccf4a48SAlan Stern 			if (uhci->frame_number + uhci->is_stopped !=
1322dccf4a48SAlan Stern 					qh->unlink_frame)
1323dccf4a48SAlan Stern 				uhci_make_qh_idle(uhci, qh);
1324dccf4a48SAlan Stern 
1325dccf4a48SAlan Stern 		/* If none of the QH's URBs have been dequeued then the QH
1326dccf4a48SAlan Stern 		 * should be re-activated. */
1327dccf4a48SAlan Stern 		} else {
1328dccf4a48SAlan Stern 			struct urb_priv *urbp;
1329dccf4a48SAlan Stern 			int any_dequeued = 0;
1330dccf4a48SAlan Stern 
1331dccf4a48SAlan Stern 			list_for_each_entry(urbp, &qh->queue, node) {
1332dccf4a48SAlan Stern 				if (urbp->urb->status != -EINPROGRESS) {
1333dccf4a48SAlan Stern 					any_dequeued = 1;
1334dccf4a48SAlan Stern 					break;
1335dccf4a48SAlan Stern 				}
1336dccf4a48SAlan Stern 			}
1337dccf4a48SAlan Stern 			if (!any_dequeued)
1338dccf4a48SAlan Stern 				uhci_activate_qh(uhci, qh);
1339dccf4a48SAlan Stern 		}
1340dccf4a48SAlan Stern 	}
13411da177e4SLinus Torvalds }
13421da177e4SLinus Torvalds 
13431da177e4SLinus Torvalds static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
13441da177e4SLinus Torvalds {
13451da177e4SLinus Torvalds 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
13461da177e4SLinus Torvalds 	unsigned long flags;
13471da177e4SLinus Torvalds 	struct urb_priv *urbp;
13481da177e4SLinus Torvalds 
13491da177e4SLinus Torvalds 	spin_lock_irqsave(&uhci->lock, flags);
13501da177e4SLinus Torvalds 	urbp = urb->hcpriv;
13511da177e4SLinus Torvalds 	if (!urbp)			/* URB was never linked! */
13521da177e4SLinus Torvalds 		goto done;
13531da177e4SLinus Torvalds 
1354dccf4a48SAlan Stern 	/* Remove Isochronous TDs from the frame list ASAP */
1355b81d3436SAlan Stern 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
1356dccf4a48SAlan Stern 		uhci_unlink_isochronous_tds(uhci, urb);
1357dccf4a48SAlan Stern 	uhci_unlink_qh(uhci, urbp->qh);
13581da177e4SLinus Torvalds 
13591da177e4SLinus Torvalds done:
13601da177e4SLinus Torvalds 	spin_unlock_irqrestore(&uhci->lock, flags);
13611da177e4SLinus Torvalds 	return 0;
13621da177e4SLinus Torvalds }
13631da177e4SLinus Torvalds 
13641da177e4SLinus Torvalds static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb)
13651da177e4SLinus Torvalds {
13661da177e4SLinus Torvalds 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
13671da177e4SLinus Torvalds 	struct list_head *head;
13681da177e4SLinus Torvalds 	struct uhci_td *td;
13691da177e4SLinus Torvalds 	int count = 0;
13701da177e4SLinus Torvalds 
13711da177e4SLinus Torvalds 	uhci_dec_fsbr(uhci, urb);
13721da177e4SLinus Torvalds 
13731da177e4SLinus Torvalds 	urbp->fsbr_timeout = 1;
13741da177e4SLinus Torvalds 
13751da177e4SLinus Torvalds 	/*
13761da177e4SLinus Torvalds 	 * Ideally we would want to fix qh->element as well, but it's
13771da177e4SLinus Torvalds 	 * read/write by the HC, so that can introduce a race. It's not
13781da177e4SLinus Torvalds 	 * really worth the hassle
13791da177e4SLinus Torvalds 	 */
13801da177e4SLinus Torvalds 
13811da177e4SLinus Torvalds 	head = &urbp->td_list;
13821da177e4SLinus Torvalds 	list_for_each_entry(td, head, list) {
13831da177e4SLinus Torvalds 		/*
13841da177e4SLinus Torvalds 		 * Make sure we don't do the last one (since it'll have the
1385687f5f34SAlan Stern 		 * TERM bit set) as well as we skip every so many TDs to
13861da177e4SLinus Torvalds 		 * make sure it doesn't hog the bandwidth
13871da177e4SLinus Torvalds 		 */
13881da177e4SLinus Torvalds 		if (td->list.next != head && (count % DEPTH_INTERVAL) ==
13891da177e4SLinus Torvalds 				(DEPTH_INTERVAL - 1))
13901da177e4SLinus Torvalds 			td->link |= UHCI_PTR_DEPTH;
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 		count++;
13931da177e4SLinus Torvalds 	}
13941da177e4SLinus Torvalds 
13951da177e4SLinus Torvalds 	return 0;
13961da177e4SLinus Torvalds }
13971da177e4SLinus Torvalds 
13981da177e4SLinus Torvalds static void uhci_free_pending_tds(struct uhci_hcd *uhci)
13991da177e4SLinus Torvalds {
14001da177e4SLinus Torvalds 	struct uhci_td *td, *tmp;
14011da177e4SLinus Torvalds 
14021da177e4SLinus Torvalds 	list_for_each_entry_safe(td, tmp, &uhci->td_remove_list, remove_list) {
14031da177e4SLinus Torvalds 		list_del_init(&td->remove_list);
14041da177e4SLinus Torvalds 
14051da177e4SLinus Torvalds 		uhci_free_td(uhci, td);
14061da177e4SLinus Torvalds 	}
14071da177e4SLinus Torvalds }
14081da177e4SLinus Torvalds 
14091da177e4SLinus Torvalds static void
14101da177e4SLinus Torvalds uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
14111da177e4SLinus Torvalds __releases(uhci->lock)
14121da177e4SLinus Torvalds __acquires(uhci->lock)
14131da177e4SLinus Torvalds {
14141da177e4SLinus Torvalds 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
14151da177e4SLinus Torvalds 
1416dccf4a48SAlan Stern 	uhci_free_urb_priv(uhci, (struct urb_priv *) (urb->hcpriv));
14171da177e4SLinus Torvalds 
14181da177e4SLinus Torvalds 	spin_unlock(&uhci->lock);
14191da177e4SLinus Torvalds 	usb_hcd_giveback_urb(hcd, urb, regs);
14201da177e4SLinus Torvalds 	spin_lock(&uhci->lock);
14211da177e4SLinus Torvalds }
14221da177e4SLinus Torvalds 
14231da177e4SLinus Torvalds static void uhci_finish_completion(struct uhci_hcd *uhci, struct pt_regs *regs)
14241da177e4SLinus Torvalds {
14251da177e4SLinus Torvalds 	struct urb_priv *urbp, *tmp;
14261da177e4SLinus Torvalds 
14271da177e4SLinus Torvalds 	list_for_each_entry_safe(urbp, tmp, &uhci->complete_list, urb_list) {
14281da177e4SLinus Torvalds 		struct urb *urb = urbp->urb;
14291da177e4SLinus Torvalds 
14301da177e4SLinus Torvalds 		list_del_init(&urbp->urb_list);
14311da177e4SLinus Torvalds 		uhci_finish_urb(uhci_to_hcd(uhci), urb, regs);
14321da177e4SLinus Torvalds 	}
14331da177e4SLinus Torvalds }
14341da177e4SLinus Torvalds 
14351da177e4SLinus Torvalds /* Process events in the schedule, but only in one thread at a time */
14361da177e4SLinus Torvalds static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
14371da177e4SLinus Torvalds {
14381da177e4SLinus Torvalds 	struct urb_priv *urbp, *tmp;
14391da177e4SLinus Torvalds 
14401da177e4SLinus Torvalds 	/* Don't allow re-entrant calls */
14411da177e4SLinus Torvalds 	if (uhci->scan_in_progress) {
14421da177e4SLinus Torvalds 		uhci->need_rescan = 1;
14431da177e4SLinus Torvalds 		return;
14441da177e4SLinus Torvalds 	}
14451da177e4SLinus Torvalds 	uhci->scan_in_progress = 1;
14461da177e4SLinus Torvalds  rescan:
14471da177e4SLinus Torvalds 	uhci->need_rescan = 0;
14481da177e4SLinus Torvalds 
14496c1b445cSAlan Stern 	uhci_clear_next_interrupt(uhci);
14501da177e4SLinus Torvalds 	uhci_get_current_frame_number(uhci);
14511da177e4SLinus Torvalds 
14521da177e4SLinus Torvalds 	if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age)
14531da177e4SLinus Torvalds 		uhci_free_pending_tds(uhci);
14541da177e4SLinus Torvalds 
14551da177e4SLinus Torvalds 	/* Walk the list of pending URBs to see which ones completed
14561da177e4SLinus Torvalds 	 * (must be _safe because uhci_transfer_result() dequeues URBs) */
14571da177e4SLinus Torvalds 	list_for_each_entry_safe(urbp, tmp, &uhci->urb_list, urb_list) {
14581da177e4SLinus Torvalds 		struct urb *urb = urbp->urb;
14591da177e4SLinus Torvalds 
14601da177e4SLinus Torvalds 		/* Checks the status and does all of the magic necessary */
14611da177e4SLinus Torvalds 		uhci_transfer_result(uhci, urb);
14621da177e4SLinus Torvalds 	}
14631da177e4SLinus Torvalds 	uhci_finish_completion(uhci, regs);
14641da177e4SLinus Torvalds 
14651da177e4SLinus Torvalds 	/* If the controller is stopped, we can finish these off right now */
1466dccf4a48SAlan Stern 	if (uhci->is_stopped)
14671da177e4SLinus Torvalds 		uhci_free_pending_tds(uhci);
14681da177e4SLinus Torvalds 
14691da177e4SLinus Torvalds 	if (uhci->need_rescan)
14701da177e4SLinus Torvalds 		goto rescan;
14711da177e4SLinus Torvalds 	uhci->scan_in_progress = 0;
14721da177e4SLinus Torvalds 
1473dccf4a48SAlan Stern 	/* Check out the QHs waiting for unlinking */
1474dccf4a48SAlan Stern 	uhci_scan_unlinking_qhs(uhci);
1475dccf4a48SAlan Stern 
1476dccf4a48SAlan Stern 	if (list_empty(&uhci->td_remove_list) &&
1477dccf4a48SAlan Stern 			list_empty(&uhci->skel_unlink_qh->node))
14781da177e4SLinus Torvalds 		uhci_clear_next_interrupt(uhci);
14791da177e4SLinus Torvalds 	else
14801da177e4SLinus Torvalds 		uhci_set_next_interrupt(uhci);
14811da177e4SLinus Torvalds }
1482f5946f82SAlan Stern 
1483f5946f82SAlan Stern static void check_fsbr(struct uhci_hcd *uhci)
1484f5946f82SAlan Stern {
1485f5946f82SAlan Stern 	struct urb_priv *up;
1486f5946f82SAlan Stern 
1487f5946f82SAlan Stern 	list_for_each_entry(up, &uhci->urb_list, urb_list) {
1488f5946f82SAlan Stern 		struct urb *u = up->urb;
1489f5946f82SAlan Stern 
1490f5946f82SAlan Stern 		spin_lock(&u->lock);
1491f5946f82SAlan Stern 
1492f5946f82SAlan Stern 		/* Check if the FSBR timed out */
1493f5946f82SAlan Stern 		if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
1494f5946f82SAlan Stern 			uhci_fsbr_timeout(uhci, u);
1495f5946f82SAlan Stern 
1496f5946f82SAlan Stern 		spin_unlock(&u->lock);
1497f5946f82SAlan Stern 	}
1498f5946f82SAlan Stern 
1499f5946f82SAlan Stern 	/* Really disable FSBR */
1500f5946f82SAlan Stern 	if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
1501f5946f82SAlan Stern 		uhci->fsbrtimeout = 0;
1502f5946f82SAlan Stern 		uhci->skel_term_qh->link = UHCI_PTR_TERM;
1503f5946f82SAlan Stern 	}
1504f5946f82SAlan Stern }
1505