Skip to content

Commit

Permalink
USB: EHCI: create a "periodic schedule info" struct
Browse files Browse the repository at this point in the history
This patch begins the process of unifying the scheduling parameters
that ehci-hcd uses for interrupt and isochronous transfers.  It
creates an ehci_per_sched structure, which will be stored in both
ehci_qh and ehci_iso_stream structures, and will contain the common
scheduling information needed for both.

Initially we merely create the new structure and move some existing
fields into it.  Later patches will add more fields and utilize these
structures in improved scheduling algorithms.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Oct 11, 2013
1 parent 91a99b5 commit ffa0248
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 121 deletions.
7 changes: 4 additions & 3 deletions drivers/usb/host/ehci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
case Q_TYPE_QH:
hw = p.qh->hw;
temp = scnprintf (next, size, " qh%d-%04x/%p",
p.qh->period,
p.qh->ps.period,
hc32_to_cpup(ehci,
&hw->hw_info2)
/* uframe masks */
Expand Down Expand Up @@ -618,7 +618,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
speed_char (scratch),
scratch & 0x007f,
(scratch >> 8) & 0x000f, type,
p.qh->usecs, p.qh->c_usecs,
p.qh->ps.usecs,
p.qh->ps.c_usecs,
temp,
0x7ff & (scratch >> 16));

Expand All @@ -645,7 +646,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
case Q_TYPE_SITD:
temp = scnprintf (next, size,
" sitd%d-%04x/%p",
p.sitd->stream->interval,
p.sitd->stream->ps.period,
hc32_to_cpup(ehci, &p.sitd->hw_uframe)
& 0x0000ffff,
p.sitd);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
* while the QH is active. Unlink it now;
* re-linking will call qh_refresh().
*/
usb_settoggle(qh->dev, epnum, is_out, 0);
usb_settoggle(qh->ps.udev, epnum, is_out, 0);
qh->exception = 1;
if (eptype == USB_ENDPOINT_XFER_BULK)
start_unlink_async(ehci, qh);
Expand Down
40 changes: 19 additions & 21 deletions drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)

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);
}
}

Expand Down Expand Up @@ -797,26 +797,25 @@ qh_make (
* 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;

Expand All @@ -826,27 +825,26 @@ qh_make (

/* 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) {
Expand Down
Loading

0 comments on commit ffa0248

Please sign in to comment.