// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2001-2004 by David Brownell
 * Copyright (c) 2003 Michal Sojka, for high-speed iso transfers
 */

/* this file is part of ehci-hcd.c */

/*-------------------------------------------------------------------------*/

/*
 * EHCI scheduled transaction support:  interrupt, iso, split iso
 * These are called "periodic" transactions in the EHCI spec.
 *
 * Note that for interrupt transfers, the QH/QTD manipulation is shared
 * with the "asynchronous" transaction support (control/bulk transfers).
 * The only real difference is in how interrupt transfers are scheduled.
 *
 * For ISO, we make an "iso_stream" head to serve the same role as a QH.
 * It keeps track of every ITD (or SITD) that's linked, and holds enough
 * pre-calculated schedule data to make appending to the queue be quick.
 */

static int ehci_get_frame(struct usb_hcd *hcd);

/*
 * periodic_next_shadow - return "next" pointer on shadow list
 * @periodic: host pointer to qh/itd/sitd
 * @tag: hardware tag for type of this record
 */
static union ehci_shadow *
periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
		__hc32 tag)
{
	switch (hc32_to_cpu(ehci, tag)) {
	case Q_TYPE_QH:
		return &periodic->qh->qh_next;
	case Q_TYPE_FSTN:
		return &periodic->fstn->fstn_next;
	case Q_TYPE_ITD:
		return &periodic->itd->itd_next;
	/* case Q_TYPE_SITD: */
	default:
		return &periodic->sitd->sitd_next;
	}
}

static __hc32 *
shadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic,
		__hc32 tag)
{
	switch (hc32_to_cpu(ehci, tag)) {
	/* our ehci_shadow.qh is actually software part */
	case Q_TYPE_QH:
		return &periodic->qh->hw->hw_next;
	/* others are hw parts */
	default:
		return periodic->hw_next;
	}
}

/* caller must hold ehci->lock */
static void periodic_unlink(struct ehci_hcd *ehci, unsigned frame, void *ptr)
{
	union ehci_shadow	*prev_p = &ehci->pshadow[frame];
	__hc32			*hw_p = &ehci->periodic[frame];
	union ehci_shadow	here = *prev_p;

	/* find predecessor of "ptr"; hw and shadow lists are in sync */
	while (here.ptr && here.ptr != ptr) {
		prev_p = periodic_next_shadow(ehci, prev_p,
				Q_NEXT_TYPE(ehci, *hw_p));
		hw_p = shadow_next_periodic(ehci, &here,
				Q_NEXT_TYPE(ehci, *hw_p));
		here = *prev_p;
	}
	/* an interrupt entry (at list end) could have been shared */
	if (!here.ptr)
		return;

	/* update shadow and hardware lists ... the old "next" pointers
	 * from ptr may still be in use, the caller updates them.
	 */
	*prev_p = *periodic_next_shadow(ehci, &here,
			Q_NEXT_TYPE(ehci, *hw_p));

	if (!ehci->use_dummy_qh ||
	    *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p))
			!= EHCI_LIST_END(ehci))
		*hw_p = *shadow_next_periodic(ehci, &here,
				Q_NEXT_TYPE(ehci, *hw_p));
	else
		*hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma);
}

/*-------------------------------------------------------------------------*/

/* Bandwidth and TT management */

/* Find the TT data structure for this device; create it if necessary */
static struct ehci_tt *find_tt(struct usb_device *udev)
{
	struct usb_tt		*utt = udev->tt;
	struct ehci_tt		*tt, **tt_index, **ptt;
	unsigned		port;
	bool			allocated_index = false;

	if (!utt)
		return NULL;		/* Not below a TT */

	/*
	 * Find/create our data structure.
	 * For hubs with a single TT, we get it directly.
	 * For hubs with multiple TTs, there's an extra level of pointers.
	 */
	tt_index = NULL;
	if (utt->multi) {
		tt_index = utt->hcpriv;
		if (!tt_index) {		/* Create the index array */
			tt_index = kcalloc(utt->hub->maxchild,
					   sizeof(*tt_index),
					   GFP_ATOMIC);
			if (!tt_index)
				return ERR_PTR(-ENOMEM);
			utt->hcpriv = tt_index;
			allocated_index = true;
		}
		port = udev->ttport - 1;
		ptt = &tt_index[port];
	} else {
		port = 0;
		ptt = (struct ehci_tt **) &utt->hcpriv;
	}

	tt = *ptt;
	if (!tt) {				/* Create the ehci_tt */
		struct ehci_hcd		*ehci =
				hcd_to_ehci(bus_to_hcd(udev->bus));

		tt = kzalloc(sizeof(*tt), GFP_ATOMIC);
		if (!tt) {
			if (allocated_index) {
				utt->hcpriv = NULL;
				kfree(tt_index);
			}
			return ERR_PTR(-ENOMEM);
		}
		list_add_tail(&tt->tt_list, &ehci->tt_list);
		INIT_LIST_HEAD(&tt->ps_list);
		tt->usb_tt = utt;
		tt->tt_port = port;
		*ptt = tt;
	}

	return tt;
}

/* Release the TT above udev, if it's not in use */
static void drop_tt(struct usb_device *udev)
{
	struct usb_tt		*utt = udev->tt;
	struct ehci_tt		*tt, **tt_index, **ptt;
	int			cnt, i;

	if (!utt || !utt->hcpriv)
		return;		/* Not below a TT, or never allocated */

	cnt = 0;
	if (utt->multi) {
		tt_index = utt->hcpriv;
		ptt = &tt_index[udev->ttport - 1];

		/* How many entries are left in tt_index? */
		for (i = 0; i < utt->hub->maxchild; ++i)
			cnt += !!tt_index[i];
	} else {
		tt_index = NULL;
		ptt = (struct ehci_tt **) &utt->hcpriv;
	}

	tt = *ptt;
	if (!tt || !list_empty(&tt->ps_list))
		return;		/* never allocated, or still in use */

	list_del(&tt->tt_list);
	*ptt = NULL;
	kfree(tt);
	if (cnt == 1) {
		utt->hcpriv = NULL;
		kfree(tt_index);
	}
}

static void bandwidth_dbg(struct ehci_hcd *ehci, int sign, char *type,
		struct ehci_per_sched *ps)
{
	dev_dbg(&ps->udev->dev,
			"ep %02x: %s %s @ %u+%u (%u.%u+%u) [%u/%u us] mask %04x\n",
			ps->ep->desc.bEndpointAddress,
			(sign >= 0 ? "reserve" : "release"), type,
			(ps->bw_phase << 3) + ps->phase_uf, ps->bw_uperiod,
			ps->phase, ps->phase_uf, ps->period,
			ps->usecs, ps->c_usecs, ps->cs_mask);
}

static void reserve_release_intr_bandwidth(struct ehci_hcd *ehci,
		struct ehci_qh *qh, int sign)
{
	unsigned		start_uf;
	unsigned		i, j, m;
	int			usecs = qh->ps.usecs;
	int			c_usecs = qh->ps.c_usecs;
	int			tt_usecs = qh->ps.tt_usecs;
	struct ehci_tt		*tt;

	if (qh->ps.phase == NO_FRAME)	/* Bandwidth wasn't reserved */
		return;
	start_uf = qh->ps.bw_phase << 3;

	bandwidth_dbg(ehci, sign, "intr", &qh->ps);

	if (sign < 0) {		/* Release bandwidth */
		usecs = -usecs;
		c_usecs = -c_usecs;
		tt_usecs = -tt_usecs;
	}

	/* Entire transaction (high speed) or start-split (full/low speed) */
	for (i = start_uf + qh->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE;
			i += qh->ps.bw_uperiod)
		ehci->bandwidth[i] += usecs;

	/* Complete-split (full/low speed) */
	if (qh->ps.c_usecs) {
		/* NOTE: adjustments needed for FSTN */
		for (i = start_uf; i < EHCI_BANDWIDTH_SIZE;
				i += qh->ps.bw_uperiod) {
			for ((j = 2, m = 1 << (j+8)); j < 8; (++j, m <<= 1)) {
				if (qh->ps.cs_mask & m)
					ehci->bandwidth[i+j] += c_usecs;
			}
		}
	}

	/* FS/LS bus bandwidth */
	if (tt_usecs) {
		/*
		 * find_tt() will not return any error here as we have
		 * already called find_tt() before calling this function
		 * and checked for any error return. The previous call
		 * would have created the data structure.
		 */
		tt = find_tt(qh->ps.udev);
		if (sign > 0)
			list_add_tail(&qh->ps.ps_list, &tt->ps_list);
		else
			list_del(&qh->ps.ps_list);

		for (i = start_uf >> 3; i < EHCI_BANDWIDTH_FRAMES;
				i += qh->ps.bw_period)
			tt->bandwidth[i] += tt_usecs;
	}
}

/*-------------------------------------------------------------------------*/

static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE],
		struct ehci_tt *tt)
{
	struct ehci_per_sched	*ps;
	unsigned		uframe, uf, x;
	u8			*budget_line;

	if (!tt)
		return;
	memset(budget_table, 0, EHCI_BANDWIDTH_SIZE);

	/* Add up the contributions from all the endpoints using this TT */
	list_for_each_entry(ps, &tt->ps_list, ps_list) {
		for (uframe = ps->bw_phase << 3; uframe < EHCI_BANDWIDTH_SIZE;
				uframe += ps->bw_uperiod) {
			budget_line = &budget_table[uframe];
			x = ps->tt_usecs;

			/* propagate the time forward */
			for (uf = ps->phase_uf; uf < 8; ++uf) {
				x += budget_line[uf];

				/* Each microframe lasts 125 us */
				if (x <= 125) {
					budget_line[uf] = x;
					break;
				}
				budget_line[uf] = 125;
				x -= 125;
			}
		}
	}
}

static int __maybe_unused same_tt(struct usb_device *dev1,
		struct usb_device *dev2)
{
	if (!dev1->tt || !dev2->tt)
		return 0;
	if (dev1->tt != dev2->tt)
		return 0;
	if (dev1->tt->multi)
		return dev1->ttport == dev2->ttport;
	else
		return 1;
}

#ifdef CONFIG_USB_EHCI_TT_NEWSCHED

static const unsigned char
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };

/* carryover low/fullspeed bandwidth that crosses uframe boundries */
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
{
	int i;

	for (i = 0; i < 7; i++) {
		if (max_tt_usecs[i] < tt_usecs[i]) {
			tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i];
			tt_usecs[i] = max_tt_usecs[i];
		}
	}
}

/*
 * Return true if the device's tt's downstream bus is available for a
 * periodic transfer of the specified length (usecs), starting at the
 * specified frame/uframe.  Note that (as summarized in section 11.19
 * of the usb 2.0 spec) TTs can buffer multiple transactions for each
 * uframe.
 *
 * The uframe parameter is when the fullspeed/lowspeed transfer
 * should be executed in "B-frame" terms, which is the same as the
 * highspeed ssplit's uframe (which is in "H-frame" terms).  For example
 * a ssplit in "H-frame" 0 causes a transfer in "B-frame" 0.
 * See the EHCI spec sec 4.5 and fig 4.7.
 *
 * This checks if the full/lowspeed bus, at the specified starting uframe,
 * has the specified bandwidth available, according to rules listed
 * in USB 2.0 spec section 11.18.1 fig 11-60.
 *
 * This does not check if the transfer would exceed the max ssplit
 * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4,
 * since proper scheduling limits ssplits to less than 16 per uframe.
 */
static int tt_available(
	struct ehci_hcd		*ehci,
	struct ehci_per_sched	*ps,
	struct ehci_tt		*tt,
	unsigned		frame,
	unsigned		uframe
)
{
	unsigned		period = ps->bw_period;
	unsigned		usecs = ps->tt_usecs;

	if ((period == 0) || (uframe >= 7))	/* error */
		return 0;

	for (frame &= period - 1; frame < EHCI_BANDWIDTH_FRAMES;
			frame += period) {
		unsigned	i, uf;
		unsigned short	tt_usecs[8];

		if (tt->bandwidth[frame] + usecs > 900)
			return 0;

		uf = frame << 3;
		for (i = 0; i < 8; (++i, ++uf))
			tt_usecs[i] = ehci->tt_budget[uf];

		if (max_tt_usecs[uframe] <= tt_usecs[uframe])
			return 0;

		/* special case for isoc transfers larger than 125us:
		 * the first and each subsequent fully used uframe
		 * must be empty, so as to not illegally delay
		 * already scheduled transactions
		 */
		if (usecs > 125) {
			int ufs = (usecs / 125);

			for (i = uframe; i < (uframe + ufs) && i < 8; i++)
				if (tt_usecs[i] > 0)
					return 0;
		}

		tt_usecs[uframe] += usecs;

		carryover_tt_bandwidth(tt_usecs);

		/* fail if the carryover pushed bw past the last uframe's limit */
		if (max_tt_usecs[7] < tt_usecs[7])
			return 0;
	}

	return 1;
}

#else

/* return true iff the device's transaction translator is available
 * for a periodic transfer starting at the specified frame, using
 * all the uframes in the mask.
 */
static int tt_no_collision(
	struct ehci_hcd		*ehci,
	unsigned		period,
	struct usb_device	*dev,
	unsigned		frame,
	u32			uf_mask
)
{
	if (period == 0)	/* error */
		return 0;

	/* note bandwidth wastage:  split never follows csplit
	 * (different dev or endpoint) until the next uframe.
	 * calling convention doesn't make that distinction.
	 */
	for (; frame < ehci->periodic_size; frame += period) {
		union ehci_shadow	here;
		__hc32			type;
		struct ehci_qh_hw	*hw;

		here = ehci->pshadow[frame];
		type = Q_NEXT_TYPE(ehci, ehci->periodic[frame]);
		while (here.ptr) {
			switch (hc32_to_cpu(ehci, type)) {
			case Q_TYPE_ITD:
				type = Q_NEXT_TYPE(ehci, here.itd->hw_next);
				here = here.itd->itd_next;
				continue;
			case Q_TYPE_QH:
				hw = here.qh->hw;
				if (same_tt(dev, here.qh->ps.udev)) {
					u32		mask;

					mask = hc32_to_cpu(ehci,
							hw->hw_info2);
					/* "knows" no gap is needed */
					mask |= mask >> 8;
					if (mask & uf_mask)
						break;
				}
				type = Q_NEXT_TYPE(ehci, hw->hw_next);
				here = here.qh->qh_next;
				continue;
			case Q_TYPE_SITD:
				if (same_tt(dev, here.sitd->urb->dev)) {
					u16		mask;

					mask = hc32_to_cpu(ehci, here.sitd
								->hw_uframe);
					/* FIXME assumes no gap for IN! */
					mask |= mask >> 8;
					if (mask & uf_mask)
						break;
				}
				type = Q_NEXT_TYPE(ehci, here.sitd->hw_next);
				here = here.sitd->sitd_next;
				continue;
			/* case Q_TYPE_FSTN: */
			default:
				ehci_dbg(ehci,
					"periodic frame %d bogus type %d\n",
					frame, type);
			}

			/* collision or error */
			return 0;
		}
	}

	/* no collision */
	return 1;
}

#endif /* CONFIG_USB_EHCI_TT_NEWSCHED */

/*-------------------------------------------------------------------------*/

static void enable_periodic(struct ehci_hcd *ehci)
{
	if (ehci->periodic_count++)
		return;

	/* Stop waiting to turn off the periodic schedule */
	ehci->enabled_hrtimer_events &= ~BIT(EHCI_HRTIMER_DISABLE_PERIODIC);

	/* Don't start the schedule until PSS is 0 */
	ehci_poll_PSS(ehci);
	turn_on_io_watchdog(ehci);
}

static void disable_periodic(struct ehci_hcd *ehci)
{
	if (--ehci->periodic_count)
		return;

	/* Don't turn off the schedule until PSS is 1 */
	ehci_poll_PSS(ehci);
}

/*-------------------------------------------------------------------------*/

/* periodic schedule slots have iso tds (normal or split) first, then a
 * sparse tree for active interrupt transfers.
 *
 * this just links in a qh; caller guarantees uframe masks are set right.
 * no FSTN support (yet; ehci 0.96+)
 */
static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	unsigned	i;
	unsigned	period = qh->ps.period;

	dev_dbg(&qh->ps.udev->dev,
		"link qh%d-%04x/%p start %d [%d/%d us]\n",
		period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
			& (QH_CMASK | QH_SMASK),
		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);

	/* high bandwidth, or otherwise every microframe */
	if (period == 0)
		period = 1;

	for (i = qh->ps.phase; i < ehci->periodic_size; i += period) {
		union ehci_shadow	*prev = &ehci->pshadow[i];
		__hc32			*hw_p = &ehci->periodic[i];
		union ehci_shadow	here = *prev;
		__hc32			type = 0;

		/* skip the iso nodes at list head */
		while (here.ptr) {
			type = Q_NEXT_TYPE(ehci, *hw_p);
			if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
				break;
			prev = periodic_next_shadow(ehci, prev, type);
			hw_p = shadow_next_periodic(ehci, &here, type);
			here = *prev;
		}

		/* sorting each branch by period (slow-->fast)
		 * enables sharing interior tree nodes
		 */
		while (here.ptr && qh != here.qh) {
			if (qh->ps.period > here.qh->ps.period)
				break;
			prev = &here.qh->qh_next;
			hw_p = &here.qh->hw->hw_next;
			here = *prev;
		}
		/* link in this qh, unless some earlier pass did that */
		if (qh != here.qh) {
			qh->qh_next = here;
			if (here.qh)
				qh->hw->hw_next = *hw_p;
			wmb();
			prev->qh = qh;
			*hw_p = QH_NEXT(ehci, qh->qh_dma);
		}
	}
	qh->qh_state = QH_STATE_LINKED;
	qh->xacterrs = 0;
	qh->unlink_reason = 0;

	/* update per-qh bandwidth for debugfs */
	ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->ps.bw_period
		? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period)
		: (qh->ps.usecs * 8);

	list_add(&qh->intr_node, &ehci->intr_qh_list);

	/* maybe enable periodic schedule processing */
	++ehci->intr_count;
	enable_periodic(ehci);
}

static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	unsigned	i;
	unsigned	period;

	/*
	 * If qh is for a low/full-speed device, simply unlinking it
	 * could interfere with an ongoing split transaction.  To unlink
	 * it safely would require setting the QH_INACTIVATE bit and
	 * waiting at least one frame, as described in EHCI 4.12.2.5.
	 *
	 * We won't bother with any of this.  Instead, we assume that the
	 * only reason for unlinking an interrupt QH while the current URB
	 * is still active is to dequeue all the URBs (flush the whole
	 * endpoint queue).
	 *
	 * If rebalancing the periodic schedule is ever implemented, this
	 * approach will no longer be valid.
	 */

	/* high bandwidth, or otherwise part of every microframe */
	period = qh->ps.period ? : 1;

	for (i = qh->ps.phase; i < ehci->periodic_size; i += period)
		periodic_unlink(ehci, i, qh);

	/* update per-qh bandwidth for debugfs */
	ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->ps.bw_period
		? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period)
		: (qh->ps.usecs * 8);

	dev_dbg(&qh->ps.udev->dev,
		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
		qh->ps.period,
		hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);

	/* qh->qh_next still "live" to HC */
	qh->qh_state = QH_STATE_UNLINK;
	qh->qh_next.ptr = NULL;

	if (ehci->qh_scan_next == qh)
		ehci->qh_scan_next = list_entry(qh->intr_node.next,
				struct ehci_qh, intr_node);
	list_del(&qh->intr_node);
}

static void cancel_unlink_wait_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	if (qh->qh_state != QH_STATE_LINKED ||
			list_empty(&qh->unlink_node))
		return;

	list_del_init(&qh->unlink_node);

	/*
	 * TODO: disable the event of EHCI_HRTIMER_START_UNLINK_INTR for
	 * avoiding unnecessary CPU wakeup
	 */
}

static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	/* If the QH isn't linked then there's nothing we can do. */
	if (qh->qh_state != QH_STATE_LINKED)
		return;

	/* if the qh is waiting for unlink, cancel it now */
	cancel_unlink_wait_intr(ehci, qh);

	qh_unlink_periodic(ehci, qh);

	/* Make sure the unlinks are visible before starting the timer */
	wmb();

	/*
	 * The EHCI spec doesn't say how long it takes the controller to
	 * stop accessing an unlinked interrupt QH.  The timer delay is
	 * 9 uframes; presumably that will be long enough.
	 */
	qh->unlink_cycle = ehci->intr_unlink_cycle;

	/* New entries go at the end of the intr_unlink list */
	list_add_tail(&qh->unlink_node, &ehci->intr_unlink);

	if (ehci->intr_unlinking)
		;	/* Avoid recursive calls */
	else if (ehci->rh_state < EHCI_RH_RUNNING)
		ehci_handle_intr_unlinks(ehci);
	else if (ehci->intr_unlink.next == &qh->unlink_node) {
		ehci_enable_event(ehci, EHCI_HRTIMER_UNLINK_INTR, true);
		++ehci->intr_unlink_cycle;
	}
}

/*
 * It is common only one intr URB is scheduled on one qh, and
 * given complete() is run in tasklet context, introduce a bit
 * delay to avoid unlink qh too early.
 */
static void start_unlink_intr_wait(struct ehci_hcd *ehci,
				   struct ehci_qh *qh)
{
	qh->unlink_cycle = ehci->intr_unlink_wait_cycle;

	/* New entries go at the end of the intr_unlink_wait list */
	list_add_tail(&qh->unlink_node, &ehci->intr_unlink_wait);

	if (ehci->rh_state < EHCI_RH_RUNNING)
		ehci_handle_start_intr_unlinks(ehci);
	else if (ehci->intr_unlink_wait.next == &qh->unlink_node) {
		ehci_enable_event(ehci, EHCI_HRTIMER_START_UNLINK_INTR, true);
		++ehci->intr_unlink_wait_cycle;
	}
}

static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	struct ehci_qh_hw	*hw = qh->hw;
	int			rc;

	qh->qh_state = QH_STATE_IDLE;
	hw->hw_next = EHCI_LIST_END(ehci);

	if (!list_empty(&qh->qtd_list))
		qh_completions(ehci, qh);

	/* reschedule QH iff another request is queued */
	if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
		rc = qh_schedule(ehci, qh);
		if (rc == 0) {
			qh_refresh(ehci, qh);
			qh_link_periodic(ehci, qh);
		}

		/* An error here likely indicates handshake failure
		 * or no space left in the schedule.  Neither fault
		 * should happen often ...
		 *
		 * FIXME kill the now-dysfunctional queued urbs
		 */
		else {
			ehci_err(ehci, "can't reschedule qh %p, err %d\n",
					qh, rc);
		}
	}

	/* maybe turn off periodic schedule */
	--ehci->intr_count;
	disable_periodic(ehci);
}

/*-------------------------------------------------------------------------*/

static int check_period(
	struct ehci_hcd *ehci,
	unsigned	frame,
	unsigned	uframe,
	unsigned	uperiod,
	unsigned	usecs
) {
	/* complete split running into next frame?
	 * given FSTN support, we could sometimes check...
	 */
	if (uframe >= 8)
		return 0;

	/* convert "usecs we need" to "max already claimed" */
	usecs = ehci->uframe_periodic_max - usecs;

	for (uframe += frame << 3; uframe < EHCI_BANDWIDTH_SIZE;
			uframe += uperiod) {
		if (ehci->bandwidth[uframe] > usecs)
			return 0;
	}

	/* success! */
	return 1;
}

static int check_intr_schedule(
	struct ehci_hcd		*ehci,
	unsigned		frame,
	unsigned		uframe,
	struct ehci_qh		*qh,
	unsigned		*c_maskp,
	struct ehci_tt		*tt
)
{
	int		retval = -ENOSPC;
	u8		mask = 0;

	if (qh->ps.c_usecs && uframe >= 6)	/* FSTN territory? */
		goto done;

	if (!check_period(ehci, frame, uframe, qh->ps.bw_uperiod, qh->ps.usecs))
		goto done;
	if (!qh->ps.c_usecs) {
		retval = 0;
		*c_maskp = 0;
		goto done;
	}

#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
	if (tt_available(ehci, &qh->ps, tt, frame, uframe)) {
		unsigned i;

		/* TODO : this may need FSTN for SSPLIT in uframe 5. */
		for (i = uframe+2; i < 8 && i <= uframe+4; i++)
			if (!check_period(ehci, frame, i,
					qh->ps.bw_uperiod, qh->ps.c_usecs))
				goto done;
			else
				mask |= 1 << i;

		retval = 0;

		*c_maskp = mask;
	}
#else
	/* Make sure this tt's buffer is also available for CSPLITs.
	 * We pessimize a bit; probably the typical full speed case
	 * doesn't need the second CSPLIT.
	 *
	 * NOTE:  both SPLIT and CSPLIT could be checked in just
	 * one smart pass...
	 */
	mask = 0x03 << (uframe + qh->gap_uf);
	*c_maskp = mask;

	mask |= 1 << uframe;
	if (tt_no_collision(ehci, qh->ps.bw_period, qh->ps.udev, frame, mask)) {
		if (!check_period(ehci, frame, uframe + qh->gap_uf + 1,
				qh->ps.bw_uperiod, qh->ps.c_usecs))
			goto done;
		if (!check_period(ehci, frame, uframe + qh->gap_uf,
				qh->ps.bw_uperiod, qh->ps.c_usecs))
			goto done;
		retval = 0;
	}
#endif
done:
	return retval;
}

/* "first fit" scheduling policy used the first time through,
 * or when the previous schedule slot can't be re-used.
 */
static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
	int		status = 0;
	unsigned	uframe;
	unsigned	c_mask;
	struct ehci_qh_hw	*hw = qh->hw;
	struct ehci_tt		*tt;

	hw->hw_next = EHCI_LIST_END(ehci);

	/* reuse the previous schedule slots, if we can */
	if (qh->ps.phase != NO_FRAME) {
		ehci_dbg(ehci, "reused qh %p schedule\n", qh);
		return 0;
	}

	uframe = 0;
	c_mask = 0;
	tt = find_tt(qh->ps.udev);
	if (IS_ERR(tt)) {
		status = PTR_ERR(tt);
		goto done;
	}
	compute_tt_budget(ehci->tt_budget, tt);

	/* else scan the schedule to find a group of slots such that all
	 * uframes have enough periodic bandwidth available.
	 */
	/* "normal" case, uframing flexible except with splits */
	if (qh->ps.bw_period) {
		int		i;
		unsigned	frame;

		for (i = qh->ps.bw_period; i > 0; --i) {
			frame = ++ehci->random_frame & (qh->ps.bw_period - 1);
			for (uframe = 0; uframe < 8; uframe++) {
				status = check_intr_schedule(ehci,
						frame, uframe, qh, &c_mask, tt);
				if (status == 0)
					goto got_it;
			}
		}

	/* qh->ps.bw_period == 0 means every uframe */
	} else {
		status = check_intr_schedule(ehci, 0, 0, qh, &c_mask, tt);
	}
	if (status)
		goto done;

 got_it:
	qh->ps.phase = (qh->ps.period ? ehci->random_frame &
			(qh->ps.period - 1) : 0);
	qh->ps.bw_phase = qh->ps.phase & (qh->ps.bw_period - 1);
	qh->ps.phase_uf = uframe;
	qh->ps.cs_mask = qh->ps.period ?
			(c_mask << 8) | (1 << uframe) :
			QH_SMASK;

	/* reset S-frame and (maybe) C-frame masks */
	hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
	hw->hw_info2 |= cpu_to_hc32(ehci, qh->ps.cs_mask);
	reserve_release_intr_bandwidth(ehci, qh, 1);

done:
	return status;
}

static int intr_submit(
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	struct list_head	*qtd_list,
	gfp_t			mem_flags
) {
	unsigned		epnum;
	unsigned long		flags;
	struct ehci_qh		*qh;
	int			status;
	struct list_head	empty;

	/* get endpoint and transfer/schedule data */
	epnum = urb->ep->desc.bEndpointAddress;

	spin_lock_irqsave(&ehci->lock, flags);

	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
		status = -ESHUTDOWN;
		goto done_not_linked;
	}
	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
	if (unlikely(status))
		goto done_not_linked;

	/* get qh and force any scheduling errors */
	INIT_LIST_HEAD(&empty);
	qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv);
	if (qh == NULL) {
		status = -ENOMEM;
		goto done;
	}
	if (qh->qh_state == QH_STATE_IDLE) {
		status = qh_schedule(ehci, qh);
		if (status)
			goto done;
	}

	/* then queue the urb's tds to the qh */
	qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv);
	BUG_ON(qh == NULL);

	/* stuff into the periodic schedule */
	if (qh->qh_state == QH_STATE_IDLE) {
		qh_refresh(ehci, qh);
		qh_link_periodic(ehci, qh);
	} else {
		/* cancel unlink wait for the qh */
		cancel_unlink_wait_intr(ehci, qh);
	}

	/* ... update usbfs periodic stats */
	ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;

done:
	if (unlikely(status))
		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
done_not_linked:
	spin_unlock_irqrestore(&ehci->lock, flags);
	if (status)
		qtd_list_free(ehci, urb, qtd_list);

	return status;
}

static void scan_intr(struct ehci_hcd *ehci)
{
	struct ehci_qh		*qh;

	list_for_each_entry_safe(qh, ehci->qh_scan_next, &ehci->intr_qh_list,
			intr_node) {

		/* clean any finished work for this qh */
		if (!list_empty(&qh->qtd_list)) {
			int temp;

			/*
			 * Unlinks could happen here; completion reporting
			 * drops the lock.  That's why ehci->qh_scan_next
			 * always holds the next qh to scan; if the next qh
			 * gets unlinked then ehci->qh_scan_next is adjusted
			 * in qh_unlink_periodic().
			 */
			temp = qh_completions(ehci, qh);
			if (unlikely(temp))
				start_unlink_intr(ehci, qh);
			else if (unlikely(list_empty(&qh->qtd_list) &&
					qh->qh_state == QH_STATE_LINKED))
				start_unlink_intr_wait(ehci, qh);
		}
	}
}

/*-------------------------------------------------------------------------*/

/* ehci_iso_stream ops work with both ITD and SITD */

static struct ehci_iso_stream *
iso_stream_alloc(gfp_t mem_flags)
{
	struct ehci_iso_stream *stream;

	stream = kzalloc(sizeof(*stream), mem_flags);
	if (likely(stream != NULL)) {
		INIT_LIST_HEAD(&stream->td_list);
		INIT_LIST_HEAD(&stream->free_list);
		stream->next_uframe = NO_FRAME;
		stream->ps.phase = NO_FRAME;
	}
	return stream;
}

static void
iso_stream_init(
	struct ehci_hcd		*ehci,
	struct ehci_iso_stream	*stream,
	struct urb		*urb
)
{
	static const u8 smask_out[] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f };

	struct usb_device	*dev = urb->dev;
	u32			buf1;
	unsigned		epnum, maxp;
	int			is_input;
	unsigned		tmp;

	/*
	 * this might be a "high bandwidth" highspeed endpoint,
	 * as encoded in the ep descriptor's wMaxPacket field
	 */
	epnum = usb_pipeendpoint(urb->pipe);
	is_input = usb_pipein(urb->pipe) ? USB_DIR_IN : 0;
	maxp = usb_endpoint_maxp(&urb->ep->desc);
	buf1 = is_input ? 1 << 11 : 0;

	/* knows about ITD vs SITD */
	if (dev->speed == USB_SPEED_HIGH) {
		unsigned multi = usb_endpoint_maxp_mult(&urb->ep->desc);

		stream->highspeed = 1;

		buf1 |= maxp;
		maxp *= multi;

		stream->buf0 = cpu_to_hc32(ehci, (epnum << 8) | dev->devnum);
		stream->buf1 = cpu_to_hc32(ehci, buf1);
		stream->buf2 = cpu_to_hc32(ehci, multi);

		/* usbfs wants to report the average usecs per frame tied up
		 * when transfers on this endpoint are scheduled ...
		 */
		stream->ps.usecs = HS_USECS_ISO(maxp);

		/* period for bandwidth allocation */
		tmp = min_t(unsigned, EHCI_BANDWIDTH_SIZE,
				1 << (urb->ep->desc.bInterval - 1));

		/* Allow urb->interval to override */
		stream->ps.bw_uperiod = min_t(unsigned, tmp, urb->interval);

		stream->uperiod = urb->interval;
		stream->ps.period = urb->interval >> 3;
		stream->bandwidth = stream->ps.usecs * 8 /
				stream->ps.bw_uperiod;

	} else {
		u32		addr;
		int		think_time;
		int		hs_transfers;

		addr = dev->ttport << 24;
		if (!ehci_is_TDI(ehci)
				|| (dev->tt->hub !=
					ehci_to_hcd(ehci)->self.root_hub))
			addr |= dev->tt->hub->devnum << 16;
		addr |= epnum << 8;
		addr |= dev->devnum;
		stream->ps.usecs = HS_USECS_ISO(maxp);
		think_time = dev->tt->think_time;
		stream->ps.tt_usecs = NS_TO_US(think_time + usb_calc_bus_time(
				dev->speed, is_input, 1, maxp));
		hs_transfers = max(1u, (maxp + 187) / 188);
		if (is_input) {
			u32	tmp;

			addr |= 1 << 31;
			stream->ps.c_usecs = stream->ps.usecs;
			stream->ps.usecs = HS_USECS_ISO(1);
			stream->ps.cs_mask = 1;

			/* c-mask as specified in USB 2.0 11.18.4 3.c */
			tmp = (1 << (hs_transfers + 2)) - 1;
			stream->ps.cs_mask |= tmp << (8 + 2);
		} else
			stream->ps.cs_mask = smask_out[hs_transfers - 1];

		/* period for bandwidth allocation */
		tmp = min_t(unsigned, EHCI_BANDWIDTH_FRAMES,
				1 << (urb->ep->desc.bInterval - 1));

		/* Allow urb->interval to override */
		stream->ps.bw_period = min_t(unsigned, tmp, urb->interval);
		stream->ps.bw_uperiod = stream->ps.bw_period << 3;

		stream->ps.period = urb->interval;
		stream->uperiod = urb->interval << 3;
		stream->bandwidth = (stream->ps.usecs + stream->ps.c_usecs) /
				stream->ps.bw_period;

		/* stream->splits gets created from cs_mask later */
		stream->address = cpu_to_hc32(ehci, addr);
	}

	stream->ps.udev = dev;
	stream->ps.ep = urb->ep;

	stream->bEndpointAddress = is_input | epnum;
	stream->maxp = maxp;
}

static struct ehci_iso_stream *
iso_stream_find(struct ehci_hcd *ehci, struct urb *urb)
{
	unsigned		epnum;
	struct ehci_iso_stream	*stream;
	struct usb_host_endpoint *ep;
	unsigned long		flags;

	epnum = usb_pipeendpoint (urb->pipe);
	if (usb_pipein(urb->pipe))
		ep = urb->dev->ep_in[epnum];
	else
		ep = urb->dev->ep_out[epnum];

	spin_lock_irqsave(&ehci->lock, flags);
	stream = ep->hcpriv;

	if (unlikely(stream == NULL)) {
		stream = iso_stream_alloc(GFP_ATOMIC);
		if (likely(stream != NULL)) {
			ep->hcpriv = stream;
			iso_stream_init(ehci, stream, urb);
		}

	/* if dev->ep [epnum] is a QH, hw is set */
	} else if (unlikely(stream->hw != NULL)) {
		ehci_dbg(ehci, "dev %s ep%d%s, not iso??\n",
			urb->dev->devpath, epnum,
			usb_pipein(urb->pipe) ? "in" : "out");
		stream = NULL;
	}

	spin_unlock_irqrestore(&ehci->lock, flags);
	return stream;
}

/*-------------------------------------------------------------------------*/

/* ehci_iso_sched ops can be ITD-only or SITD-only */

static struct ehci_iso_sched *
iso_sched_alloc(unsigned packets, gfp_t mem_flags)
{
	struct ehci_iso_sched	*iso_sched;
	int			size = sizeof(*iso_sched);

	size += packets * sizeof(struct ehci_iso_packet);
	iso_sched = kzalloc(size, mem_flags);
	if (likely(iso_sched != NULL))
		INIT_LIST_HEAD(&iso_sched->td_list);

	return iso_sched;
}

static inline void
itd_sched_init(
	struct ehci_hcd		*ehci,
	struct ehci_iso_sched	*iso_sched,
	struct ehci_iso_stream	*stream,
	struct urb		*urb
)
{
	unsigned	i;
	dma_addr_t	dma = urb->transfer_dma;

	/* how many uframes are needed for these transfers */
	iso_sched->span = urb->number_of_packets * stream->uperiod;

	/* figure out per-uframe itd fields that we'll need later
	 * when we fit new itds into the schedule.
	 */
	for (i = 0; i < urb->number_of_packets; i++) {
		struct ehci_iso_packet	*uframe = &iso_sched->packet[i];
		unsigned		length;
		dma_addr_t		buf;
		u32			trans;

		length = urb->iso_frame_desc[i].length;
		buf = dma + urb->iso_frame_desc[i].offset;

		trans = EHCI_ISOC_ACTIVE;
		trans |= buf & 0x0fff;
		if (unlikely(((i + 1) == urb->number_of_packets))
				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
			trans |= EHCI_ITD_IOC;
		trans |= length << 16;
		uframe->transaction = cpu_to_hc32(ehci, trans);

		/* might need to cross a buffer page within a uframe */
		uframe->bufp = (buf & ~(u64)0x0fff);
		buf += length;
		if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff))))
			uframe->cross = 1;
	}
}

static void
iso_sched_free(
	struct ehci_iso_stream	*stream,
	struct ehci_iso_sched	*iso_sched
)
{
	if (!iso_sched)
		return;
	/* caller must hold ehci->lock! */
	list_splice(&iso_sched->td_list, &stream->free_list);
	kfree(iso_sched);
}

static int
itd_urb_transaction(
	struct ehci_iso_stream	*stream,
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	gfp_t			mem_flags
)
{
	struct ehci_itd		*itd;
	dma_addr_t		itd_dma;
	int			i;
	unsigned		num_itds;
	struct ehci_iso_sched	*sched;
	unsigned long		flags;

	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
	if (unlikely(sched == NULL))
		return -ENOMEM;

	itd_sched_init(ehci, sched, stream, urb);

	if (urb->interval < 8)
		num_itds = 1 + (sched->span + 7) / 8;
	else
		num_itds = urb->number_of_packets;

	/* allocate/init ITDs */
	spin_lock_irqsave(&ehci->lock, flags);
	for (i = 0; i < num_itds; i++) {

		/*
		 * Use iTDs from the free list, but not iTDs that may
		 * still be in use by the hardware.
		 */
		if (likely(!list_empty(&stream->free_list))) {
			itd = list_first_entry(&stream->free_list,
					struct ehci_itd, itd_list);
			if (itd->frame == ehci->now_frame)
				goto alloc_itd;
			list_del(&itd->itd_list);
			itd_dma = itd->itd_dma;
		} else {
 alloc_itd:
			spin_unlock_irqrestore(&ehci->lock, flags);
			itd = dma_pool_alloc(ehci->itd_pool, mem_flags,
					&itd_dma);
			spin_lock_irqsave(&ehci->lock, flags);
			if (!itd) {
				iso_sched_free(stream, sched);
				spin_unlock_irqrestore(&ehci->lock, flags);
				return -ENOMEM;
			}
		}

		memset(itd, 0, sizeof(*itd));
		itd->itd_dma = itd_dma;
		itd->frame = NO_FRAME;
		list_add(&itd->itd_list, &sched->td_list);
	}
	spin_unlock_irqrestore(&ehci->lock, flags);

	/* temporarily store schedule info in hcpriv */
	urb->hcpriv = sched;
	urb->error_count = 0;
	return 0;
}

/*-------------------------------------------------------------------------*/

static void reserve_release_iso_bandwidth(struct ehci_hcd *ehci,
		struct ehci_iso_stream *stream, int sign)
{
	unsigned		uframe;
	unsigned		i, j;
	unsigned		s_mask, c_mask, m;
	int			usecs = stream->ps.usecs;
	int			c_usecs = stream->ps.c_usecs;
	int			tt_usecs = stream->ps.tt_usecs;
	struct ehci_tt		*tt;

	if (stream->ps.phase == NO_FRAME)	/* Bandwidth wasn't reserved */
		return;
	uframe = stream->ps.bw_phase << 3;

	bandwidth_dbg(ehci, sign, "iso", &stream->ps);

	if (sign < 0) {		/* Release bandwidth */
		usecs = -usecs;
		c_usecs = -c_usecs;
		tt_usecs = -tt_usecs;
	}

	if (!stream->splits) {		/* High speed */
		for (i = uframe + stream->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE;
				i += stream->ps.bw_uperiod)
			ehci->bandwidth[i] += usecs;

	} else {			/* Full speed */
		s_mask = stream->ps.cs_mask;
		c_mask = s_mask >> 8;

		/* NOTE: adjustment needed for frame overflow */
		for (i = uframe; i < EHCI_BANDWIDTH_SIZE;
				i += stream->ps.bw_uperiod) {
			for ((j = stream->ps.phase_uf, m = 1 << j); j < 8;
					(++j, m <<= 1)) {
				if (s_mask & m)
					ehci->bandwidth[i+j] += usecs;
				else if (c_mask & m)
					ehci->bandwidth[i+j] += c_usecs;
			}
		}

		/*
		 * find_tt() will not return any error here as we have
		 * already called find_tt() before calling this function
		 * and checked for any error return. The previous call
		 * would have created the data structure.
		 */
		tt = find_tt(stream->ps.udev);
		if (sign > 0)
			list_add_tail(&stream->ps.ps_list, &tt->ps_list);
		else
			list_del(&stream->ps.ps_list);

		for (i = uframe >> 3; i < EHCI_BANDWIDTH_FRAMES;
				i += stream->ps.bw_period)
			tt->bandwidth[i] += tt_usecs;
	}
}

static inline int
itd_slot_ok(
	struct ehci_hcd		*ehci,
	struct ehci_iso_stream	*stream,
	unsigned		uframe
)
{
	unsigned		usecs;

	/* convert "usecs we need" to "max already claimed" */
	usecs = ehci->uframe_periodic_max - stream->ps.usecs;

	for (uframe &= stream->ps.bw_uperiod - 1; uframe < EHCI_BANDWIDTH_SIZE;
			uframe += stream->ps.bw_uperiod) {
		if (ehci->bandwidth[uframe] > usecs)
			return 0;
	}
	return 1;
}

static inline int
sitd_slot_ok(
	struct ehci_hcd		*ehci,
	struct ehci_iso_stream	*stream,
	unsigned		uframe,
	struct ehci_iso_sched	*sched,
	struct ehci_tt		*tt
)
{
	unsigned		mask, tmp;
	unsigned		frame, uf;

	mask = stream->ps.cs_mask << (uframe & 7);

	/* for OUT, don't wrap SSPLIT into H-microframe 7 */
	if (((stream->ps.cs_mask & 0xff) << (uframe & 7)) >= (1 << 7))
		return 0;

	/* for IN, don't wrap CSPLIT into the next frame */
	if (mask & ~0xffff)
		return 0;

	/* check bandwidth */
	uframe &= stream->ps.bw_uperiod - 1;
	frame = uframe >> 3;

#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
	/* The tt's fullspeed bus bandwidth must be available.
	 * tt_available scheduling guarantees 10+% for control/bulk.
	 */
	uf = uframe & 7;
	if (!tt_available(ehci, &stream->ps, tt, frame, uf))
		return 0;
#else
	/* tt must be idle for start(s), any gap, and csplit.
	 * assume scheduling slop leaves 10+% for control/bulk.
	 */
	if (!tt_no_collision(ehci, stream->ps.bw_period,
			stream->ps.udev, frame, mask))
		return 0;
#endif

	do {
		unsigned	max_used;
		unsigned	i;

		/* check starts (OUT uses more than one) */
		uf = uframe;
		max_used = ehci->uframe_periodic_max - stream->ps.usecs;
		for (tmp = stream->ps.cs_mask & 0xff; tmp; tmp >>= 1, uf++) {
			if (ehci->bandwidth[uf] > max_used)
				return 0;
		}

		/* for IN, check CSPLIT */
		if (stream->ps.c_usecs) {
			max_used = ehci->uframe_periodic_max -
					stream->ps.c_usecs;
			uf = uframe & ~7;
			tmp = 1 << (2+8);
			for (i = (uframe & 7) + 2; i < 8; (++i, tmp <<= 1)) {
				if ((stream->ps.cs_mask & tmp) == 0)
					continue;
				if (ehci->bandwidth[uf+i] > max_used)
					return 0;
			}
		}

		uframe += stream->ps.bw_uperiod;
	} while (uframe < EHCI_BANDWIDTH_SIZE);

	stream->ps.cs_mask <<= uframe & 7;
	stream->splits = cpu_to_hc32(ehci, stream->ps.cs_mask);
	return 1;
}

/*
 * This scheduler plans almost as far into the future as it has actual
 * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
 * "as small as possible" to be cache-friendlier.)  That limits the size
 * transfers you can stream reliably; avoid more than 64 msec per urb.
 * Also avoid queue depths of less than ehci's worst irq latency (affected
 * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
 * and other factors); or more than about 230 msec total (for portability,
 * given EHCI_TUNE_FLS and the slop).  Or, write a smarter scheduler!
 */

static int
iso_stream_schedule(
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	struct ehci_iso_stream	*stream
)
{
	u32			now, base, next, start, period, span, now2;
	u32			wrap = 0, skip = 0;
	int			status = 0;
	unsigned		mod = ehci->periodic_size << 3;
	struct ehci_iso_sched	*sched = urb->hcpriv;
	bool			empty = list_empty(&stream->td_list);
	bool			new_stream = false;

	period = stream->uperiod;
	span = sched->span;
	if (!stream->highspeed)
		span <<= 3;

	/* Start a new isochronous stream? */
	if (unlikely(empty && !hcd_periodic_completion_in_progress(
			ehci_to_hcd(ehci), urb->ep))) {

		/* Schedule the endpoint */
		if (stream->ps.phase == NO_FRAME) {
			int		done = 0;
			struct ehci_tt	*tt = find_tt(stream->ps.udev);

			if (IS_ERR(tt)) {
				status = PTR_ERR(tt);
				goto fail;
			}
			compute_tt_budget(ehci->tt_budget, tt);

			start = ((-(++ehci->random_frame)) << 3) & (period - 1);

			/* find a uframe slot with enough bandwidth.
			 * Early uframes are more precious because full-speed
			 * iso IN transfers can't use late uframes,
			 * and therefore they should be allocated last.
			 */
			next = start;
			start += period;
			do {
				start--;
				/* check schedule: enough space? */
				if (stream->highspeed) {
					if (itd_slot_ok(ehci, stream, start))
						done = 1;
				} else {
					if ((start % 8) >= 6)
						continue;
					if (sitd_slot_ok(ehci, stream, start,
							sched, tt))
						done = 1;
				}
			} while (start > next && !done);

			/* no room in the schedule */
			if (!done) {
				ehci_dbg(ehci, "iso sched full %p", urb);
				status = -ENOSPC;
				goto fail;
			}
			stream->ps.phase = (start >> 3) &
					(stream->ps.period - 1);
			stream->ps.bw_phase = stream->ps.phase &
					(stream->ps.bw_period - 1);
			stream->ps.phase_uf = start & 7;
			reserve_release_iso_bandwidth(ehci, stream, 1);
		}

		/* New stream is already scheduled; use the upcoming slot */
		else {
			start = (stream->ps.phase << 3) + stream->ps.phase_uf;
		}

		stream->next_uframe = start;
		new_stream = true;
	}

	now = ehci_read_frame_index(ehci) & (mod - 1);

	/* Take the isochronous scheduling threshold into account */
	if (ehci->i_thresh)
		next = now + ehci->i_thresh;	/* uframe cache */
	else
		next = (now + 2 + 7) & ~0x07;	/* full frame cache */

	/* If needed, initialize last_iso_frame so that this URB will be seen */
	if (ehci->isoc_count == 0)
		ehci->last_iso_frame = now >> 3;

	/*
	 * Use ehci->last_iso_frame as the base.  There can't be any
	 * TDs scheduled for earlier than that.
	 */
	base = ehci->last_iso_frame << 3;
	next = (next - base) & (mod - 1);
	start = (stream->next_uframe - base) & (mod - 1);

	if (unlikely(new_stream))
		goto do_ASAP;

	/*
	 * Typical case: reuse current schedule, stream may still be active.
	 * Hopefully there are no gaps from the host falling behind
	 * (irq delays etc).  If there are, the behavior depends on
	 * whether URB_ISO_ASAP is set.
	 */
	now2 = (now - base) & (mod - 1);

	/* Is the schedule about to wrap around? */
	if (unlikely(!empty && start < period)) {
		ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n",
				urb, stream->next_uframe, base, period, mod);
		status = -EFBIG;
		goto fail;
	}

	/* Is the next packet scheduled after the base time? */
	if (likely(!empty || start <= now2 + period)) {

		/* URB_ISO_ASAP: make sure that start >= next */
		if (unlikely(start < next &&
				(urb->transfer_flags & URB_ISO_ASAP)))
			goto do_ASAP;

		/* Otherwise use start, if it's not in the past */
		if (likely(start >= now2))
			goto use_start;

	/* Otherwise we got an underrun while the queue was empty */
	} else {
		if (urb->transfer_flags & URB_ISO_ASAP)
			goto do_ASAP;
		wrap = mod;
		now2 += mod;
	}

	/* How many uframes and packets do we need to skip? */
	skip = (now2 - start + period - 1) & -period;
	if (skip >= span) {		/* Entirely in the past? */
		ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n",
				urb, start + base, span - period, now2 + base,
				base);

		/* Try to keep the last TD intact for scanning later */
		skip = span - period;

		/* Will it come before the current scan position? */
		if (empty) {
			skip = span;	/* Skip the entire URB */
			status = 1;	/* and give it back immediately */
			iso_sched_free(stream, sched);
			sched = NULL;
		}
	}
	urb->error_count = skip / period;
	if (sched)
		sched->first_packet = urb->error_count;
	goto use_start;

 do_ASAP:
	/* Use the first slot after "next" */
	start = next + ((start - next) & (period - 1));

 use_start:
	/* Tried to schedule too far into the future? */
	if (unlikely(start + span - period >= mod + wrap)) {
		ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
				urb, start, span - period, mod + wrap);
		status = -EFBIG;
		goto fail;
	}

	start += base;
	stream->next_uframe = (start + skip) & (mod - 1);

	/* report high speed start in uframes; full speed, in frames */
	urb->start_frame = start & (mod - 1);
	if (!stream->highspeed)
		urb->start_frame >>= 3;
	return status;

 fail:
	iso_sched_free(stream, sched);
	urb->hcpriv = NULL;
	return status;
}

/*-------------------------------------------------------------------------*/

static inline void
itd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream,
		struct ehci_itd *itd)
{
	int i;

	/* it's been recently zeroed */
	itd->hw_next = EHCI_LIST_END(ehci);
	itd->hw_bufp[0] = stream->buf0;
	itd->hw_bufp[1] = stream->buf1;
	itd->hw_bufp[2] = stream->buf2;

	for (i = 0; i < 8; i++)
		itd->index[i] = -1;

	/* All other fields are filled when scheduling */
}

static inline void
itd_patch(
	struct ehci_hcd		*ehci,
	struct ehci_itd		*itd,
	struct ehci_iso_sched	*iso_sched,
	unsigned		index,
	u16			uframe
)
{
	struct ehci_iso_packet	*uf = &iso_sched->packet[index];
	unsigned		pg = itd->pg;

	/* BUG_ON(pg == 6 && uf->cross); */

	uframe &= 0x07;
	itd->index[uframe] = index;

	itd->hw_transaction[uframe] = uf->transaction;
	itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12);
	itd->hw_bufp[pg] |= cpu_to_hc32(ehci, uf->bufp & ~(u32)0);
	itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(uf->bufp >> 32));

	/* iso_frame_desc[].offset must be strictly increasing */
	if (unlikely(uf->cross)) {
		u64	bufp = uf->bufp + 4096;

		itd->pg = ++pg;
		itd->hw_bufp[pg] |= cpu_to_hc32(ehci, bufp & ~(u32)0);
		itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(bufp >> 32));
	}
}

static inline void
itd_link(struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
{
	union ehci_shadow	*prev = &ehci->pshadow[frame];
	__hc32			*hw_p = &ehci->periodic[frame];
	union ehci_shadow	here = *prev;
	__hc32			type = 0;

	/* skip any iso nodes which might belong to previous microframes */
	while (here.ptr) {
		type = Q_NEXT_TYPE(ehci, *hw_p);
		if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
			break;
		prev = periodic_next_shadow(ehci, prev, type);
		hw_p = shadow_next_periodic(ehci, &here, type);
		here = *prev;
	}

	itd->itd_next = here;
	itd->hw_next = *hw_p;
	prev->itd = itd;
	itd->frame = frame;
	wmb();
	*hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
}

/* fit urb's itds into the selected schedule slot; activate as needed */
static void itd_link_urb(
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	unsigned		mod,
	struct ehci_iso_stream	*stream
)
{
	int			packet;
	unsigned		next_uframe, uframe, frame;
	struct ehci_iso_sched	*iso_sched = urb->hcpriv;
	struct ehci_itd		*itd;

	next_uframe = stream->next_uframe & (mod - 1);

	if (unlikely(list_empty(&stream->td_list)))
		ehci_to_hcd(ehci)->self.bandwidth_allocated
				+= stream->bandwidth;

	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
		if (ehci->amd_pll_fix == 1)
			usb_amd_quirk_pll_disable();
	}

	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;

	/* fill iTDs uframe by uframe */
	for (packet = iso_sched->first_packet, itd = NULL;
			packet < urb->number_of_packets;) {
		if (itd == NULL) {
			/* ASSERT:  we have all necessary itds */
			/* BUG_ON(list_empty(&iso_sched->td_list)); */

			/* ASSERT:  no itds for this endpoint in this uframe */

			itd = list_entry(iso_sched->td_list.next,
					struct ehci_itd, itd_list);
			list_move_tail(&itd->itd_list, &stream->td_list);
			itd->stream = stream;
			itd->urb = urb;
			itd_init(ehci, stream, itd);
		}

		uframe = next_uframe & 0x07;
		frame = next_uframe >> 3;

		itd_patch(ehci, itd, iso_sched, packet, uframe);

		next_uframe += stream->uperiod;
		next_uframe &= mod - 1;
		packet++;

		/* link completed itds into the schedule */
		if (((next_uframe >> 3) != frame)
				|| packet == urb->number_of_packets) {
			itd_link(ehci, frame & (ehci->periodic_size - 1), itd);
			itd = NULL;
		}
	}
	stream->next_uframe = next_uframe;

	/* don't need that schedule data any more */
	iso_sched_free(stream, iso_sched);
	urb->hcpriv = stream;

	++ehci->isoc_count;
	enable_periodic(ehci);
}

#define	ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)

/* Process and recycle a completed ITD.  Return true iff its urb completed,
 * and hence its completion callback probably added things to the hardware
 * schedule.
 *
 * Note that we carefully avoid recycling this descriptor until after any
 * completion callback runs, so that it won't be reused quickly.  That is,
 * assuming (a) no more than two urbs per frame on this endpoint, and also
 * (b) only this endpoint's completions submit URBs.  It seems some silicon
 * corrupts things if you reuse completed descriptors very quickly...
 */
static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd)
{
	struct urb				*urb = itd->urb;
	struct usb_iso_packet_descriptor	*desc;
	u32					t;
	unsigned				uframe;
	int					urb_index = -1;
	struct ehci_iso_stream			*stream = itd->stream;
	bool					retval = false;

	/* for each uframe with a packet */
	for (uframe = 0; uframe < 8; uframe++) {
		if (likely(itd->index[uframe] == -1))
			continue;
		urb_index = itd->index[uframe];
		desc = &urb->iso_frame_desc[urb_index];

		t = hc32_to_cpup(ehci, &itd->hw_transaction[uframe]);
		itd->hw_transaction[uframe] = 0;

		/* report transfer status */
		if (unlikely(t & ISO_ERRS)) {
			urb->error_count++;
			if (t & EHCI_ISOC_BUF_ERR)
				desc->status = usb_pipein(urb->pipe)
					? -ENOSR  /* hc couldn't read */
					: -ECOMM; /* hc couldn't write */
			else if (t & EHCI_ISOC_BABBLE)
				desc->status = -EOVERFLOW;
			else /* (t & EHCI_ISOC_XACTERR) */
				desc->status = -EPROTO;

			/* HC need not update length with this error */
			if (!(t & EHCI_ISOC_BABBLE)) {
				desc->actual_length = EHCI_ITD_LENGTH(t);
				urb->actual_length += desc->actual_length;
			}
		} else if (likely((t & EHCI_ISOC_ACTIVE) == 0)) {
			desc->status = 0;
			desc->actual_length = EHCI_ITD_LENGTH(t);
			urb->actual_length += desc->actual_length;
		} else {
			/* URB was too late */
			urb->error_count++;
		}
	}

	/* handle completion now? */
	if (likely((urb_index + 1) != urb->number_of_packets))
		goto done;

	/*
	 * ASSERT: it's really the last itd for this urb
	 * list_for_each_entry (itd, &stream->td_list, itd_list)
	 *	 BUG_ON(itd->urb == urb);
	 */

	/* give urb back to the driver; completion often (re)submits */
	ehci_urb_done(ehci, urb, 0);
	retval = true;
	urb = NULL;

	--ehci->isoc_count;
	disable_periodic(ehci);

	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
		if (ehci->amd_pll_fix == 1)
			usb_amd_quirk_pll_enable();
	}

	if (unlikely(list_is_singular(&stream->td_list)))
		ehci_to_hcd(ehci)->self.bandwidth_allocated
				-= stream->bandwidth;

done:
	itd->urb = NULL;

	/* Add to the end of the free list for later reuse */
	list_move_tail(&itd->itd_list, &stream->free_list);

	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
	if (list_empty(&stream->td_list)) {
		list_splice_tail_init(&stream->free_list,
				&ehci->cached_itd_list);
		start_free_itds(ehci);
	}

	return retval;
}

/*-------------------------------------------------------------------------*/

static int itd_submit(struct ehci_hcd *ehci, struct urb *urb,
	gfp_t mem_flags)
{
	int			status = -EINVAL;
	unsigned long		flags;
	struct ehci_iso_stream	*stream;

	/* Get iso_stream head */
	stream = iso_stream_find(ehci, urb);
	if (unlikely(stream == NULL)) {
		ehci_dbg(ehci, "can't get iso stream\n");
		return -ENOMEM;
	}
	if (unlikely(urb->interval != stream->uperiod)) {
		ehci_dbg(ehci, "can't change iso interval %d --> %d\n",
			stream->uperiod, urb->interval);
		goto done;
	}

#ifdef EHCI_URB_TRACE
	ehci_dbg(ehci,
		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
		__func__, urb->dev->devpath, urb,
		usb_pipeendpoint(urb->pipe),
		usb_pipein(urb->pipe) ? "in" : "out",
		urb->transfer_buffer_length,
		urb->number_of_packets, urb->interval,
		stream);
#endif

	/* allocate ITDs w/o locking anything */
	status = itd_urb_transaction(stream, ehci, urb, mem_flags);
	if (unlikely(status < 0)) {
		ehci_dbg(ehci, "can't init itds\n");
		goto done;
	}

	/* schedule ... need to lock */
	spin_lock_irqsave(&ehci->lock, flags);
	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
		status = -ESHUTDOWN;
		goto done_not_linked;
	}
	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
	if (unlikely(status))
		goto done_not_linked;
	status = iso_stream_schedule(ehci, urb, stream);
	if (likely(status == 0)) {
		itd_link_urb(ehci, urb, ehci->periodic_size << 3, stream);
	} else if (status > 0) {
		status = 0;
		ehci_urb_done(ehci, urb, 0);
	} else {
		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
	}
 done_not_linked:
	spin_unlock_irqrestore(&ehci->lock, flags);
 done:
	return status;
}

/*-------------------------------------------------------------------------*/

/*
 * "Split ISO TDs" ... used for USB 1.1 devices going through the
 * TTs in USB 2.0 hubs.  These need microframe scheduling.
 */

static inline void
sitd_sched_init(
	struct ehci_hcd		*ehci,
	struct ehci_iso_sched	*iso_sched,
	struct ehci_iso_stream	*stream,
	struct urb		*urb
)
{
	unsigned	i;
	dma_addr_t	dma = urb->transfer_dma;

	/* how many frames are needed for these transfers */
	iso_sched->span = urb->number_of_packets * stream->ps.period;

	/* figure out per-frame sitd fields that we'll need later
	 * when we fit new sitds into the schedule.
	 */
	for (i = 0; i < urb->number_of_packets; i++) {
		struct ehci_iso_packet	*packet = &iso_sched->packet[i];
		unsigned		length;
		dma_addr_t		buf;
		u32			trans;

		length = urb->iso_frame_desc[i].length & 0x03ff;
		buf = dma + urb->iso_frame_desc[i].offset;

		trans = SITD_STS_ACTIVE;
		if (((i + 1) == urb->number_of_packets)
				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
			trans |= SITD_IOC;
		trans |= length << 16;
		packet->transaction = cpu_to_hc32(ehci, trans);

		/* might need to cross a buffer page within a td */
		packet->bufp = buf;
		packet->buf1 = (buf + length) & ~0x0fff;
		if (packet->buf1 != (buf & ~(u64)0x0fff))
			packet->cross = 1;

		/* OUT uses multiple start-splits */
		if (stream->bEndpointAddress & USB_DIR_IN)
			continue;
		length = (length + 187) / 188;
		if (length > 1) /* BEGIN vs ALL */
			length |= 1 << 3;
		packet->buf1 |= length;
	}
}

static int
sitd_urb_transaction(
	struct ehci_iso_stream	*stream,
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	gfp_t			mem_flags
)
{
	struct ehci_sitd	*sitd;
	dma_addr_t		sitd_dma;
	int			i;
	struct ehci_iso_sched	*iso_sched;
	unsigned long		flags;

	iso_sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
	if (iso_sched == NULL)
		return -ENOMEM;

	sitd_sched_init(ehci, iso_sched, stream, urb);

	/* allocate/init sITDs */
	spin_lock_irqsave(&ehci->lock, flags);
	for (i = 0; i < urb->number_of_packets; i++) {

		/* NOTE:  for now, we don't try to handle wraparound cases
		 * for IN (using sitd->hw_backpointer, like a FSTN), which
		 * means we never need two sitds for full speed packets.
		 */

		/*
		 * Use siTDs from the free list, but not siTDs that may
		 * still be in use by the hardware.
		 */
		if (likely(!list_empty(&stream->free_list))) {
			sitd = list_first_entry(&stream->free_list,
					 struct ehci_sitd, sitd_list);
			if (sitd->frame == ehci->now_frame)
				goto alloc_sitd;
			list_del(&sitd->sitd_list);
			sitd_dma = sitd->sitd_dma;
		} else {
 alloc_sitd:
			spin_unlock_irqrestore(&ehci->lock, flags);
			sitd = dma_pool_alloc(ehci->sitd_pool, mem_flags,
					&sitd_dma);
			spin_lock_irqsave(&ehci->lock, flags);
			if (!sitd) {
				iso_sched_free(stream, iso_sched);
				spin_unlock_irqrestore(&ehci->lock, flags);
				return -ENOMEM;
			}
		}

		memset(sitd, 0, sizeof(*sitd));
		sitd->sitd_dma = sitd_dma;
		sitd->frame = NO_FRAME;
		list_add(&sitd->sitd_list, &iso_sched->td_list);
	}

	/* temporarily store schedule info in hcpriv */
	urb->hcpriv = iso_sched;
	urb->error_count = 0;

	spin_unlock_irqrestore(&ehci->lock, flags);
	return 0;
}

/*-------------------------------------------------------------------------*/

static inline void
sitd_patch(
	struct ehci_hcd		*ehci,
	struct ehci_iso_stream	*stream,
	struct ehci_sitd	*sitd,
	struct ehci_iso_sched	*iso_sched,
	unsigned		index
)
{
	struct ehci_iso_packet	*uf = &iso_sched->packet[index];
	u64			bufp;

	sitd->hw_next = EHCI_LIST_END(ehci);
	sitd->hw_fullspeed_ep = stream->address;
	sitd->hw_uframe = stream->splits;
	sitd->hw_results = uf->transaction;
	sitd->hw_backpointer = EHCI_LIST_END(ehci);

	bufp = uf->bufp;
	sitd->hw_buf[0] = cpu_to_hc32(ehci, bufp);
	sitd->hw_buf_hi[0] = cpu_to_hc32(ehci, bufp >> 32);

	sitd->hw_buf[1] = cpu_to_hc32(ehci, uf->buf1);
	if (uf->cross)
		bufp += 4096;
	sitd->hw_buf_hi[1] = cpu_to_hc32(ehci, bufp >> 32);
	sitd->index = index;
}

static inline void
sitd_link(struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
{
	/* note: sitd ordering could matter (CSPLIT then SSPLIT) */
	sitd->sitd_next = ehci->pshadow[frame];
	sitd->hw_next = ehci->periodic[frame];
	ehci->pshadow[frame].sitd = sitd;
	sitd->frame = frame;
	wmb();
	ehci->periodic[frame] = cpu_to_hc32(ehci, sitd->sitd_dma | Q_TYPE_SITD);
}

/* fit urb's sitds into the selected schedule slot; activate as needed */
static void sitd_link_urb(
	struct ehci_hcd		*ehci,
	struct urb		*urb,
	unsigned		mod,
	struct ehci_iso_stream	*stream
)
{
	int			packet;
	unsigned		next_uframe;
	struct ehci_iso_sched	*sched = urb->hcpriv;
	struct ehci_sitd	*sitd;

	next_uframe = stream->next_uframe;

	if (list_empty(&stream->td_list))
		/* usbfs ignores TT bandwidth */
		ehci_to_hcd(ehci)->self.bandwidth_allocated
				+= stream->bandwidth;

	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
		if (ehci->amd_pll_fix == 1)
			usb_amd_quirk_pll_disable();
	}

	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;

	/* fill sITDs frame by frame */
	for (packet = sched->first_packet, sitd = NULL;
			packet < urb->number_of_packets;
			packet++) {

		/* ASSERT:  we have all necessary sitds */
		BUG_ON(list_empty(&sched->td_list));

		/* ASSERT:  no itds for this endpoint in this frame */

		sitd = list_entry(sched->td_list.next,
				struct ehci_sitd, sitd_list);
		list_move_tail(&sitd->sitd_list, &stream->td_list);
		sitd->stream = stream;
		sitd->urb = urb;

		sitd_patch(ehci, stream, sitd, sched, packet);
		sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),
				sitd);

		next_uframe += stream->uperiod;
	}
	stream->next_uframe = next_uframe & (mod - 1);

	/* don't need that schedule data any more */
	iso_sched_free(stream, sched);
	urb->hcpriv = stream;

	++ehci->isoc_count;
	enable_periodic(ehci);
}

/*-------------------------------------------------------------------------*/

#define	SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \
				| SITD_STS_XACT | SITD_STS_MMF)

/* Process and recycle a completed SITD.  Return true iff its urb completed,
 * and hence its completion callback probably added things to the hardware
 * schedule.
 *
 * Note that we carefully avoid recycling this descriptor until after any
 * completion callback runs, so that it won't be reused quickly.  That is,
 * assuming (a) no more than two urbs per frame on this endpoint, and also
 * (b) only this endpoint's completions submit URBs.  It seems some silicon
 * corrupts things if you reuse completed descriptors very quickly...
 */
static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
{
	struct urb				*urb = sitd->urb;
	struct usb_iso_packet_descriptor	*desc;
	u32					t;
	int					urb_index;
	struct ehci_iso_stream			*stream = sitd->stream;
	bool					retval = false;

	urb_index = sitd->index;
	desc = &urb->iso_frame_desc[urb_index];
	t = hc32_to_cpup(ehci, &sitd->hw_results);

	/* report transfer status */
	if (unlikely(t & SITD_ERRS)) {
		urb->error_count++;
		if (t & SITD_STS_DBE)
			desc->status = usb_pipein(urb->pipe)
				? -ENOSR  /* hc couldn't read */
				: -ECOMM; /* hc couldn't write */
		else if (t & SITD_STS_BABBLE)
			desc->status = -EOVERFLOW;
		else /* XACT, MMF, etc */
			desc->status = -EPROTO;
	} else if (unlikely(t & SITD_STS_ACTIVE)) {
		/* URB was too late */
		urb->error_count++;
	} else {
		desc->status = 0;
		desc->actual_length = desc->length - SITD_LENGTH(t);
		urb->actual_length += desc->actual_length;
	}

	/* handle completion now? */
	if ((urb_index + 1) != urb->number_of_packets)
		goto done;

	/*
	 * ASSERT: it's really the last sitd for this urb
	 * list_for_each_entry (sitd, &stream->td_list, sitd_list)
	 *	 BUG_ON(sitd->urb == urb);
	 */

	/* give urb back to the driver; completion often (re)submits */
	ehci_urb_done(ehci, urb, 0);
	retval = true;
	urb = NULL;

	--ehci->isoc_count;
	disable_periodic(ehci);

	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
	if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
		if (ehci->amd_pll_fix == 1)
			usb_amd_quirk_pll_enable();
	}

	if (list_is_singular(&stream->td_list))
		ehci_to_hcd(ehci)->self.bandwidth_allocated
				-= stream->bandwidth;

done:
	sitd->urb = NULL;

	/* Add to the end of the free list for later reuse */
	list_move_tail(&sitd->sitd_list, &stream->free_list);

	/* Recycle the siTDs when the pipeline is empty (ep no longer in use) */
	if (list_empty(&stream->td_list)) {
		list_splice_tail_init(&stream->free_list,
				&ehci->cached_sitd_list);
		start_free_itds(ehci);
	}

	return retval;
}


static int sitd_submit(struct ehci_hcd *ehci, struct urb *urb,
	gfp_t mem_flags)
{
	int			status = -EINVAL;
	unsigned long		flags;
	struct ehci_iso_stream	*stream;

	/* Get iso_stream head */
	stream = iso_stream_find(ehci, urb);
	if (stream == NULL) {
		ehci_dbg(ehci, "can't get iso stream\n");
		return -ENOMEM;
	}
	if (urb->interval != stream->ps.period) {
		ehci_dbg(ehci, "can't change iso interval %d --> %d\n",
			stream->ps.period, urb->interval);
		goto done;
	}

#ifdef EHCI_URB_TRACE
	ehci_dbg(ehci,
		"submit %p dev%s ep%d%s-iso len %d\n",
		urb, urb->dev->devpath,
		usb_pipeendpoint(urb->pipe),
		usb_pipein(urb->pipe) ? "in" : "out",
		urb->transfer_buffer_length);
#endif

	/* allocate SITDs */
	status = sitd_urb_transaction(stream, ehci, urb, mem_flags);
	if (status < 0) {
		ehci_dbg(ehci, "can't init sitds\n");
		goto done;
	}

	/* schedule ... need to lock */
	spin_lock_irqsave(&ehci->lock, flags);
	if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
		status = -ESHUTDOWN;
		goto done_not_linked;
	}
	status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
	if (unlikely(status))
		goto done_not_linked;
	status = iso_stream_schedule(ehci, urb, stream);
	if (likely(status == 0)) {
		sitd_link_urb(ehci, urb, ehci->periodic_size << 3, stream);
	} else if (status > 0) {
		status = 0;
		ehci_urb_done(ehci, urb, 0);
	} else {
		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
	}
 done_not_linked:
	spin_unlock_irqrestore(&ehci->lock, flags);
 done:
	return status;
}

/*-------------------------------------------------------------------------*/

static void scan_isoc(struct ehci_hcd *ehci)
{
	unsigned		uf, now_frame, frame;
	unsigned		fmask = ehci->periodic_size - 1;
	bool			modified, live;
	union ehci_shadow	q, *q_p;
	__hc32			type, *hw_p;

	/*
	 * When running, scan from last scan point up to "now"
	 * else clean up by scanning everything that's left.
	 * Touches as few pages as possible:  cache-friendly.
	 */
	if (ehci->rh_state >= EHCI_RH_RUNNING) {
		uf = ehci_read_frame_index(ehci);
		now_frame = (uf >> 3) & fmask;
		live = true;
	} else  {
		now_frame = (ehci->last_iso_frame - 1) & fmask;
		live = false;
	}
	ehci->now_frame = now_frame;

	frame = ehci->last_iso_frame;

restart:
	/* Scan each element in frame's queue for completions */
	q_p = &ehci->pshadow[frame];
	hw_p = &ehci->periodic[frame];
	q.ptr = q_p->ptr;
	type = Q_NEXT_TYPE(ehci, *hw_p);
	modified = false;

	while (q.ptr != NULL) {
		switch (hc32_to_cpu(ehci, type)) {
		case Q_TYPE_ITD:
			/*
			 * If this ITD is still active, leave it for
			 * later processing ... check the next entry.
			 * No need to check for activity unless the
			 * frame is current.
			 */
			if (frame == now_frame && live) {
				rmb();
				for (uf = 0; uf < 8; uf++) {
					if (q.itd->hw_transaction[uf] &
							ITD_ACTIVE(ehci))
						break;
				}
				if (uf < 8) {
					q_p = &q.itd->itd_next;
					hw_p = &q.itd->hw_next;
					type = Q_NEXT_TYPE(ehci,
							q.itd->hw_next);
					q = *q_p;
					break;
				}
			}

			/*
			 * Take finished ITDs out of the schedule
			 * and process them:  recycle, maybe report
			 * URB completion.  HC won't cache the
			 * pointer for much longer, if at all.
			 */
			*q_p = q.itd->itd_next;
			if (!ehci->use_dummy_qh ||
					q.itd->hw_next != EHCI_LIST_END(ehci))
				*hw_p = q.itd->hw_next;
			else
				*hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma);
			type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
			wmb();
			modified = itd_complete(ehci, q.itd);
			q = *q_p;
			break;
		case Q_TYPE_SITD:
			/*
			 * If this SITD is still active, leave it for
			 * later processing ... check the next entry.
			 * No need to check for activity unless the
			 * frame is current.
			 */
			if (((frame == now_frame) ||
					(((frame + 1) & fmask) == now_frame))
				&& live
				&& (q.sitd->hw_results & SITD_ACTIVE(ehci))) {

				q_p = &q.sitd->sitd_next;
				hw_p = &q.sitd->hw_next;
				type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
				q = *q_p;
				break;
			}

			/*
			 * Take finished SITDs out of the schedule
			 * and process them:  recycle, maybe report
			 * URB completion.
			 */
			*q_p = q.sitd->sitd_next;
			if (!ehci->use_dummy_qh ||
					q.sitd->hw_next != EHCI_LIST_END(ehci))
				*hw_p = q.sitd->hw_next;
			else
				*hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma);
			type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
			wmb();
			modified = sitd_complete(ehci, q.sitd);
			q = *q_p;
			break;
		default:
			ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n",
					type, frame, q.ptr);
			/* BUG(); */
			fallthrough;
		case Q_TYPE_QH:
		case Q_TYPE_FSTN:
			/* End of the iTDs and siTDs */
			q.ptr = NULL;
			break;
		}

		/* Assume completion callbacks modify the queue */
		if (unlikely(modified && ehci->isoc_count > 0))
			goto restart;
	}

	/* Stop when we have reached the current frame */
	if (frame == now_frame)
		return;

	/* The last frame may still have active siTDs */
	ehci->last_iso_frame = frame;
	frame = (frame + 1) & fmask;

	goto restart;
}
