is_out = qh->is_out;
                epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
-               if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+               if (unlikely(!usb_gettoggle(qh->ps.udev, epnum, is_out))) {
                        hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
-                       usb_settoggle (qh->dev, epnum, is_out, 1);
+                       usb_settoggle(qh->ps.udev, epnum, is_out, 1);
                }
        }
 
         * For control/bulk requests, the HC or TT handles these.
         */
        if (type == PIPE_INTERRUPT) {
-               qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
+               qh->ps.usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
                                is_input, 0,
                                hb_mult(maxp) * max_packet(maxp)));
-               qh->start = NO_FRAME;
+               qh->ps.phase = NO_FRAME;
 
                if (urb->dev->speed == USB_SPEED_HIGH) {
-                       qh->c_usecs = 0;
+                       qh->ps.c_usecs = 0;
                        qh->gap_uf = 0;
 
-                       qh->period = urb->interval >> 3;
-                       if (qh->period == 0 && urb->interval != 1) {
+                       if (urb->interval > 1 && urb->interval < 8) {
                                /* NOTE interval 2 or 4 uframes could work.
                                 * But interval 1 scheduling is simpler, and
                                 * includes high bandwidth.
                                 */
                                urb->interval = 1;
-                       } else if (qh->period > ehci->periodic_size) {
-                               qh->period = ehci->periodic_size;
-                               urb->interval = qh->period << 3;
+                       } else if (urb->interval > ehci->periodic_size << 3) {
+                               urb->interval = ehci->periodic_size << 3;
                        }
+                       qh->ps.period = urb->interval >> 3;
                } else {
                        int             think_time;
 
 
                        /* FIXME this just approximates SPLIT/CSPLIT times */
                        if (is_input) {         // SPLIT, gap, CSPLIT+DATA
-                               qh->c_usecs = qh->usecs + HS_USECS (0);
-                               qh->usecs = HS_USECS (1);
+                               qh->ps.c_usecs = qh->ps.usecs + HS_USECS(0);
+                               qh->ps.usecs = HS_USECS(1);
                        } else {                // SPLIT+DATA, gap, CSPLIT
-                               qh->usecs += HS_USECS (1);
-                               qh->c_usecs = HS_USECS (0);
+                               qh->ps.usecs += HS_USECS(1);
+                               qh->ps.c_usecs = HS_USECS(0);
                        }
 
                        think_time = tt ? tt->think_time : 0;
-                       qh->tt_usecs = NS_TO_US (think_time +
+                       qh->ps.tt_usecs = NS_TO_US(think_time +
                                        usb_calc_bus_time (urb->dev->speed,
                                        is_input, 0, max_packet (maxp)));
-                       qh->period = urb->interval;
-                       if (qh->period > ehci->periodic_size) {
-                               qh->period = ehci->periodic_size;
-                               urb->interval = qh->period;
-                       }
+                       if (urb->interval > ehci->periodic_size)
+                               urb->interval = ehci->periodic_size;
+                       qh->ps.period = urb->interval;
                }
        }
 
        /* support for tt scheduling, and access to toggles */
-       qh->dev = urb->dev;
+       qh->ps.udev = urb->dev;
+       qh->ps.ep = urb->ep;
 
        /* using TT? */
        switch (urb->dev->speed) {
 
                        hw = q->qh->hw;
                        /* is it in the S-mask? */
                        if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
-                               usecs += q->qh->usecs;
+                               usecs += q->qh->ps.usecs;
                        /* ... or C-mask? */
                        if (hw->hw_info2 & cpu_to_hc32(ehci,
                                        1 << (8 + uframe)))
-                               usecs += q->qh->c_usecs;
+                               usecs += q->qh->ps.c_usecs;
                        hw_p = &hw->hw_next;
                        q = &q->qh->qh_next;
                        break;
                        break;
                case Q_TYPE_ITD:
                        if (q->itd->hw_transaction[uframe])
-                               usecs += q->itd->stream->usecs;
+                               usecs += q->itd->stream->ps.usecs;
                        hw_p = &q->itd->hw_next;
                        q = &q->itd->itd_next;
                        break;
                                        1 << uframe)) {
                                if (q->sitd->hw_fullspeed_ep &
                                                cpu_to_hc32(ehci, 1<<31))
-                                       usecs += q->sitd->stream->usecs;
+                                       usecs += q->sitd->stream->ps.usecs;
                                else    /* worst case for OUT start-split */
                                        usecs += HS_USECS_ISO (188);
                        }
                        if (q->sitd->hw_uframe &
                                        cpu_to_hc32(ehci, 1 << (8 + uframe))) {
                                /* worst case for IN complete-split */
-                               usecs += q->sitd->stream->c_usecs;
+                               usecs += q->sitd->stream->ps.c_usecs;
                        }
 
                        hw_p = &q->sitd->hw_next;
                        q = &q->itd->itd_next;
                        continue;
                case Q_TYPE_QH:
-                       if (same_tt(dev, q->qh->dev)) {
+                       if (same_tt(dev, q->qh->ps.udev)) {
                                uf = tt_start_uframe(ehci, q->qh->hw->hw_info2);
-                               tt_usecs[uf] += q->qh->tt_usecs;
+                               tt_usecs[uf] += q->qh->ps.tt_usecs;
                        }
                        hw_p = &q->qh->hw->hw_next;
                        q = &q->qh->qh_next;
                case Q_TYPE_SITD:
                        if (same_tt(dev, q->sitd->urb->dev)) {
                                uf = tt_start_uframe(ehci, q->sitd->hw_uframe);
-                               tt_usecs[uf] += q->sitd->stream->tt_usecs;
+                               tt_usecs[uf] += q->sitd->stream->ps.tt_usecs;
                        }
                        hw_p = &q->sitd->hw_next;
                        q = &q->sitd->sitd_next;
                                continue;
                        case Q_TYPE_QH:
                                hw = here.qh->hw;
-                               if (same_tt (dev, here.qh->dev)) {
+                               if (same_tt(dev, here.qh->ps.udev)) {
                                        u32             mask;
 
                                        mask = hc32_to_cpu(ehci,
 static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        unsigned        i;
-       unsigned        period = qh->period;
+       unsigned        period = qh->ps.period;
 
-       dev_dbg (&qh->dev->dev,
+       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->start, qh->usecs, qh->c_usecs);
+               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->start; i < ehci->periodic_size; i += period) {
+       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;
                 * enables sharing interior tree nodes
                 */
                while (here.ptr && qh != here.qh) {
-                       if (qh->period > here.qh->period)
+                       if (qh->ps.period > here.qh->ps.period)
                                break;
                        prev = &here.qh->qh_next;
                        hw_p = &here.qh->hw->hw_next;
        qh->xacterrs = 0;
        qh->exception = 0;
 
-       /* update per-qh bandwidth for usbfs */
-       ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period
-               ? ((qh->usecs + qh->c_usecs) / qh->period)
-               : (qh->usecs * 8);
+       /* update per-qh bandwidth for debugfs */
+       ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->ps.period
+               ? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.period)
+               : (qh->ps.usecs * 8);
 
        list_add(&qh->intr_node, &ehci->intr_qh_list);
 
         */
 
        /* high bandwidth, or otherwise part of every microframe */
-       if ((period = qh->period) == 0)
-               period = 1;
+       period = qh->ps.period ? : 1;
 
-       for (i = qh->start; i < ehci->periodic_size; i += period)
+       for (i = qh->ps.phase; i < ehci->periodic_size; i += period)
                periodic_unlink (ehci, i, qh);
 
-       /* update per-qh bandwidth for usbfs */
-       ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period
-               ? ((qh->usecs + qh->c_usecs) / qh->period)
-               : (qh->usecs * 8);
+       /* update per-qh bandwidth for debugfs */
+       ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->ps.period
+               ? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.period)
+               : (qh->ps.usecs * 8);
 
-       dev_dbg (&qh->dev->dev,
+       dev_dbg(&qh->ps.udev->dev,
                "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-               qh->period,
+               qh->ps.period,
                hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
-               qh, qh->start, qh->usecs, qh->c_usecs);
+               qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
 
        /* qh->qh_next still "live" to HC */
        qh->qh_state = QH_STATE_UNLINK;
        int             retval = -ENOSPC;
        u8              mask = 0;
 
-       if (qh->c_usecs && uframe >= 6)         /* FSTN territory? */
+       if (qh->ps.c_usecs && uframe >= 6)      /* FSTN territory? */
                goto done;
 
-       if (!check_period (ehci, frame, uframe, qh->period, qh->usecs))
+       if (!check_period(ehci, frame, uframe, qh->ps.period, qh->ps.usecs))
                goto done;
-       if (!qh->c_usecs) {
+       if (!qh->ps.c_usecs) {
                retval = 0;
                *c_maskp = 0;
                goto done;
        }
 
 #ifdef CONFIG_USB_EHCI_TT_NEWSCHED
-       if (tt_available (ehci, qh->period, qh->dev, frame, uframe,
-                               qh->tt_usecs)) {
+       if (tt_available(ehci, qh->ps.period, qh->ps.udev, frame, uframe,
+                               qh->ps.tt_usecs)) {
                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->period, qh->c_usecs))
+                       if (!check_period(ehci, frame, i,
+                                       qh->ps.period, qh->ps.c_usecs))
                                goto done;
                        else
                                mask |= 1 << i;
        *c_maskp = cpu_to_hc32(ehci, mask << 8);
 
        mask |= 1 << uframe;
-       if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
-               if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
-                                       qh->period, qh->c_usecs))
+       if (tt_no_collision(ehci, qh->ps.period, qh->ps.udev, frame, mask)) {
+               if (!check_period(ehci, frame, uframe + qh->gap_uf + 1,
+                               qh->ps.period, qh->ps.c_usecs))
                        goto done;
-               if (!check_period (ehci, frame, uframe + qh->gap_uf,
-                                       qh->period, qh->c_usecs))
+               if (!check_period(ehci, frame, uframe + qh->gap_uf,
+                               qh->ps.period, qh->ps.c_usecs))
                        goto done;
                retval = 0;
        }
        struct ehci_qh_hw       *hw = qh->hw;
 
        hw->hw_next = EHCI_LIST_END(ehci);
-       frame = qh->start;
+       frame = qh->ps.phase;
 
        /* reuse the previous schedule slots, if we can */
        if (frame != NO_FRAME) {
         */
        if (status) {
                /* "normal" case, uframing flexible except with splits */
-               if (qh->period) {
+               if (qh->ps.period) {
                        int             i;
 
-                       for (i = qh->period; status && i > 0; --i) {
-                               frame = ++ehci->random_frame % qh->period;
+                       for (i = qh->ps.period; status && i > 0; --i) {
+                               frame = ++ehci->random_frame % qh->ps.period;
                                for (uframe = 0; uframe < 8; uframe++) {
                                        status = check_intr_schedule (ehci,
                                                        frame, uframe, qh,
                                }
                        }
 
-               /* qh->period == 0 means every uframe */
+               /* qh->ps.period == 0 means every uframe */
                } else {
                        frame = 0;
                        status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);
                }
                if (status)
                        goto done;
-               qh->start = frame;
+               qh->ps.phase = frame;
 
                /* reset S-frame and (maybe) C-frame masks */
                hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
-               hw->hw_info2 |= qh->period
+               hw->hw_info2 |= qh->ps.period
                        ? cpu_to_hc32(ehci, 1 << uframe)
                        : cpu_to_hc32(ehci, QH_SMASK);
                hw->hw_info2 |= c_mask;
 iso_stream_init (
        struct ehci_hcd         *ehci,
        struct ehci_iso_stream  *stream,
-       struct usb_device       *dev,
-       int                     pipe,
-       unsigned                interval
+       struct urb              *urb
 )
 {
        static const u8 smask_out [] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f };
 
+       struct usb_device       *dev = urb->dev;
+       unsigned                interval = urb->interval;
        u32                     buf1;
        unsigned                epnum, maxp;
        int                     is_input;
-       long                    bandwidth;
 
        /*
         * this might be a "high bandwidth" highspeed endpoint,
         * as encoded in the ep descriptor's wMaxPacket field
         */
-       epnum = usb_pipeendpoint (pipe);
-       is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
-       maxp = usb_maxpacket(dev, pipe, !is_input);
+       epnum = usb_pipeendpoint(urb->pipe);
+       is_input = usb_pipein(urb->pipe) ? USB_DIR_IN : 0;
+       maxp = usb_endpoint_maxp(&urb->ep->desc);
        if (is_input) {
                buf1 = (1 << 11);
        } else {
                /* usbfs wants to report the average usecs per frame tied up
                 * when transfers on this endpoint are scheduled ...
                 */
-               stream->usecs = HS_USECS_ISO (maxp);
-               bandwidth = stream->usecs * 8;
-               bandwidth /= interval;
+               stream->ps.usecs = HS_USECS_ISO(maxp);
+
+               stream->bandwidth = stream->ps.usecs * 8 / interval;
+               stream->uperiod = interval;
+               stream->ps.period = interval >> 3;
 
        } else {
                u32             addr;
                        addr |= dev->tt->hub->devnum << 16;
                addr |= epnum << 8;
                addr |= dev->devnum;
-               stream->usecs = HS_USECS_ISO (maxp);
+               stream->ps.usecs = HS_USECS_ISO(maxp);
                think_time = dev->tt ? dev->tt->think_time : 0;
-               stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_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->c_usecs = stream->usecs;
-                       stream->usecs = HS_USECS_ISO (1);
+                       stream->ps.c_usecs = stream->ps.usecs;
+                       stream->ps.usecs = HS_USECS_ISO(1);
                        stream->raw_mask = 1;
 
                        /* c-mask as specified in USB 2.0 11.18.4 3.c */
                        stream->raw_mask |= tmp << (8 + 2);
                } else
                        stream->raw_mask = smask_out [hs_transfers - 1];
-               bandwidth = stream->usecs + stream->c_usecs;
-               bandwidth /= interval;
+
+               stream->bandwidth = (stream->ps.usecs + stream->ps.c_usecs) /
+                               interval;
+               stream->uperiod = interval << 3;
+               stream->ps.period = interval;
 
                /* stream->splits gets created from raw_mask later */
                stream->address = cpu_to_hc32(ehci, addr);
        }
-       stream->bandwidth = bandwidth;
 
-       stream->udev = dev;
+       stream->ps.udev = dev;
+       stream->ps.ep = urb->ep;
 
        stream->bEndpointAddress = is_input | epnum;
-       stream->interval = interval;
        stream->maxp = maxp;
 }
 
                stream = iso_stream_alloc(GFP_ATOMIC);
                if (likely (stream != NULL)) {
                        ep->hcpriv = stream;
-                       stream->ep = ep;
-                       iso_stream_init(ehci, stream, urb->dev, urb->pipe,
-                                       urb->interval);
+                       iso_stream_init(ehci, stream, urb);
                }
 
        /* if dev->ep [epnum] is a QH, hw is set */
        dma_addr_t      dma = urb->transfer_dma;
 
        /* how many uframes are needed for these transfers */
-       iso_sched->span = urb->number_of_packets * stream->interval;
+       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.
         */
        uf = uframe & 7;
        if (!tt_available(ehci, period_uframes >> 3,
-                       stream->udev, frame, uf, stream->tt_usecs))
+                       stream->ps.udev, frame, uf, stream->ps.tt_usecs))
                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, period_uframes >> 3,
-                       stream->udev, frame, mask))
+                       stream->ps.udev, frame, mask))
                return 0;
 #endif
 
                uf = uframe & 7;
 
                /* check starts (OUT uses more than one) */
-               max_used = ehci->uframe_periodic_max - stream->usecs;
+               max_used = ehci->uframe_periodic_max - stream->ps.usecs;
                for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) {
                        if (periodic_usecs (ehci, frame, uf) > max_used)
                                return 0;
                }
 
                /* for IN, check CSPLIT */
-               if (stream->c_usecs) {
+               if (stream->ps.c_usecs) {
                        uf = uframe & 7;
-                       max_used = ehci->uframe_periodic_max - stream->c_usecs;
+                       max_used = ehci->uframe_periodic_max -
+                                       stream->ps.c_usecs;
                        do {
                                tmp = 1 << uf;
                                tmp <<= 8;
                        /* check schedule: enough space? */
                        if (stream->highspeed) {
                                if (itd_slot_ok(ehci, mod, start,
-                                               stream->usecs, period))
+                                               stream->ps.usecs, period))
                                        done = 1;
                        } else {
                                if ((start % 8) >= 6)
 
                itd_patch(ehci, itd, iso_sched, packet, uframe);
 
-               next_uframe += stream->interval;
+               next_uframe += stream->uperiod;
                next_uframe &= mod - 1;
                packet++;
 
                ehci_dbg (ehci, "can't get iso stream\n");
                return -ENOMEM;
        }
-       if (unlikely (urb->interval != stream->interval)) {
+       if (unlikely(urb->interval != stream->uperiod)) {
                ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
-                       stream->interval, urb->interval);
+                       stream->uperiod, urb->interval);
                goto done;
        }
 
        dma_addr_t      dma = urb->transfer_dma;
 
        /* how many frames are needed for these transfers */
-       iso_sched->span = urb->number_of_packets * stream->interval;
+       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.
                sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),
                                sitd);
 
-               next_uframe += stream->interval << 3;
+               next_uframe += stream->uperiod;
        }
        stream->next_uframe = next_uframe & (mod - 1);
 
                ehci_dbg (ehci, "can't get iso stream\n");
                return -ENOMEM;
        }
-       if (urb->interval != stream->interval) {
+       if (urb->interval != stream->ps.period) {
                ehci_dbg (ehci, "can't change iso interval %d --> %d\n",
-                       stream->interval, urb->interval);
+                       stream->ps.period, urb->interval);
                goto done;
        }