11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2001-2004 by David Brownell
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2003 Michal Sojka, for high-speed iso transfers
453bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of the GNU General Public License as published by the
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Free Software Foundation; either version 2 of the License, or (at your
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * option) any later version.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, but
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details.
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software Foundation,
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this file is part of ehci-hcd.c */
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EHCI scheduled transaction support:  interrupt, iso, split iso
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * These are called "periodic" transactions in the EHCI spec.
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note that for interrupt transfers, the QH/QTD manipulation is shared
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with the "asynchronous" transaction support (control/bulk transfers).
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The only real difference is in how interrupt transfers are scheduled.
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For ISO, we make an "iso_stream" head to serve the same role as a QH.
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It keeps track of every ITD (or SITD) that's linked, and holds enough
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pre-calculated schedule data to make appending to the queue be quick.
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ehci_get_frame (struct usb_hcd *hcd);
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3968aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern#ifdef CONFIG_PCI
4068aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern
4168aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Sternstatic unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
4268aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern{
4368aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	unsigned uf;
4468aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern
4568aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	/*
4668aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 * The MosChip MCS9990 controller updates its microframe counter
4768aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 * a little before the frame counter, and occasionally we will read
4868aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 * the invalid intermediate value.  Avoid problems by checking the
4968aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 * microframe number (the low-order 3 bits); if they are 0 then
5068aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 * re-read the register to get the correct value.
5168aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	 */
5268aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	uf = ehci_readl(ehci, &ehci->regs->frame_index);
5368aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
5468aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern		uf = ehci_readl(ehci, &ehci->regs->frame_index);
5568aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	return uf;
5668aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern}
5768aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern
5868aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern#endif
5968aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * periodic_next_shadow - return "next" pointer on shadow list
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @periodic: host pointer to qh/itd/sitd
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @tag: hardware tag for type of this record
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic union ehci_shadow *
686dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roeseperiodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
696dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		__hc32 tag)
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
716dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	switch (hc32_to_cpu(ehci, tag)) {
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case Q_TYPE_QH:
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return &periodic->qh->qh_next;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case Q_TYPE_FSTN:
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return &periodic->fstn->fstn_next;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case Q_TYPE_ITD:
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return &periodic->itd->itd_next;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// case Q_TYPE_SITD:
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return &periodic->sitd->sitd_next;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
843807e26d69b9ad3864fe03224ebebc9610d5802eAlek Dustatic __hc32 *
853807e26d69b9ad3864fe03224ebebc9610d5802eAlek Dushadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic,
863807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		__hc32 tag)
873807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du{
883807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	switch (hc32_to_cpu(ehci, tag)) {
893807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	/* our ehci_shadow.qh is actually software part */
903807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	case Q_TYPE_QH:
913807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		return &periodic->qh->hw->hw_next;
923807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	/* others are hw parts */
933807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	default:
943807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		return periodic->hw_next;
953807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	}
963807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du}
973807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* caller must hold ehci->lock */
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1016dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	union ehci_shadow	*prev_p = &ehci->pshadow[frame];
1026dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	__hc32			*hw_p = &ehci->periodic[frame];
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union ehci_shadow	here = *prev_p;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* find predecessor of "ptr"; hw and shadow lists are in sync */
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (here.ptr && here.ptr != ptr) {
1076dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		prev_p = periodic_next_shadow(ehci, prev_p,
1086dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				Q_NEXT_TYPE(ehci, *hw_p));
1093807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		hw_p = shadow_next_periodic(ehci, &here,
1103807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				Q_NEXT_TYPE(ehci, *hw_p));
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		here = *prev_p;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* an interrupt entry (at list end) could have been shared */
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!here.ptr)
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* update shadow and hardware lists ... the old "next" pointers
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * from ptr may still be in use, the caller updates them.
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1206dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	*prev_p = *periodic_next_shadow(ehci, &here,
1216dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			Q_NEXT_TYPE(ehci, *hw_p));
1223d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu
1233d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu	if (!ehci->use_dummy_qh ||
1243d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu	    *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p))
1253d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu			!= EHCI_LIST_END(ehci))
1263d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu		*hw_p = *shadow_next_periodic(ehci, &here,
1273d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				Q_NEXT_TYPE(ehci, *hw_p));
1283d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu	else
1293d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu		*hw_p = ehci->dummy->qh_dma;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* how many of the uframe's 125 usecs are allocated? */
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsperiodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1366dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	__hc32			*hw_p = &ehci->periodic [frame];
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union ehci_shadow	*q = &ehci->pshadow [frame];
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		usecs = 0;
1393807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	struct ehci_qh_hw	*hw;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (q->ptr) {
1426dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case Q_TYPE_QH:
1443807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			hw = q->qh->hw;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* is it in the S-mask? */
1463807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				usecs += q->qh->usecs;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* ... or C-mask? */
1493807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			if (hw->hw_info2 & cpu_to_hc32(ehci,
1506dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					1 << (8 + uframe)))
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				usecs += q->qh->c_usecs;
1523807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			hw_p = &hw->hw_next;
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			q = &q->qh->qh_next;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// case Q_TYPE_FSTN:
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* for "save place" FSTNs, count the relevant INTR
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * bandwidth from the previous frame
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
1606dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			if (q->fstn->hw_prev != EHCI_LIST_END(ehci)) {
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ehci_dbg (ehci, "ignoring FSTN cost ...\n");
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw_p = &q->fstn->hw_next;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			q = &q->fstn->fstn_next;
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case Q_TYPE_ITD:
1673b6fcfd0664aeac6ae2fd1231f04b3ed24723c1eKarsten Wiese			if (q->itd->hw_transaction[uframe])
1683b6fcfd0664aeac6ae2fd1231f04b3ed24723c1eKarsten Wiese				usecs += q->itd->stream->usecs;
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw_p = &q->itd->hw_next;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			q = &q->itd->itd_next;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case Q_TYPE_SITD:
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* is it in the S-mask?  (count SPLIT, DATA) */
1746dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			if (q->sitd->hw_uframe & cpu_to_hc32(ehci,
1756dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					1 << uframe)) {
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (q->sitd->hw_fullspeed_ep &
1776dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese						cpu_to_hc32(ehci, 1<<31))
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					usecs += q->sitd->stream->usecs;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else	/* worst case for OUT start-split */
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					usecs += HS_USECS_ISO (188);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* ... C-mask?  (count CSPLIT, DATA) */
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (q->sitd->hw_uframe &
1856dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					cpu_to_hc32(ehci, 1 << (8 + uframe))) {
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* worst case for IN complete-split */
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				usecs += q->sitd->stream->c_usecs;
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw_p = &q->sitd->hw_next;
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			q = &q->sitd->sitd_next;
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef	DEBUG
196cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov	if (usecs > ehci->uframe_periodic_max)
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_err (ehci, "uframe %d sched overrun: %d usecs\n",
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame * 8 + uframe, usecs);
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return usecs;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int same_tt (struct usb_device *dev1, struct usb_device *dev2)
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev1->tt || !dev2->tt)
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev1->tt != dev2->tt)
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev1->tt->multi)
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return dev1->ttport == dev2->ttport;
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
217ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
218ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
219ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman/* Which uframe does the low/fullspeed transfer start in?
220ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
221ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * The parameter is the mask of ssplits in "H-frame" terms
222ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * and this returns the transfer start uframe in "B-frame" terms,
223ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * which allows both to match, e.g. a ssplit in "H-frame" uframe 0
224ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * will cause a transfer in "B-frame" uframe 0.  "B-frames" lag
225ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * "H-frames" by 1 uframe.  See the EHCI spec sec 4.5 and figure 4.7.
226ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman */
2276dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roesestatic inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
228ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman{
2296dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	unsigned char smask = QH_SMASK & hc32_to_cpu(ehci, mask);
230ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	if (!smask) {
231ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		ehci_err(ehci, "invalid empty smask!\n");
232ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		/* uframe 7 can't have bw so this will indicate failure */
233ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		return 7;
234ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	}
235ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	return ffs(smask) - 1;
236ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman}
237ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
238ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanstatic const unsigned char
239ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanmax_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
240ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
241ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman/* carryover low/fullspeed bandwidth that crosses uframe boundries */
242ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanstatic inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
243ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman{
244ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	int i;
245ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	for (i=0; i<7; i++) {
246ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		if (max_tt_usecs[i] < tt_usecs[i]) {
247ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i];
248ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			tt_usecs[i] = max_tt_usecs[i];
249ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		}
250ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	}
251ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman}
252ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
253ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman/* How many of the tt's periodic downstream 1000 usecs are allocated?
254ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
255ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * While this measures the bandwidth in terms of usecs/uframe,
256ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * the low/fullspeed bus has no notion of uframes, so any particular
257ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * low/fullspeed transfer can "carry over" from one uframe to the next,
258ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * since the TT just performs downstream transfers in sequence.
259ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
260dc0d5c1e5c7532e800fff6e313cd4af44af99976Joe Perches * For example two separate 100 usec transfers can start in the same uframe,
261ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * and the second one would "carry over" 75 usecs into the next uframe.
262ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman */
263ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanstatic void
264ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanperiodic_tt_usecs (
265ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	struct ehci_hcd *ehci,
266ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	struct usb_device *dev,
267ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned frame,
268ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned short tt_usecs[8]
269ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman)
270ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman{
2716dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	__hc32			*hw_p = &ehci->periodic [frame];
272ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	union ehci_shadow	*q = &ehci->pshadow [frame];
273ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned char		uf;
274ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
275ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	memset(tt_usecs, 0, 16);
276ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
277ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	while (q->ptr) {
2786dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
279ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		case Q_TYPE_ITD:
280ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			hw_p = &q->itd->hw_next;
281ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			q = &q->itd->itd_next;
282ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			continue;
283ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		case Q_TYPE_QH:
284ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			if (same_tt(dev, q->qh->dev)) {
2853807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				uf = tt_start_uframe(ehci, q->qh->hw->hw_info2);
286ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				tt_usecs[uf] += q->qh->tt_usecs;
287ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			}
2883807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			hw_p = &q->qh->hw->hw_next;
289ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			q = &q->qh->qh_next;
290ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			continue;
291ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		case Q_TYPE_SITD:
292ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			if (same_tt(dev, q->sitd->urb->dev)) {
293ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				uf = tt_start_uframe(ehci, q->sitd->hw_uframe);
294ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				tt_usecs[uf] += q->sitd->stream->tt_usecs;
295ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			}
296ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			hw_p = &q->sitd->hw_next;
297ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			q = &q->sitd->sitd_next;
298ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			continue;
299ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		// case Q_TYPE_FSTN:
300ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		default:
3016dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n",
3026dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					frame);
303ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			hw_p = &q->fstn->hw_next;
304ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			q = &q->fstn->fstn_next;
305ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		}
306ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	}
307ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
308ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	carryover_tt_bandwidth(tt_usecs);
309ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
310ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	if (max_tt_usecs[7] < tt_usecs[7])
311ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n",
312ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			frame, tt_usecs[7] - max_tt_usecs[7]);
313ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman}
314ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
315ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman/*
316ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * Return true if the device's tt's downstream bus is available for a
317ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * periodic transfer of the specified length (usecs), starting at the
318ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * specified frame/uframe.  Note that (as summarized in section 11.19
319ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * of the usb 2.0 spec) TTs can buffer multiple transactions for each
320ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * uframe.
321ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
322ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * The uframe parameter is when the fullspeed/lowspeed transfer
323ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * should be executed in "B-frame" terms, which is the same as the
324ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * highspeed ssplit's uframe (which is in "H-frame" terms).  For example
325ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * a ssplit in "H-frame" 0 causes a transfer in "B-frame" 0.
326ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * See the EHCI spec sec 4.5 and fig 4.7.
327ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
328ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * This checks if the full/lowspeed bus, at the specified starting uframe,
329ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * has the specified bandwidth available, according to rules listed
330ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * in USB 2.0 spec section 11.18.1 fig 11-60.
331ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman *
332ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * This does not check if the transfer would exceed the max ssplit
333ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4,
334ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman * since proper scheduling limits ssplits to less than 16 per uframe.
335ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman */
336ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetmanstatic int tt_available (
337ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	struct ehci_hcd		*ehci,
338ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned		period,
339ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	struct usb_device	*dev,
340ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned		frame,
341ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	unsigned		uframe,
342ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	u16			usecs
343ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman)
344ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman{
345ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	if ((period == 0) || (uframe >= 7))	/* error */
346ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		return 0;
347ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
348ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	for (; frame < ehci->periodic_size; frame += period) {
349ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		unsigned short tt_usecs[8];
350ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
351ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		periodic_tt_usecs (ehci, dev, frame, tt_usecs);
352ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
353ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		ehci_vdbg(ehci, "tt frame %d check %d usecs start uframe %d in"
354ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			" schedule %d/%d/%d/%d/%d/%d/%d/%d\n",
355ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			frame, usecs, uframe,
356ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			tt_usecs[0], tt_usecs[1], tt_usecs[2], tt_usecs[3],
357ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			tt_usecs[4], tt_usecs[5], tt_usecs[6], tt_usecs[7]);
358ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
359ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		if (max_tt_usecs[uframe] <= tt_usecs[uframe]) {
360ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			ehci_vdbg(ehci, "frame %d uframe %d fully scheduled\n",
361ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				frame, uframe);
362ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			return 0;
363ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		}
364ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
365ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		/* special case for isoc transfers larger than 125us:
366ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 * the first and each subsequent fully used uframe
367ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 * must be empty, so as to not illegally delay
368ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 * already scheduled transactions
369ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 */
370ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		if (125 < usecs) {
371c065c60e83c006611caed23d1320450fcd709398Dan Streetman			int ufs = (usecs / 125);
372ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			int i;
373ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			for (i = uframe; i < (uframe + ufs) && i < 8; i++)
374ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				if (0 < tt_usecs[i]) {
375ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman					ehci_vdbg(ehci,
376ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman						"multi-uframe xfer can't fit "
377ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman						"in frame %d uframe %d\n",
378ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman						frame, i);
379ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman					return 0;
380ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				}
381ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		}
382ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
383ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		tt_usecs[uframe] += usecs;
384ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
385ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		carryover_tt_bandwidth(tt_usecs);
386ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
387ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		/* fail if the carryover pushed bw past the last uframe's limit */
388ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		if (max_tt_usecs[7] < tt_usecs[7]) {
389ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			ehci_vdbg(ehci,
390ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				"tt unavailable usecs %d frame %d uframe %d\n",
391ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				usecs, frame, uframe);
392ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			return 0;
393ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		}
394ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	}
395ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
396ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	return 1;
397ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman}
398ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
399ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#else
400ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* return true iff the device's transaction translator is available
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for a periodic transfer starting at the specified frame, using
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * all the uframes in the mask.
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tt_no_collision (
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		period,
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_device	*dev,
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		frame,
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			uf_mask
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (period == 0)	/* error */
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* note bandwidth wastage:  split never follows csplit
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * (different dev or endpoint) until the next uframe.
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * calling convention doesn't make that distinction.
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (; frame < ehci->periodic_size; frame += period) {
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		union ehci_shadow	here;
4226dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		__hc32			type;
4233807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		struct ehci_qh_hw	*hw;
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		here = ehci->pshadow [frame];
4266dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]);
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (here.ptr) {
4286dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			switch (hc32_to_cpu(ehci, type)) {
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_ITD:
4306dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				type = Q_NEXT_TYPE(ehci, here.itd->hw_next);
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				here = here.itd->itd_next;
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_QH:
4343807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				hw = here.qh->hw;
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (same_tt (dev, here.qh->dev)) {
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					u32		mask;
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4386dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					mask = hc32_to_cpu(ehci,
4393807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du							hw->hw_info2);
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/* "knows" no gap is needed */
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mask |= mask >> 8;
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (mask & uf_mask)
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						break;
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4453807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				type = Q_NEXT_TYPE(ehci, hw->hw_next);
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				here = here.qh->qh_next;
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_SITD:
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (same_tt (dev, here.sitd->urb->dev)) {
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					u16		mask;
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4526dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					mask = hc32_to_cpu(ehci, here.sitd
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds								->hw_uframe);
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/* FIXME assumes no gap for IN! */
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mask |= mask >> 8;
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (mask & uf_mask)
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						break;
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4596dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				type = Q_NEXT_TYPE(ehci, here.sitd->hw_next);
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				here = here.sitd->sitd_next;
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			// case Q_TYPE_FSTN:
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ehci_dbg (ehci,
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					"periodic frame %d bogus type %d\n",
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					frame, type);
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* collision or error */
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* no collision */
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
478ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#endif /* CONFIG_USB_EHCI_TT_NEWSCHED */
479ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int enable_periodic (struct ehci_hcd *ehci)
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32	cmd;
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	status;
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
48701c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	if (ehci->periodic_sched++)
48801c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell		return 0;
48901c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* did clearing PSE did take effect yet?
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * takes effect only at frame boundaries...
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
493c765d4cad977f7e454a53d5bca5a942156b2d94cKarsten Wiese	status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
494c765d4cad977f7e454a53d5bca5a942156b2d94cKarsten Wiese					     STS_PSS, 0, 9 * 125);
49569fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern	if (status) {
49669fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern		usb_hc_died(ehci_to_hcd(ehci));
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return status;
49869fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern	}
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
500083522d76662cda71328df1f3d75e5a9057c7c9fBenjamin Herrenschmidt	cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
501083522d76662cda71328df1f3d75e5a9057c7c9fBenjamin Herrenschmidt	ehci_writel(ehci, cmd, &ehci->regs->command);
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* posted write ... PSS happens later */
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* make sure ehci_work scans these */
50568aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	ehci->next_uframe = ehci_read_frame_index(ehci)
506083522d76662cda71328df1f3d75e5a9057c7c9fBenjamin Herrenschmidt		% (ehci->periodic_size << 3);
507ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum	if (unlikely(ehci->broken_periodic))
508ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		ehci->last_periodic_enable = ktime_get_real();
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int disable_periodic (struct ehci_hcd *ehci)
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32	cmd;
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int	status;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51701c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	if (--ehci->periodic_sched)
51801c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell		return 0;
51901c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell
520ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum	if (unlikely(ehci->broken_periodic)) {
521ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		/* delay experimentally determined */
522ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000);
523ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		ktime_t now = ktime_get_real();
524ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		s64 delay = ktime_us_delta(safe, now);
525ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum
526ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum		if (unlikely(delay > 0))
527ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum			udelay(delay);
528ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum	}
529ee4ecb8ac63a5792bec448037d4b82ec4144f94bOliver Neukum
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* did setting PSE not take effect yet?
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * takes effect only at frame boundaries...
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
533c765d4cad977f7e454a53d5bca5a942156b2d94cKarsten Wiese	status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
534c765d4cad977f7e454a53d5bca5a942156b2d94cKarsten Wiese					     STS_PSS, STS_PSS, 9 * 125);
53569fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern	if (status) {
53669fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern		usb_hc_died(ehci_to_hcd(ehci));
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return status;
53869fff59de4d844f8b4c2454c3c23d32b69dcbfd7Alan Stern	}
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
540083522d76662cda71328df1f3d75e5a9057c7c9fBenjamin Herrenschmidt	cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
541083522d76662cda71328df1f3d75e5a9057c7c9fBenjamin Herrenschmidt	ehci_writel(ehci, cmd, &ehci->regs->command);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* posted write ... */
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5440e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	free_cached_lists(ehci);
545d63c66d2d08f52487f3ef32f1c9b1231d848966bDmitri Epshtein
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci->next_uframe = -1;
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* periodic schedule slots have iso tds (normal or split) first, then a
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sparse tree for active interrupt transfers.
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this just links in a qh; caller guarantees uframe masks are set right.
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no FSTN support (yet; ehci 0.96+)
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	i;
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	period = qh->period;
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_dbg (&qh->dev->dev,
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"link qh%d-%04x/%p start %d [%d/%d us]\n",
5653807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
5663807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			& (QH_CMASK | QH_SMASK),
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qh, qh->start, qh->usecs, qh->c_usecs);
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* high bandwidth, or otherwise every microframe */
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (period == 0)
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		period = 1;
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = qh->start; i < ehci->periodic_size; i += period) {
5746dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		union ehci_shadow	*prev = &ehci->pshadow[i];
5756dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		__hc32			*hw_p = &ehci->periodic[i];
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		union ehci_shadow	here = *prev;
5776dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		__hc32			type = 0;
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* skip the iso nodes at list head */
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (here.ptr) {
5816dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			type = Q_NEXT_TYPE(ehci, *hw_p);
5826dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5846dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			prev = periodic_next_shadow(ehci, prev, type);
5853807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			hw_p = shadow_next_periodic(ehci, &here, type);
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			here = *prev;
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* sorting each branch by period (slow-->fast)
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * enables sharing interior tree nodes
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (here.ptr && qh != here.qh) {
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (qh->period > here.qh->period)
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			prev = &here.qh->qh_next;
5963807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du			hw_p = &here.qh->hw->hw_next;
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			here = *prev;
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* link in this qh, unless some earlier pass did that */
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (qh != here.qh) {
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			qh->qh_next = here;
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (here.qh)
6033807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				qh->hw->hw_next = *hw_p;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			wmb ();
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			prev->qh = qh;
6066dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			*hw_p = QH_NEXT (ehci, qh->qh_dma);
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh->qh_state = QH_STATE_LINKED;
610ef4638f955f2c4a667c8af20769d03f5ed3781caAlan Stern	qh->xacterrs = 0;
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh_get (qh);
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* update per-qh bandwidth for usbfs */
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		? ((qh->usecs + qh->c_usecs) / qh->period)
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: (qh->usecs * 8);
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* maybe enable periodic schedule processing */
61901c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	return enable_periodic(ehci);
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
62201c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownellstatic int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	i;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	period;
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// FIXME:
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// IF this isn't high speed
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	//   and this qh is active in the current uframe
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	//   (and overlay token SplitXstate is false?)
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// THEN
632551509d267905705f6d723e51ec706916f06b859Harvey Harrison	//   qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */);
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* high bandwidth, or otherwise part of every microframe */
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((period = qh->period) == 0)
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		period = 1;
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = qh->start; i < ehci->periodic_size; i += period)
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		periodic_unlink (ehci, i, qh);
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* update per-qh bandwidth for usbfs */
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		? ((qh->usecs + qh->c_usecs) / qh->period)
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: (qh->usecs * 8);
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_dbg (&qh->dev->dev,
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
6487dedacf4270a810fadcca887ac85d267b5f1882dDavid Brownell		qh->period,
6493807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qh, qh->start, qh->usecs, qh->c_usecs);
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* qh->qh_next still "live" to HC */
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh->qh_state = QH_STATE_UNLINK;
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh->qh_next.ptr = NULL;
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh_put (qh);
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* maybe turn off periodic schedule */
65801c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	return disable_periodic(ehci);
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
663a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	unsigned		wait;
664a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	struct ehci_qh_hw	*hw = qh->hw;
665a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	int			rc;
666a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern
667a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	/* If the QH isn't linked then there's nothing we can do
668a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	 * unless we were called during a giveback, in which case
669a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	 * qh_completions() has to deal with it.
670a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	 */
671a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	if (qh->qh_state != QH_STATE_LINKED) {
672a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		if (qh->qh_state == QH_STATE_COMPLETING)
673a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern			qh->needs_rescan = 1;
674a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		return;
675a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	}
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh_unlink_periodic (ehci, qh);
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* simple/paranoid:  always delay, expecting the HC needs to read
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * qh->hw_next or finish a writeback after SPLIT/CSPLIT ... and
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * expect khubd to clean up after any CSPLITs we won't issue.
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * active high speed queues may need bigger delays...
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty (&qh->qtd_list)
6856dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			|| (cpu_to_hc32(ehci, QH_CMASK)
6863807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du					& hw->hw_info2) != 0)
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		wait = 2;
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		wait = 55;	/* worst case: 3 * 1024 */
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay (wait);
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh->qh_state = QH_STATE_IDLE;
6933807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	hw->hw_next = EHCI_LIST_END(ehci);
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	wmb ();
695a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern
696a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	qh_completions(ehci, qh);
697a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern
698a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	/* reschedule QH iff another request is queued */
699a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	if (!list_empty(&qh->qtd_list) &&
700e8799906045302776b35b66b16495c575db3b69cAlan Stern			ehci->rh_state == EHCI_RH_RUNNING) {
701a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		rc = qh_schedule(ehci, qh);
702a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern
703a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		/* An error here likely indicates handshake failure
704a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		 * or no space left in the schedule.  Neither fault
705a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		 * should happen often ...
706a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		 *
707a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		 * FIXME kill the now-dysfunctional queued urbs
708a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		 */
709a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern		if (rc != 0)
710a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern			ehci_err(ehci, "can't reschedule qh %p, err %d\n",
711a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern					qh, rc);
712a448c9d8c58ff7d3f8cc2a8f835065460099b22dAlan Stern	}
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int check_period (
71853bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	struct ehci_hcd *ehci,
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	frame,
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	uframe,
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	period,
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	usecs
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds) {
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int		claimed;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* complete split running into next frame?
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * given FSTN support, we could sometimes check...
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (uframe >= 8)
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
732cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov	/* convert "usecs we need" to "max already claimed" */
733cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov	usecs = ehci->uframe_periodic_max - usecs;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* we "know" 2 and 4 uframe intervals were rejected; so
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * for period 0, check _every_ microframe in the schedule.
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (period == 0)) {
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		do {
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (uframe = 0; uframe < 7; uframe++) {
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				claimed = periodic_usecs (ehci, frame, uframe);
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (claimed > usecs)
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return 0;
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} while ((frame += 1) < ehci->periodic_size);
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* just check the specified uframe, at that period */
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		do {
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			claimed = periodic_usecs (ehci, frame, uframe);
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (claimed > usecs)
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 0;
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} while ((frame += period) < ehci->periodic_size);
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// success!
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int check_intr_schedule (
76153bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	struct ehci_hcd		*ehci,
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		frame,
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		uframe,
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const struct ehci_qh	*qh,
7656dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	__hc32			*c_maskp
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
76853bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	int		retval = -ENOSPC;
769ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	u8		mask = 0;
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!check_period (ehci, frame, uframe, qh->period, qh->usecs))
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!qh->c_usecs) {
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = 0;
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*c_maskp = 0;
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
782ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
783ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	if (tt_available (ehci, qh->period, qh->dev, frame, uframe,
784ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				qh->tt_usecs)) {
785ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		unsigned i;
786ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
787ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		/* TODO : this may need FSTN for SSPLIT in uframe 5. */
788ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		for (i=uframe+1; i<8 && i<uframe+4; i++)
789ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			if (!check_period (ehci, frame, i,
790ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman						qh->period, qh->c_usecs))
791ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				goto done;
792ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			else
793ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				mask |= 1 << i;
794ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
795ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		retval = 0;
796ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman
7976dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		*c_maskp = cpu_to_hc32(ehci, mask << 8);
798ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman	}
799ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#else
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Make sure this tt's buffer is also available for CSPLITs.
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We pessimize a bit; probably the typical full speed case
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * doesn't need the second CSPLIT.
80353bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	 *
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * NOTE:  both SPLIT and CSPLIT could be checked in just
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * one smart pass...
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mask = 0x03 << (uframe + qh->gap_uf);
8086dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	*c_maskp = cpu_to_hc32(ehci, mask << 8);
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mask |= 1 << uframe;
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					qh->period, qh->c_usecs))
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!check_period (ehci, frame, uframe + qh->gap_uf,
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					qh->period, qh->c_usecs))
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = 0;
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
820ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#endif
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return retval;
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* "first fit" scheduling policy used the first time through,
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or when the previous schedule slot can't be re-used.
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
8286dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roesestatic int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
83053bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	int		status;
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	uframe;
8326dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	__hc32		c_mask;
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
8343807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	struct ehci_qh_hw	*hw = qh->hw;
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	qh_refresh(ehci, qh);
8373807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du	hw->hw_next = EHCI_LIST_END(ehci);
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	frame = qh->start;
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* reuse the previous schedule slots, if we can */
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (frame < qh->period) {
8423807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK);
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = check_intr_schedule (ehci, frame, --uframe,
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				qh, &c_mask);
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uframe = 0;
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c_mask = 0;
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = -ENOSPC;
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* else scan the schedule to find a group of slots such that all
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * uframes have enough periodic bandwidth available.
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status) {
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* "normal" case, uframing flexible except with splits */
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (qh->period) {
85768335e816a92411649955a9903b1f30c388ea322Alan Stern			int		i;
85868335e816a92411649955a9903b1f30c388ea322Alan Stern
85968335e816a92411649955a9903b1f30c388ea322Alan Stern			for (i = qh->period; status && i > 0; --i) {
86068335e816a92411649955a9903b1f30c388ea322Alan Stern				frame = ++ehci->random_frame % qh->period;
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				for (uframe = 0; uframe < 8; uframe++) {
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					status = check_intr_schedule (ehci,
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							frame, uframe, qh,
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							&c_mask);
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (status == 0)
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						break;
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
86868335e816a92411649955a9903b1f30c388ea322Alan Stern			}
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* qh->period == 0 means every uframe */
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			frame = 0;
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (status)
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qh->start = frame;
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* reset S-frame and (maybe) C-frame masks */
8803807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
8813807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		hw->hw_info2 |= qh->period
8826dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			? cpu_to_hc32(ehci, 1 << uframe)
8836dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			: cpu_to_hc32(ehci, QH_SMASK);
8843807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du		hw->hw_info2 |= c_mask;
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "reused qh %p schedule\n", qh);
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* stuff into the periodic schedule */
88953bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	status = qh_link_periodic (ehci, qh);
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return status;
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int intr_submit (
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head	*qtd_list,
89855016f10e31bb15b85d8c500f979dfdceb37d548Al Viro	gfp_t			mem_flags
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds) {
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		epnum;
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_qh		*qh;
903e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	int			status;
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct list_head	empty;
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* get endpoint and transfer/schedule data */
907e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	epnum = urb->ep->desc.bEndpointAddress;
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911541c7d432f76771079e7c295d596ea47cc6a3030Alan Stern	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
9128de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt		status = -ESHUTDOWN;
913e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
9148de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt	}
915e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
916e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	if (unlikely(status))
917e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
9188de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* get qh and force any scheduling errors */
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD (&empty);
921e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv);
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (qh == NULL) {
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = -ENOMEM;
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (qh->qh_state == QH_STATE_IDLE) {
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((status = qh_schedule (ehci, qh)) != 0)
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* then queue the urb's tds to the qh */
932e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv);
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	BUG_ON (qh == NULL);
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ... update usbfs periodic stats */
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
939e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	if (unlikely(status))
940e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
941e9df41c5c5899259541dc928872cad4d07b82076Alan Sterndone_not_linked:
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status)
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qtd_list_free (ehci, urb, qtd_list);
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return status;
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ehci_iso_stream ops work with both ITD and SITD */
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ehci_iso_stream *
95455016f10e31bb15b85d8c500f979dfdceb37d548Al Viroiso_stream_alloc (gfp_t mem_flags)
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream *stream;
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9587b842b6e3704f4b9606ff8a4ffe03579d9addf5ePekka Enberg	stream = kzalloc(sizeof *stream, mem_flags);
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (likely (stream != NULL)) {
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		INIT_LIST_HEAD(&stream->td_list);
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		INIT_LIST_HEAD(&stream->free_list);
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->next_uframe = -1;
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->refcount = 1;
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return stream;
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_stream_init (
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_device	*dev,
9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			pipe,
9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		interval
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static const u8 smask_out [] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f };
9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			buf1;
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		epnum, maxp;
9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			is_input;
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long			bandwidth;
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * this might be a "high bandwidth" highspeed endpoint,
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * as encoded in the ep descriptor's wMaxPacket field
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	epnum = usb_pipeendpoint (pipe);
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	maxp = usb_maxpacket(dev, pipe, !is_input);
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (is_input) {
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf1 = (1 << 11);
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf1 = 0;
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* knows about ITD vs SITD */
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev->speed == USB_SPEED_HIGH) {
9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned multi = hb_mult(maxp);
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->highspeed = 1;
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		maxp = max_packet(maxp);
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf1 |= maxp;
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		maxp *= multi;
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10076dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		stream->buf0 = cpu_to_hc32(ehci, (epnum << 8) | dev->devnum);
10086dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		stream->buf1 = cpu_to_hc32(ehci, buf1);
10096dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		stream->buf2 = cpu_to_hc32(ehci, multi);
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* usbfs wants to report the average usecs per frame tied up
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * when transfers on this endpoint are scheduled ...
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->usecs = HS_USECS_ISO (maxp);
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bandwidth = stream->usecs * 8;
1016372dd6e8ed924e876f3beb598721e813ad7fa323Alan Stern		bandwidth /= interval;
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u32		addr;
1020d0384200f6b608e77fb5ddf7dfae1bf0e42c1c6eDavid Brownell		int		think_time;
1021469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch		int		hs_transfers;
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr = dev->ttport << 24;
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!ehci_is_TDI(ehci)
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				|| (dev->tt->hub !=
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					ehci_to_hcd(ehci)->self.root_hub))
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			addr |= dev->tt->hub->devnum << 16;
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr |= epnum << 8;
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr |= dev->devnum;
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->usecs = HS_USECS_ISO (maxp);
1031d0384200f6b608e77fb5ddf7dfae1bf0e42c1c6eDavid Brownell		think_time = dev->tt ? dev->tt->think_time : 0;
1032d0384200f6b608e77fb5ddf7dfae1bf0e42c1c6eDavid Brownell		stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
1033d0384200f6b608e77fb5ddf7dfae1bf0e42c1c6eDavid Brownell				dev->speed, is_input, 1, maxp));
1034469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch		hs_transfers = max (1u, (maxp + 187) / 188);
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (is_input) {
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			u32	tmp;
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			addr |= 1 << 31;
10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->c_usecs = stream->usecs;
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->usecs = HS_USECS_ISO (1);
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->raw_mask = 1;
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1043469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch			/* c-mask as specified in USB 2.0 11.18.4 3.c */
1044469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch			tmp = (1 << (hs_transfers + 2)) - 1;
1045469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch			stream->raw_mask |= tmp << (8 + 2);
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else
1047469d02293d494d30dba81895cd3d34b0a3a6d51aClemens Ladisch			stream->raw_mask = smask_out [hs_transfers - 1];
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bandwidth = stream->usecs + stream->c_usecs;
1049372dd6e8ed924e876f3beb598721e813ad7fa323Alan Stern		bandwidth /= interval << 3;
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* stream->splits gets created from raw_mask later */
10526dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		stream->address = cpu_to_hc32(ehci, addr);
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->bandwidth = bandwidth;
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->udev = dev;
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->bEndpointAddress = is_input | epnum;
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->interval = interval;
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->maxp = maxp;
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->refcount--;
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* free whenever just a dev->ep reference remains.
10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * not like a QH -- no persistent state (toggle, halt)
10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (stream->refcount == 1) {
10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// BUG_ON (!list_empty(&stream->td_list));
10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (!list_empty (&stream->free_list)) {
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			struct list_head	*entry;
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			entry = stream->free_list.next;
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_del (entry);
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* knows about ITD vs SITD */
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (stream->highspeed) {
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct ehci_itd		*itd;
10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				itd = list_entry (entry, struct ehci_itd,
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						itd_list);
10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				dma_pool_free (ehci->itd_pool, itd,
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						itd->itd_dma);
10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct ehci_sitd	*sitd;
10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				sitd = list_entry (entry, struct ehci_sitd,
10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						sitd_list);
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				dma_pool_free (ehci->sitd_pool, sitd,
10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						sitd->sitd_dma);
10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->bEndpointAddress &= 0x0f;
10999aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		if (stream->ep)
11009aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			stream->ep->hcpriv = NULL;
11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		kfree(stream);
11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline struct ehci_iso_stream *
11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_stream_get (struct ehci_iso_stream *stream)
11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (likely (stream != NULL))
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream->refcount++;
11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return stream;
11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ehci_iso_stream *
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		epnum;
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream;
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_host_endpoint *ep;
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	epnum = usb_pipeendpoint (urb->pipe);
11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (usb_pipein(urb->pipe))
11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ep = urb->dev->ep_in[epnum];
11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ep = urb->dev->ep_out[epnum];
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream = ep->hcpriv;
11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (stream == NULL)) {
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream = iso_stream_alloc(GFP_ATOMIC);
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (likely (stream != NULL)) {
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* dev->ep owns the initial refcount */
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ep->hcpriv = stream;
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->ep = ep;
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			iso_stream_init(ehci, stream, urb->dev, urb->pipe,
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					urb->interval);
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11411082f57abfa26590b60c43f503afb24102a37016Clemens Ladisch	/* if dev->ep [epnum] is a QH, hw is set */
11421082f57abfa26590b60c43f503afb24102a37016Clemens Ladisch	} else if (unlikely (stream->hw != NULL)) {
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			urb->dev->devpath, epnum,
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			usb_pipein(urb->pipe) ? "in" : "out");
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream = NULL;
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* caller guarantees an eventual matching iso_stream_put */
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream = iso_stream_get (stream);
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return stream;
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ehci_iso_sched ops can be ITD-only or SITD-only */
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ehci_iso_sched *
116155016f10e31bb15b85d8c500f979dfdceb37d548Al Viroiso_sched_alloc (unsigned packets, gfp_t mem_flags)
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched;
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			size = sizeof *iso_sched;
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	size += packets * sizeof (struct ehci_iso_packet);
116780b6ca48321974a6566a1c9048ba34f60420bca6Eric Sesterhenn	iso_sched = kzalloc(size, mem_flags);
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (likely (iso_sched != NULL)) {
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		INIT_LIST_HEAD (&iso_sched->td_list);
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return iso_sched;
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
11756dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roeseitd_sched_init(
11766dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	struct ehci_hcd		*ehci,
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched,
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	i;
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dma_addr_t	dma = urb->transfer_dma;
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* how many uframes are needed for these transfers */
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_sched->span = urb->number_of_packets * stream->interval;
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* figure out per-uframe itd fields that we'll need later
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * when we fit new itds into the schedule.
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < urb->number_of_packets; i++) {
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ehci_iso_packet	*uframe = &iso_sched->packet [i];
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned		length;
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dma_addr_t		buf;
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u32			trans;
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		length = urb->iso_frame_desc [i].length;
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf = dma + urb->iso_frame_desc [i].offset;
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		trans = EHCI_ISOC_ACTIVE;
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		trans |= buf & 0x0fff;
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (unlikely (((i + 1) == urb->number_of_packets))
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			trans |= EHCI_ITD_IOC;
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		trans |= length << 16;
12066dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		uframe->transaction = cpu_to_hc32(ehci, trans);
12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
120877078570abe0848c3076b4f7d42f79b1407f3e8fDavid Brownell		/* might need to cross a buffer page within a uframe */
12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uframe->bufp = (buf & ~(u64)0x0fff);
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf += length;
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			uframe->cross = 1;
12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_sched_free (
12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched
12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!iso_sched)
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// caller must hold ehci->lock!
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	list_splice (&iso_sched->td_list, &stream->free_list);
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree (iso_sched);
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsitd_urb_transaction (
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
123455016f10e31bb15b85d8c500f979dfdceb37d548Al Viro	gfp_t			mem_flags
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_itd		*itd;
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dma_addr_t		itd_dma;
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			i;
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		num_itds;
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*sched;
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (sched == NULL))
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12486dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd_sched_init(ehci, sched, stream, urb);
12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (urb->interval < 8)
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		num_itds = 1 + (sched->span + 7) / 8;
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		num_itds = urb->number_of_packets;
12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* allocate/init ITDs */
12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < num_itds; i++) {
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* free_list.next might be cache-hot ... but maybe
12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * the HC caches it too. avoid that issue for now.
12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* prefer previously-allocated itds */
12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (likely (!list_empty(&stream->free_list))) {
12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd = list_entry (stream->free_list.prev,
12666dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					struct ehci_itd, itd_list);
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_del (&itd->itd_list);
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd_dma = itd->itd_dma;
12693d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese		} else {
12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			spin_unlock_irqrestore (&ehci->lock, flags);
12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&itd_dma);
12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			spin_lock_irqsave (&ehci->lock, flags);
12743d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese			if (!itd) {
12753d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				iso_sched_free(stream, sched);
12763d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				spin_unlock_irqrestore(&ehci->lock, flags);
12773d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				return -ENOMEM;
12783d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese			}
12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset (itd, 0, sizeof *itd);
12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		itd->itd_dma = itd_dma;
12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_add (&itd->itd_list, &sched->td_list);
12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* temporarily store schedule info in hcpriv */
12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->hcpriv = sched;
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->error_count = 0;
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int
12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsitd_slot_ok (
12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			mod,
12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			uframe,
13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8			usecs,
13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			period
13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	uframe %= period;
13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
1306cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov		/* can't commit more than uframe_periodic_max usec */
13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7)
1308cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov				> (ehci->uframe_periodic_max - usecs))
13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* we know urb->interval is 2^N uframes */
13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uframe += period;
13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (uframe < mod);
13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int
13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssitd_slot_ok (
13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			mod,
13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			uframe,
13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*sched,
13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			period_uframes
13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			mask, tmp;
13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32			frame, uf;
13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mask = stream->raw_mask << (uframe & 7);
13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* for IN, don't wrap CSPLIT into the next frame */
13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mask & ~0xffff)
13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* this multi-pass logic is simple, but performance may
13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * suffer when the schedule data isn't cached.
13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* check bandwidth */
13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	uframe %= period_uframes;
13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u32		max_used;
13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame = uframe >> 3;
13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uf = uframe & 7;
13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1348ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
1349ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		/* The tt's fullspeed bus bandwidth must be available.
1350ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 * tt_available scheduling guarantees 10+% for control/bulk.
1351ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		 */
1352ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman		if (!tt_available (ehci, period_uframes << 3,
1353ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman				stream->udev, frame, uf, stream->tt_usecs))
1354ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman			return 0;
1355ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#else
13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* tt must be idle for start(s), any gap, and csplit.
13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * assume scheduling slop leaves 10+% for control/bulk.
13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!tt_no_collision (ehci, period_uframes << 3,
13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				stream->udev, frame, mask))
13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
1362ba47f66bd9fc451e9ce88f291e057b2f4910d01cDan Streetman#endif
13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* check starts (OUT uses more than one) */
1365cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov		max_used = ehci->uframe_periodic_max - stream->usecs;
13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) {
13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (periodic_usecs (ehci, frame, uf) > max_used)
13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 0;
13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* for IN, check CSPLIT */
13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (stream->c_usecs) {
13730c7346229c48fa899a1837d9200894701ea81dacClemens Ladisch			uf = uframe & 7;
1374cc62a7eb6396e8be95b9a30053ed09191818b99bKirill Smelkov			max_used = ehci->uframe_periodic_max - stream->c_usecs;
13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			do {
13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				tmp = 1 << uf;
13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				tmp <<= 8;
13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ((stream->raw_mask & tmp) == 0)
13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					continue;
13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (periodic_usecs (ehci, frame, uf)
13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						> max_used)
13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return 0;
13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} while (++uf < 8);
13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* we know urb->interval is 2^N uframes */
13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uframe += period_uframes;
13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (uframe < mod);
13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13906dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	stream->splits = cpu_to_hc32(ehci, stream->raw_mask << (uframe & 7));
13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This scheduler plans almost as far into the future as it has actual
13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "as small as possible" to be cache-friendlier.)  That limits the size
13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * transfers you can stream reliably; avoid more than 64 msec per urb.
13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Also avoid queue depths of less than ehci's worst irq latency (affected
14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and other factors); or more than about 230 msec total (for portability,
14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * given EHCI_TUNE_FLS and the slop).  Or, write a smarter scheduler!
14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1405d7e055f1975cac560427c924d2bff4b5d41fe442Sarah Sharp#define SCHEDULE_SLOP	80	/* microframes */
14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiso_stream_schedule (
14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream
14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1414ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	u32			now, next, start, period, span;
14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			status;
14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		mod = ehci->periodic_size << 3;
14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*sched = urb->hcpriv;
14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1419ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	period = urb->interval;
1420ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	span = sched->span;
1421ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	if (!stream->highspeed) {
1422ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern		period <<= 3;
1423ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern		span <<= 3;
1424ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	}
1425ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern
1426ffda080353979273e8aa69fc1e6134f20643ae56Alan Stern	if (span > mod - SCHEDULE_SLOP) {
14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "iso request %p too long\n", urb);
14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = -EFBIG;
14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto fail;
14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
143268aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern	now = ehci_read_frame_index(ehci) & (mod - 1);
14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1434b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	/* Typical case: reuse current schedule, stream is still active.
1435b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	 * Hopefully there are no gaps from the host falling behind
1436b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	 * (irq delays etc), but if there are we'll take the next
1437b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (likely (!list_empty (&stream->td_list))) {
14401fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		u32	excess;
1441dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp
1442dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp		/* For high speed devices, allow scheduling within the
1443ae68a83bdc1971cb02fefc7a686ba6d077065e71Alan Stern		 * isochronous scheduling threshold.  For full speed devices
1444ae68a83bdc1971cb02fefc7a686ba6d077065e71Alan Stern		 * and Intel PCI-based controllers, don't (work around for
1445ae68a83bdc1971cb02fefc7a686ba6d077065e71Alan Stern		 * Intel ICH9 bug).
1446dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp		 */
1447ae68a83bdc1971cb02fefc7a686ba6d077065e71Alan Stern		if (!stream->highspeed && ehci->fs_i_thresh)
1448dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp			next = now + ehci->i_thresh;
1449dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp		else
1450dccd574cccad950d9ed9bc192eae4089c6044d9dSarah Sharp			next = now;
1451b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern
14521fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		/* Fell behind (by up to twice the slop amount)?
14531fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		 * We decide based on the time of the last currently-scheduled
14541fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		 * slot, not the time of the next available slot.
14551fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		 */
14561fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		excess = (stream->next_uframe - period - next) & (mod - 1);
14571fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		if (excess >= mod - 2 * SCHEDULE_SLOP)
14581fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			start = next + excess - mod + period *
14591fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern					DIV_ROUND_UP(mod - excess, period);
14601fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		else
14611fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			start = next + excess + period;
14621fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		if (start - now >= mod) {
14631fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
14641fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern					urb, start - now - period, period,
14651fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern					mod);
1466b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern			status = -EFBIG;
1467b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern			goto fail;
1468b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern		}
14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* need to schedule; when's the next (u)frame we could start?
14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * this is bigger than ehci->i_thresh allows; scheduling itself
14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * isn't free, the slop should handle reasonably slow cpus.  it
14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * can also help high bandwidth if the dma and irq loads don't
14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * jump until after the queue is primed.
14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14771fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	else {
1478e3420901eba65b1c46bed86d360e3a8685d20734Matthieu CASTET		int done = 0;
14791fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		start = SCHEDULE_SLOP + (now & ~0x07);
14801fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern
14811fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
14821fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern
1483811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		/* find a uframe slot with enough bandwidth.
1484811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		 * Early uframes are more precious because full-speed
1485811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		 * iso IN transfers can't use late uframes,
1486811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		 * and therefore they should be allocated last.
1487811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		 */
1488811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		next = start;
1489811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		start += period;
1490811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin		do {
1491811c926c538f7e8d3c08b630dd5844efd7e000f6Thomas Poussevin			start--;
14921fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			/* check schedule: enough space? */
14931fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			if (stream->highspeed) {
14941fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				if (itd_slot_ok(ehci, mod, start,
14951fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern						stream->usecs, period))
1496e3420901eba65b1c46bed86d360e3a8685d20734Matthieu CASTET					done = 1;
14971fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			} else {
14981fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				if ((start % 8) >= 6)
14991fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern					continue;
15001fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				if (sitd_slot_ok(ehci, mod, stream,
15011fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern						start, sched, period))
1502e3420901eba65b1c46bed86d360e3a8685d20734Matthieu CASTET					done = 1;
15031fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			}
1504e3420901eba65b1c46bed86d360e3a8685d20734Matthieu CASTET		} while (start > next && !done);
15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15061fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		/* no room in the schedule */
1507e3420901eba65b1c46bed86d360e3a8685d20734Matthieu CASTET		if (!done) {
15081fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
15091fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				urb, now, now + mod);
15101fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			status = -ENOSPC;
15111fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern			goto fail;
15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15151fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	/* Tried to schedule too far into the future? */
15161fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	if (unlikely(start - now + span - period
15171fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				>= mod - 2 * SCHEDULE_SLOP)) {
15181fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
15191fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				urb, start - now, span - period,
15201fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern				mod - 2 * SCHEDULE_SLOP);
15211fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		status = -EFBIG;
15221fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern		goto fail;
15231fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	}
15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15251fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	stream->next_uframe = start & (mod - 1);
15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* report high speed start in uframes; full speed, in frames */
15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->start_frame = stream->next_uframe;
15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!stream->highspeed)
15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb->start_frame >>= 3;
15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
15321fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern
15331fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern fail:
15341fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	iso_sched_free(stream, sched);
15351fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	urb->hcpriv = NULL;
15361fb2e0558781b07d2ecaabf94c81c17ac820d8f0Alan Stern	return status;
15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
15426dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roeseitd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream,
15436dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		struct ehci_itd *itd)
15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
154777078570abe0848c3076b4f7d42f79b1407f3e8fDavid Brownell	/* it's been recently zeroed */
15486dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd->hw_next = EHCI_LIST_END(ehci);
15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	itd->hw_bufp [0] = stream->buf0;
15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	itd->hw_bufp [1] = stream->buf1;
15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	itd->hw_bufp [2] = stream->buf2;
15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < 8; i++)
15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		itd->index[i] = -1;
15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* All other fields are filled when scheduling */
15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
15606dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roeseitd_patch(
15616dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	struct ehci_hcd		*ehci,
15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_itd		*itd,
15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched,
15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		index,
156577078570abe0848c3076b4f7d42f79b1407f3e8fDavid Brownell	u16			uframe
15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_packet	*uf = &iso_sched->packet [index];
15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		pg = itd->pg;
15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	// BUG_ON (pg == 6 && uf->cross);
15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	uframe &= 0x07;
15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	itd->index [uframe] = index;
15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15766dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd->hw_transaction[uframe] = uf->transaction;
15776dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12);
15786dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd->hw_bufp[pg] |= cpu_to_hc32(ehci, uf->bufp & ~(u32)0);
15796dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(uf->bufp >> 32));
15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* iso_frame_desc[].offset must be strictly increasing */
158277078570abe0848c3076b4f7d42f79b1407f3e8fDavid Brownell	if (unlikely (uf->cross)) {
15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u64	bufp = uf->bufp + 4096;
15846dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese
15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		itd->pg = ++pg;
15866dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		itd->hw_bufp[pg] |= cpu_to_hc32(ehci, bufp & ~(u32)0);
15876dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(bufp >> 32));
15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
159492bc3648e6027384479852b770a542722fadee7cClemens Ladisch	union ehci_shadow	*prev = &ehci->pshadow[frame];
159592bc3648e6027384479852b770a542722fadee7cClemens Ladisch	__hc32			*hw_p = &ehci->periodic[frame];
159692bc3648e6027384479852b770a542722fadee7cClemens Ladisch	union ehci_shadow	here = *prev;
159792bc3648e6027384479852b770a542722fadee7cClemens Ladisch	__hc32			type = 0;
159892bc3648e6027384479852b770a542722fadee7cClemens Ladisch
159992bc3648e6027384479852b770a542722fadee7cClemens Ladisch	/* skip any iso nodes which might belong to previous microframes */
160092bc3648e6027384479852b770a542722fadee7cClemens Ladisch	while (here.ptr) {
160192bc3648e6027384479852b770a542722fadee7cClemens Ladisch		type = Q_NEXT_TYPE(ehci, *hw_p);
160292bc3648e6027384479852b770a542722fadee7cClemens Ladisch		if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
160392bc3648e6027384479852b770a542722fadee7cClemens Ladisch			break;
160492bc3648e6027384479852b770a542722fadee7cClemens Ladisch		prev = periodic_next_shadow(ehci, prev, type);
160592bc3648e6027384479852b770a542722fadee7cClemens Ladisch		hw_p = shadow_next_periodic(ehci, &here, type);
160692bc3648e6027384479852b770a542722fadee7cClemens Ladisch		here = *prev;
160792bc3648e6027384479852b770a542722fadee7cClemens Ladisch	}
160892bc3648e6027384479852b770a542722fadee7cClemens Ladisch
160992bc3648e6027384479852b770a542722fadee7cClemens Ladisch	itd->itd_next = here;
161092bc3648e6027384479852b770a542722fadee7cClemens Ladisch	itd->hw_next = *hw_p;
161192bc3648e6027384479852b770a542722fadee7cClemens Ladisch	prev->itd = itd;
16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	itd->frame = frame;
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	wmb ();
161492bc3648e6027384479852b770a542722fadee7cClemens Ladisch	*hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fit urb's itds into the selected schedule slot; activate as needed */
16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsitd_link_urb (
16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		mod,
16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream
16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
162677078570abe0848c3076b4f7d42f79b1407f3e8fDavid Brownell	int			packet;
16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		next_uframe, uframe, frame;
16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched = urb->hcpriv;
16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_itd		*itd;
16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern	next_uframe = stream->next_uframe & (mod - 1);
16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (list_empty(&stream->td_list))) {
16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_to_hcd(ehci)->self.bandwidth_allocated
16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				+= stream->bandwidth;
16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_vdbg (ehci,
16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			urb->interval,
16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			next_uframe >> 3, next_uframe & 0x7);
16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
164305570297ecbe834b1756b522412b68eaffb9ab11Alex He
164405570297ecbe834b1756b522412b68eaffb9ab11Alex He	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1645ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu		if (ehci->amd_pll_fix == 1)
1646ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu			usb_amd_quirk_pll_disable();
164705570297ecbe834b1756b522412b68eaffb9ab11Alex He	}
164805570297ecbe834b1756b522412b68eaffb9ab11Alex He
16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* fill iTDs uframe by uframe */
16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (itd == NULL) {
16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* ASSERT:  we have all necessary itds */
16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			// BUG_ON (list_empty (&iso_sched->td_list));
16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* ASSERT:  no itds for this endpoint in this uframe */
16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd = list_entry (iso_sched->td_list.next,
16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					struct ehci_itd, itd_list);
16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_move_tail (&itd->itd_list, &stream->td_list);
16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd->stream = iso_stream_get (stream);
1663508db8c954d55ed30f870d2c24d741ba6269d13cKarsten Wiese			itd->urb = urb;
16646dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			itd_init (ehci, stream, itd);
16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		uframe = next_uframe & 0x07;
16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame = next_uframe >> 3;
16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16706dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		itd_patch(ehci, itd, iso_sched, packet, uframe);
16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		next_uframe += stream->interval;
1673bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern		next_uframe &= mod - 1;
16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		packet++;
16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* link completed itds into the schedule */
16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (((next_uframe >> 3) != frame)
16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				|| packet == urb->number_of_packets) {
1679bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern			itd_link(ehci, frame & (ehci->periodic_size - 1), itd);
16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			itd = NULL;
16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream->next_uframe = next_uframe;
16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* don't need that schedule data any more */
16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_sched_free (stream, iso_sched);
16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->hcpriv = NULL;
16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	timer_action (ehci, TIMER_IO_WATCHDOG);
169001c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	return enable_periodic(ehci);
16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
169530bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell/* Process and recycle a completed ITD.  Return true iff its urb completed,
169630bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * and hence its completion callback probably added things to the hardware
169730bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * schedule.
169830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell *
169930bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * Note that we carefully avoid recycling this descriptor until after any
170030bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * completion callback runs, so that it won't be reused quickly.  That is,
170130bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * assuming (a) no more than two urbs per frame on this endpoint, and also
170230bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * (b) only this endpoint's completions submit URBs.  It seems some silicon
170330bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * corrupts things if you reuse completed descriptors very quickly...
170430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell */
17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned
17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsitd_complete (
17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd	*ehci,
17087d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells	struct ehci_itd	*itd
17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds) {
17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb				*urb = itd->urb;
17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_iso_packet_descriptor	*desc;
17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32					t;
17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned				uframe;
17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int					urb_index = -1;
17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream			*stream = itd->stream;
17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_device			*dev;
171730bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	unsigned				retval = false;
17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* for each uframe with a packet */
17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (uframe = 0; uframe < 8; uframe++) {
17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (likely (itd->index[uframe] == -1))
17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb_index = itd->index[uframe];
17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		desc = &urb->iso_frame_desc [urb_index];
17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17266dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		itd->hw_transaction [uframe] = 0;
17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* report transfer status */
17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (unlikely (t & ISO_ERRS)) {
17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			urb->error_count++;
17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (t & EHCI_ISOC_BUF_ERR)
17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				desc->status = usb_pipein (urb->pipe)
17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					? -ENOSR  /* hc couldn't read */
17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					: -ECOMM; /* hc couldn't write */
17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (t & EHCI_ISOC_BABBLE)
17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				desc->status = -EOVERFLOW;
17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else /* (t & EHCI_ISOC_XACTERR) */
17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				desc->status = -EPROTO;
17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* HC need not update length with this error */
1742ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern			if (!(t & EHCI_ISOC_BABBLE)) {
1743ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern				desc->actual_length = EHCI_ITD_LENGTH(t);
1744ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern				urb->actual_length += desc->actual_length;
1745ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern			}
17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			desc->status = 0;
1748ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern			desc->actual_length = EHCI_ITD_LENGTH(t);
1749ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern			urb->actual_length += desc->actual_length;
1750b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern		} else {
1751b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern			/* URB was too late */
1752b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern			desc->status = -EXDEV;
17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* handle completion now? */
17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (likely ((urb_index + 1) != urb->number_of_packets))
175830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell		goto done;
17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ASSERT: it's really the last itd for this urb
17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	list_for_each_entry (itd, &stream->td_list, itd_list)
17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BUG_ON (itd->urb == urb);
17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1765aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell	/* give urb back to the driver; completion often (re)submits */
17666a8e87b23ff4a979bde5451a242466a4b3f9fe7dAlan Stern	dev = urb->dev;
176714c04c0f88f228fee1f412be91d6edcb935c78aaAlan Stern	ehci_urb_done(ehci, urb, 0);
176830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	retval = true;
17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb = NULL;
177001c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	(void) disable_periodic(ehci);
17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
177305570297ecbe834b1756b522412b68eaffb9ab11Alex He	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1774ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu		if (ehci->amd_pll_fix == 1)
1775ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu			usb_amd_quirk_pll_enable();
177605570297ecbe834b1756b522412b68eaffb9ab11Alex He	}
177705570297ecbe834b1756b522412b68eaffb9ab11Alex He
1778508db8c954d55ed30f870d2c24d741ba6269d13cKarsten Wiese	if (unlikely(list_is_singular(&stream->td_list))) {
17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_to_hcd(ehci)->self.bandwidth_allocated
17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				-= stream->bandwidth;
17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_vdbg (ehci,
17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"deschedule devp %s ep%d%s-iso\n",
17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dev->devpath, stream->bEndpointAddress & 0x0f,
17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_stream_put (ehci, stream);
17879aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese
178830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownelldone:
178930bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	itd->urb = NULL;
17909aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
17919aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		/* OK to recycle this ITD now. */
17929aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		itd->stream = NULL;
17939aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		list_move(&itd->itd_list, &stream->free_list);
17949aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		iso_stream_put(ehci, stream);
17959aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	} else {
17969aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		/* HW might remember this ITD, so we can't recycle it yet.
17979aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		 * Move it to a safe place until a new frame starts.
17989aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		 */
17999aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		list_move(&itd->itd_list, &ehci->cached_itd_list);
18009aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		if (stream->refcount == 2) {
18019aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			/* If iso_stream_put() were called here, stream
18029aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			 * would be freed.  Instead, just prevent reuse.
18039aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			 */
18049aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			stream->ep->hcpriv = NULL;
18059aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			stream->ep = NULL;
18069aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		}
18079aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	}
180830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	return retval;
18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18135db539e49fc7471e23bf3c94ca304f008cb7b7f3Olav Kongasstatic int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
181455016f10e31bb15b85d8c500f979dfdceb37d548Al Viro	gfp_t mem_flags)
18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			status = -EINVAL;
18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream;
18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Get iso_stream head */
18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream = iso_stream_find (ehci, urb);
18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (stream == NULL)) {
18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't get iso stream\n");
18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (urb->interval != stream->interval)) {
18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->interval, urb->interval);
18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef EHCI_URB_TRACE
18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_dbg (ehci,
18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
1835441b62c1edb986827154768d89bbac0ba779984fHarvey Harrison		__func__, urb->dev->devpath, urb,
18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		usb_pipeendpoint (urb->pipe),
18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		usb_pipein (urb->pipe) ? "in" : "out",
18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb->transfer_buffer_length,
18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb->number_of_packets, urb->interval,
18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stream);
18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* allocate ITDs w/o locking anything */
18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = itd_urb_transaction (stream, ehci, urb, mem_flags);
18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (status < 0)) {
18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't init itds\n");
18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* schedule ... need to lock */
18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
1852541c7d432f76771079e7c295d596ea47cc6a3030Alan Stern	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
18538de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt		status = -ESHUTDOWN;
1854e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
1855e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	}
1856e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
1857e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	if (unlikely(status))
1858e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
1859e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	status = iso_stream_schedule(ehci, urb, stream);
186053bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	if (likely (status == 0))
18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
1862e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	else
1863e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
1864e9df41c5c5899259541dc928872cad4d07b82076Alan Sterndone_not_linked:
18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely (status < 0))
18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iso_stream_put (ehci, stream);
18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return status;
18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "Split ISO TDs" ... used for USB 1.1 devices going through the
18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TTs in USB 2.0 hubs.  These need microframe scheduling.
18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
18816dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roesesitd_sched_init(
18826dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	struct ehci_hcd		*ehci,
18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched,
18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb
18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	i;
18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dma_addr_t	dma = urb->transfer_dma;
18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* how many frames are needed for these transfers */
18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_sched->span = urb->number_of_packets * stream->interval;
18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* figure out per-frame sitd fields that we'll need later
18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * when we fit new sitds into the schedule.
18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < urb->number_of_packets; i++) {
18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ehci_iso_packet	*packet = &iso_sched->packet [i];
18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned		length;
19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dma_addr_t		buf;
19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u32			trans;
19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		length = urb->iso_frame_desc [i].length & 0x03ff;
19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf = dma + urb->iso_frame_desc [i].offset;
19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		trans = SITD_STS_ACTIVE;
19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (((i + 1) == urb->number_of_packets)
19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			trans |= SITD_IOC;
19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		trans |= length << 16;
19116dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		packet->transaction = cpu_to_hc32(ehci, trans);
19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* might need to cross a buffer page within a td */
19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		packet->bufp = buf;
19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		packet->buf1 = (buf + length) & ~0x0fff;
19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (packet->buf1 != (buf & ~(u64)0x0fff))
19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			packet->cross = 1;
19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191953bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell		/* OUT uses multiple start-splits */
19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (stream->bEndpointAddress & USB_DIR_IN)
19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		length = (length + 187) / 188;
19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (length > 1) /* BEGIN vs ALL */
19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			length |= 1 << 3;
19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		packet->buf1 |= length;
19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssitd_urb_transaction (
19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
193455016f10e31bb15b85d8c500f979dfdceb37d548Al Viro	gfp_t			mem_flags
19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_sitd	*sitd;
19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dma_addr_t		sitd_dma;
19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			i;
19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched;
19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (iso_sched == NULL)
19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19476dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd_sched_init(ehci, iso_sched, stream, urb);
19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* allocate/init sITDs */
19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < urb->number_of_packets; i++) {
19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* NOTE:  for now, we don't try to handle wraparound cases
19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * for IN (using sitd->hw_backpointer, like a FSTN), which
19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * means we never need two sitds for full speed packets.
19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* free_list.next might be cache-hot ... but maybe
19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * the HC caches it too. avoid that issue for now.
19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* prefer previously-allocated sitds */
19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!list_empty(&stream->free_list)) {
19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sitd = list_entry (stream->free_list.prev,
19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 struct ehci_sitd, sitd_list);
19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			list_del (&sitd->sitd_list);
19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sitd_dma = sitd->sitd_dma;
19683d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese		} else {
19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			spin_unlock_irqrestore (&ehci->lock, flags);
19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags,
19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&sitd_dma);
19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			spin_lock_irqsave (&ehci->lock, flags);
19733d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese			if (!sitd) {
19743d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				iso_sched_free(stream, iso_sched);
19753d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				spin_unlock_irqrestore(&ehci->lock, flags);
19763d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese				return -ENOMEM;
19773d01f0fe6b66dd34511eaf35e06764b8997187bcKarsten Wiese			}
19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset (sitd, 0, sizeof *sitd);
19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sitd->sitd_dma = sitd_dma;
19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_add (&sitd->sitd_list, &iso_sched->td_list);
19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* temporarily store schedule info in hcpriv */
19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->hcpriv = iso_sched;
19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->error_count = 0;
19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
19966dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roesesitd_patch(
19976dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	struct ehci_hcd		*ehci,
19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream,
19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_sitd	*sitd,
20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*iso_sched,
20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		index
20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_packet	*uf = &iso_sched->packet [index];
20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u64			bufp = uf->bufp;
20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20076dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_next = EHCI_LIST_END(ehci);
20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->hw_fullspeed_ep = stream->address;
20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->hw_uframe = stream->splits;
20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->hw_results = uf->transaction;
20116dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_backpointer = EHCI_LIST_END(ehci);
20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bufp = uf->bufp;
20146dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_buf[0] = cpu_to_hc32(ehci, bufp);
20156dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_buf_hi[0] = cpu_to_hc32(ehci, bufp >> 32);
20161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20176dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_buf[1] = cpu_to_hc32(ehci, uf->buf1);
20181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (uf->cross)
20191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bufp += 4096;
20206dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	sitd->hw_buf_hi[1] = cpu_to_hc32(ehci, bufp >> 32);
20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->index = index;
20221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
20231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* note: sitd ordering could matter (CSPLIT then SSPLIT) */
20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->sitd_next = ehci->pshadow [frame];
20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->hw_next = ehci->periodic [frame];
20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci->pshadow [frame].sitd = sitd;
20311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sitd->frame = frame;
20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	wmb ();
20336dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	ehci->periodic[frame] = cpu_to_hc32(ehci, sitd->sitd_dma | Q_TYPE_SITD);
20341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* fit urb's sitds into the selected schedule slot; activate as needed */
20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssitd_link_urb (
20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb		*urb,
20411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		mod,
20421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream
20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds)
20441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			packet;
20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned		next_uframe;
20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_sched	*sched = urb->hcpriv;
20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_sitd	*sitd;
20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	next_uframe = stream->next_uframe;
20511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty(&stream->td_list)) {
20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* usbfs ignores TT bandwidth */
20541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_to_hcd(ehci)->self.bandwidth_allocated
20551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				+= stream->bandwidth;
20561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_vdbg (ehci,
20571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"sched devp %s ep%d%s-iso [%d] %dms/%04x\n",
20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
2060bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern			(next_uframe >> 3) & (ehci->periodic_size - 1),
20616dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			stream->interval, hc32_to_cpu(ehci, stream->splits));
20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
206305570297ecbe834b1756b522412b68eaffb9ab11Alex He
206405570297ecbe834b1756b522412b68eaffb9ab11Alex He	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2065ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu		if (ehci->amd_pll_fix == 1)
2066ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu			usb_amd_quirk_pll_disable();
206705570297ecbe834b1756b522412b68eaffb9ab11Alex He	}
206805570297ecbe834b1756b522412b68eaffb9ab11Alex He
20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
20701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* fill sITDs frame by frame */
20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (packet = 0, sitd = NULL;
20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			packet < urb->number_of_packets;
20741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			packet++) {
20751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* ASSERT:  we have all necessary sitds */
20771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BUG_ON (list_empty (&sched->td_list));
20781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* ASSERT:  no itds for this endpoint in this frame */
20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sitd = list_entry (sched->td_list.next,
20821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				struct ehci_sitd, sitd_list);
20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		list_move_tail (&sitd->sitd_list, &stream->td_list);
20841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sitd->stream = iso_stream_get (stream);
2085508db8c954d55ed30f870d2c24d741ba6269d13cKarsten Wiese		sitd->urb = urb;
20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20876dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		sitd_patch(ehci, stream, sitd, sched, packet);
2088bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern		sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),
20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				sitd);
20901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		next_uframe += stream->interval << 3;
20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2093bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern	stream->next_uframe = next_uframe & (mod - 1);
20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* don't need that schedule data any more */
20961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_sched_free (stream, sched);
20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb->hcpriv = NULL;
20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	timer_action (ehci, TIMER_IO_WATCHDOG);
210001c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	return enable_periodic(ehci);
21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
21021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
21041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define	SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \
210653bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell				| SITD_STS_XACT | SITD_STS_MMF)
21071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
210830bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell/* Process and recycle a completed SITD.  Return true iff its urb completed,
210930bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * and hence its completion callback probably added things to the hardware
211030bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * schedule.
211130bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell *
211230bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * Note that we carefully avoid recycling this descriptor until after any
211330bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * completion callback runs, so that it won't be reused quickly.  That is,
211430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * assuming (a) no more than two urbs per frame on this endpoint, and also
211530bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * (b) only this endpoint's completions submit URBs.  It seems some silicon
211630bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell * corrupts things if you reuse completed descriptors very quickly...
211730bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell */
21181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned
21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssitd_complete (
21201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_hcd		*ehci,
21217d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells	struct ehci_sitd	*sitd
21221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds) {
21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct urb				*urb = sitd->urb;
21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_iso_packet_descriptor	*desc;
21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32					t;
21261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int					urb_index = -1;
21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream			*stream = sitd->stream;
21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct usb_device			*dev;
212930bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	unsigned				retval = false;
21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb_index = sitd->index;
21321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	desc = &urb->iso_frame_desc [urb_index];
21336dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese	t = hc32_to_cpup(ehci, &sitd->hw_results);
21341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* report transfer status */
21361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (t & SITD_ERRS) {
21371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb->error_count++;
21381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (t & SITD_STS_DBE)
21391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			desc->status = usb_pipein (urb->pipe)
21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				? -ENOSR  /* hc couldn't read */
21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				: -ECOMM; /* hc couldn't write */
21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else if (t & SITD_STS_BABBLE)
21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			desc->status = -EOVERFLOW;
21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else /* XACT, MMF, etc */
21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			desc->status = -EPROTO;
21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		desc->status = 0;
2148ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern		desc->actual_length = desc->length - SITD_LENGTH(t);
2149ec6d67e39f5638c792eb7490bf32586ccb9d8005Alan Stern		urb->actual_length += desc->actual_length;
21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* handle completion now? */
21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((urb_index + 1) != urb->number_of_packets)
215430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell		goto done;
21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ASSERT: it's really the last sitd for this urb
21571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	list_for_each_entry (sitd, &stream->td_list, sitd_list)
21581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BUG_ON (sitd->urb == urb);
21591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
21601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2161aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell	/* give urb back to the driver; completion often (re)submits */
21626a8e87b23ff4a979bde5451a242466a4b3f9fe7dAlan Stern	dev = urb->dev;
216314c04c0f88f228fee1f412be91d6edcb935c78aaAlan Stern	ehci_urb_done(ehci, urb, 0);
216430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	retval = true;
21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	urb = NULL;
216601c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell	(void) disable_periodic(ehci);
21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
216905570297ecbe834b1756b522412b68eaffb9ab11Alex He	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2170ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu		if (ehci->amd_pll_fix == 1)
2171ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7Andiry Xu			usb_amd_quirk_pll_enable();
217205570297ecbe834b1756b522412b68eaffb9ab11Alex He	}
217305570297ecbe834b1756b522412b68eaffb9ab11Alex He
2174508db8c954d55ed30f870d2c24d741ba6269d13cKarsten Wiese	if (list_is_singular(&stream->td_list)) {
21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_to_hcd(ehci)->self.bandwidth_allocated
21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				-= stream->bandwidth;
21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_vdbg (ehci,
21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"deschedule devp %s ep%d%s-iso\n",
21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dev->devpath, stream->bEndpointAddress & 0x0f,
21801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
21811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
21821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iso_stream_put (ehci, stream);
21830e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern
218430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownelldone:
218530bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	sitd->urb = NULL;
21860e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	if (ehci->clock_frame != sitd->frame) {
21870e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		/* OK to recycle this SITD now. */
21880e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		sitd->stream = NULL;
21890e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		list_move(&sitd->sitd_list, &stream->free_list);
21900e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		iso_stream_put(ehci, stream);
21910e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	} else {
21920e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		/* HW might remember this SITD, so we can't recycle it yet.
21930e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		 * Move it to a safe place until a new frame starts.
21940e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		 */
21950e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		list_move(&sitd->sitd_list, &ehci->cached_sitd_list);
21960e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		if (stream->refcount == 2) {
21970e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern			/* If iso_stream_put() were called here, stream
21980e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern			 * would be freed.  Instead, just prevent reuse.
21990e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern			 */
22000e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern			stream->ep->hcpriv = NULL;
22010e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern			stream->ep = NULL;
22020e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		}
22030e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	}
220430bf54e62a7926a483b4e36015bb4eb1372e6303David Brownell	return retval;
22051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
22061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22085db539e49fc7471e23bf3c94ca304f008cb7b7f3Olav Kongasstatic int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
220955016f10e31bb15b85d8c500f979dfdceb37d548Al Viro	gfp_t mem_flags)
22101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
22111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int			status = -EINVAL;
22121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		flags;
22131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ehci_iso_stream	*stream;
22141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Get iso_stream head */
22161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stream = iso_stream_find (ehci, urb);
22171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (stream == NULL) {
22181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't get iso stream\n");
22191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
22201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
22211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (urb->interval != stream->interval) {
22221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
22231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stream->interval, urb->interval);
22241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
22251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
22261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef EHCI_URB_TRACE
22281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ehci_dbg (ehci,
22291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"submit %p dev%s ep%d%s-iso len %d\n",
22301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb, urb->dev->devpath,
22311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		usb_pipeendpoint (urb->pipe),
22321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		usb_pipein (urb->pipe) ? "in" : "out",
22331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		urb->transfer_buffer_length);
22341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
22351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* allocate SITDs */
22371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = sitd_urb_transaction (stream, ehci, urb, mem_flags);
22381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status < 0) {
22391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ehci_dbg (ehci, "can't init sitds\n");
22401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
22411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
22421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* schedule ... need to lock */
22441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave (&ehci->lock, flags);
2245541c7d432f76771079e7c295d596ea47cc6a3030Alan Stern	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
22468de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt		status = -ESHUTDOWN;
2247e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
2248e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	}
2249e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
2250e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	if (unlikely(status))
2251e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		goto done_not_linked;
2252e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	status = iso_stream_schedule(ehci, urb, stream);
225353bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	if (status == 0)
22541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
2255e9df41c5c5899259541dc928872cad4d07b82076Alan Stern	else
2256e9df41c5c5899259541dc928872cad4d07b82076Alan Stern		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
2257e9df41c5c5899259541dc928872cad4d07b82076Alan Sterndone_not_linked:
22581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore (&ehci->lock, flags);
22591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
22611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status < 0)
22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iso_stream_put (ehci, stream);
22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return status;
22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/
22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22680e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Sternstatic void free_cached_lists(struct ehci_hcd *ehci)
22699aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese{
22709aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	struct ehci_itd *itd, *n;
22710e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	struct ehci_sitd *sitd, *sn;
22729aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese
22739aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
22749aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		struct ehci_iso_stream	*stream = itd->stream;
22759aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		itd->stream = NULL;
22769aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		list_move(&itd->itd_list, &stream->free_list);
22779aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		iso_stream_put(ehci, stream);
22789aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	}
22790e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern
22800e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) {
22810e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		struct ehci_iso_stream	*stream = sitd->stream;
22820e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		sitd->stream = NULL;
22830e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		list_move(&sitd->sitd_list, &stream->free_list);
22840e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		iso_stream_put(ehci, stream);
22850e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern	}
22869aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese}
22879aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese
22889aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese/*-------------------------------------------------------------------------*/
22899aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese
22901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
22917d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsscan_periodic (struct ehci_hcd *ehci)
22921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2293b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	unsigned	now_uframe, frame, clock, clock_frame, mod;
22941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned	modified;
22951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mod = ehci->periodic_size << 3;
22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
22991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * When running, scan from last scan point up to "now"
23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * else clean up by scanning everything that's left.
23011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Touches as few pages as possible:  cache-friendly.
23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	now_uframe = ehci->next_uframe;
2304e8799906045302776b35b66b16495c575db3b69cAlan Stern	if (ehci->rh_state == EHCI_RH_RUNNING) {
230568aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern		clock = ehci_read_frame_index(ehci);
2306bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern		clock_frame = (clock >> 3) & (ehci->periodic_size - 1);
23079aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	} else  {
23081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		clock = now_uframe + mod - 1;
23099aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		clock_frame = -1;
23109aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	}
23119aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	if (ehci->clock_frame != clock_frame) {
23120e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern		free_cached_lists(ehci);
23139aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese		ehci->clock_frame = clock_frame;
23149aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese	}
2315bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern	clock &= mod - 1;
2316b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern	clock_frame = clock >> 3;
23171e12c910eed82da6971f1c0421a069c680faba2eAlan Stern	++ehci->periodic_stamp;
23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (;;) {
23201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		union ehci_shadow	q, *q_p;
23216dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		__hc32			type, *hw_p;
232279592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		unsigned		incomplete = false;
23231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		frame = now_uframe >> 3;
23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrestart:
23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* scan each element in frame's queue for completions */
23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		q_p = &ehci->pshadow [frame];
23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw_p = &ehci->periodic [frame];
23301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		q.ptr = q_p->ptr;
23316dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese		type = Q_NEXT_TYPE(ehci, *hw_p);
23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		modified = 0;
23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (q.ptr != NULL) {
23351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			unsigned		uf;
23361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			union ehci_shadow	temp;
23371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int			live;
23381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2339e8799906045302776b35b66b16495c575db3b69cAlan Stern			live = (ehci->rh_state == EHCI_RH_RUNNING);
23406dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese			switch (hc32_to_cpu(ehci, type)) {
23411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_QH:
23421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* handle any completions */
23431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				temp.qh = qh_get (q.qh);
23443807e26d69b9ad3864fe03224ebebc9610d5802eAlek Du				type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
23451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				q = q.qh->qh_next;
23461e12c910eed82da6971f1c0421a069c680faba2eAlan Stern				if (temp.qh->stamp != ehci->periodic_stamp) {
23471e12c910eed82da6971f1c0421a069c680faba2eAlan Stern					modified = qh_completions(ehci, temp.qh);
23481e12c910eed82da6971f1c0421a069c680faba2eAlan Stern					if (!modified)
23491e12c910eed82da6971f1c0421a069c680faba2eAlan Stern						temp.qh->stamp = ehci->periodic_stamp;
23501e12c910eed82da6971f1c0421a069c680faba2eAlan Stern					if (unlikely(list_empty(&temp.qh->qtd_list) ||
23511e12c910eed82da6971f1c0421a069c680faba2eAlan Stern							temp.qh->needs_rescan))
23521e12c910eed82da6971f1c0421a069c680faba2eAlan Stern						intr_deschedule(ehci, temp.qh);
23531e12c910eed82da6971f1c0421a069c680faba2eAlan Stern				}
23541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				qh_put (temp.qh);
23551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
23561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_FSTN:
23571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* for "save place" FSTNs, look at QH entries
23581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * in the previous frame for completions.
23591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
23606dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				if (q.fstn->hw_prev != EHCI_LIST_END(ehci)) {
23611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					dbg ("ignoring completions from FSTNs");
23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
23636dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				type = Q_NEXT_TYPE(ehci, q.fstn->hw_next);
23641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				q = q.fstn->fstn_next;
23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_ITD:
236779592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				/* If this ITD is still active, leave it for
236879592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * later processing ... check the next entry.
2369b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern				 * No need to check for activity unless the
2370b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern				 * frame is current.
237179592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 */
2372b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern				if (frame == clock_frame && live) {
2373b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern					rmb();
2374b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern					for (uf = 0; uf < 8; uf++) {
2375b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						if (q.itd->hw_transaction[uf] &
2376b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern							    ITD_ACTIVE(ehci))
2377b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern							break;
2378b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern					}
2379b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern					if (uf < 8) {
2380b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						incomplete = true;
2381b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						q_p = &q.itd->itd_next;
2382b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						hw_p = &q.itd->hw_next;
2383b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						type = Q_NEXT_TYPE(ehci,
23846dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese							q.itd->hw_next);
2385b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						q = *q_p;
2386b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern						break;
2387b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern					}
23881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
23891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
239079592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				/* Take finished ITDs out of the schedule
239179592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * and process them:  recycle, maybe report
239279592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * URB completion.  HC won't cache the
23931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * pointer for much longer, if at all.
23941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
23951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*q_p = q.itd->itd_next;
23963d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				if (!ehci->use_dummy_qh ||
23973d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				    q.itd->hw_next != EHCI_LIST_END(ehci))
23983d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu					*hw_p = q.itd->hw_next;
23993d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				else
24003d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu					*hw_p = ehci->dummy->qh_dma;
24016dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
24021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				wmb();
24037d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells				modified = itd_complete (ehci, q.itd);
24041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				q = *q_p;
24051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
24061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case Q_TYPE_SITD:
240779592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				/* If this SITD is still active, leave it for
240879592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * later processing ... check the next entry.
2409b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern				 * No need to check for activity unless the
2410b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern				 * frame is current.
241179592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 */
241222e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein				if (((frame == clock_frame) ||
2413bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern				     (((frame + 1) & (ehci->periodic_size - 1))
241422e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein				      == clock_frame))
241522e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein				    && live
241622e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein				    && (q.sitd->hw_results &
241722e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein					SITD_ACTIVE(ehci))) {
241822e186948a262c9cd377fb43aa50bb3c3f01c468Dmitri Epshtein
241979592b722e7a8476680197d97352d2cc0f1bffd2David Brownell					incomplete = true;
24201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					q_p = &q.sitd->sitd_next;
24211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					hw_p = &q.sitd->hw_next;
24226dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese					type = Q_NEXT_TYPE(ehci,
24236dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese							q.sitd->hw_next);
24241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					q = *q_p;
24251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break;
24261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
242779592b722e7a8476680197d97352d2cc0f1bffd2David Brownell
242879592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				/* Take finished SITDs out of the schedule
242979592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * and process them:  recycle, maybe report
243079592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 * URB completion.
243179592b722e7a8476680197d97352d2cc0f1bffd2David Brownell				 */
24321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*q_p = q.sitd->sitd_next;
24333d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				if (!ehci->use_dummy_qh ||
24343d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				    q.sitd->hw_next != EHCI_LIST_END(ehci))
24353d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu					*hw_p = q.sitd->hw_next;
24363d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu				else
24373d091a6f703906c5680855ff29bd94d051c8c6d8Andiry Xu					*hw_p = ehci->dummy->qh_dma;
24386dbd682b7c6d58916096616cdf94852641bc09d9Stefan Roese				type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
24391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				wmb();
24407d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells				modified = sitd_complete (ehci, q.sitd);
24411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				q = *q_p;
24421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
24431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
24441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				dbg ("corrupt type %d frame %d shadow %p",
24451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					type, frame, q.ptr);
24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				// BUG ();
24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				q.ptr = NULL;
24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* assume completion callbacks modify the queue */
2451aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell			if (unlikely (modified)) {
2452aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell				if (likely(ehci->periodic_sched > 0))
2453aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell					goto restart;
245401c17142659c02d8cd4c67acdd8358180c5c4fb6David Brownell				/* short-circuit this scan */
2455aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell				now_uframe = clock;
2456aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell				break;
2457aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell			}
24581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
246079592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		/* If we can tell we caught up to the hardware, stop now.
246179592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		 * We can't advance our scan without collecting the ISO
246279592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		 * transfers that are still pending in this frame.
246379592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		 */
2464e8799906045302776b35b66b16495c575db3b69cAlan Stern		if (incomplete && ehci->rh_state == EHCI_RH_RUNNING) {
246579592b722e7a8476680197d97352d2cc0f1bffd2David Brownell			ehci->next_uframe = now_uframe;
246679592b722e7a8476680197d97352d2cc0f1bffd2David Brownell			break;
246779592b722e7a8476680197d97352d2cc0f1bffd2David Brownell		}
24681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// FIXME:  this assumes we won't get lapped when
24701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// latencies climb; that should be rare, but...
24711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// detect it, and just go all the way around.
24721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// FLR might help detect this case, so long as latencies
24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// don't exceed periodic_size msec (default 1.024 sec).
24741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		// FIXME:  likewise assumes HC doesn't halt mid-scan
24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (now_uframe == clock) {
24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			unsigned	now;
24791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2480e8799906045302776b35b66b16495c575db3b69cAlan Stern			if (ehci->rh_state != EHCI_RH_RUNNING
2481aa16ca307ee2da304d3a5fc0fc5e50ef8047c9e9David Brownell					|| ehci->periodic_sched == 0)
24821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
24831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ehci->next_uframe = now_uframe;
248468aa95d5d4de31c9348c1628ffa85c805305ebc5Alan Stern			now = ehci_read_frame_index(ehci) & (mod - 1);
24851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (now_uframe == now)
24861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
24871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* rescan the rest of this frame, then ... */
24891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			clock = now;
2490b40e43fcc532fa44a375a37d592e32cd0d50fe7aAlan Stern			clock_frame = clock >> 3;
24919aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			if (ehci->clock_frame != clock_frame) {
24920e5f231bc16ff9910882fa5b9d64d80e7691cfabAlan Stern				free_cached_lists(ehci);
24939aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese				ehci->clock_frame = clock_frame;
24941e12c910eed82da6971f1c0421a069c680faba2eAlan Stern				++ehci->periodic_stamp;
24959aa09d2f8f4bc440d6db1c3414d4009642875240Karsten Wiese			}
24961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
24971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			now_uframe++;
2498bccbefaae050186bed3bcc74b1fd1a9b8c6710b2Alan Stern			now_uframe &= mod - 1;
24991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
250053bd6a601a87bb6d0df844872bc15fd4e8d127ceDavid Brownell	}
25011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2502