Skip to content

Commit

Permalink
USB: EHCI: create per-TT bandwidth tables
Browse files Browse the repository at this point in the history
This patch continues the scheduling changes in ehci-hcd by adding a
table to store the bandwidth allocation below each TT.  This will
speed up the scheduling code, as it will no longer need to read
through the entire schedule to compute the bandwidth currently in use.

Properly speaking, the FS/LS budget calculations should be done in
terms of full-speed bytes per microframe, as described in the USB-2
spec.  However the driver currently uses microseconds per microframe,
and the scheduling code isn't robust enough at this point to change
over.  For the time being, we leave the calculations as they are.

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 14, 2013
1 parent ca1ad0f commit b35c500
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 85 deletions.
48 changes: 48 additions & 0 deletions drivers/usb/host/ehci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,14 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf)
{
struct ehci_hcd *ehci;
struct ehci_tt *tt;
struct ehci_per_sched *ps;
unsigned temp, size;
char *next;
unsigned i;
u8 *bw;
u16 *bf;
u8 budget[EHCI_BANDWIDTH_SIZE];

ehci = hcd_to_ehci(bus_to_hcd(buf->bus));
next = buf->output_buf;
Expand All @@ -563,6 +567,50 @@ static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf)
size -= temp;
next += temp;
}

/* Dump all the FS/LS tables */
list_for_each_entry(tt, &ehci->tt_list, tt_list) {
temp = scnprintf(next, size,
"\nTT %s port %d FS/LS bandwidth allocation (us per frame)\n",
dev_name(&tt->usb_tt->hub->dev),
tt->tt_port + !!tt->usb_tt->multi);
size -= temp;
next += temp;

bf = tt->bandwidth;
temp = scnprintf(next, size,
" %5u%5u%5u%5u%5u%5u%5u%5u\n",
bf[0], bf[1], bf[2], bf[3],
bf[4], bf[5], bf[6], bf[7]);
size -= temp;
next += temp;

temp = scnprintf(next, size,
"FS/LS budget (us per microframe)\n");
size -= temp;
next += temp;
compute_tt_budget(budget, tt);
for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
bw = &budget[i];
temp = scnprintf(next, size,
"%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
i, bw[0], bw[1], bw[2], bw[3],
bw[4], bw[5], bw[6], bw[7]);
size -= temp;
next += temp;
}
list_for_each_entry(ps, &tt->ps_list, ps_list) {
temp = scnprintf(next, size,
"%s ep %02x: %4u @ %2u.%u+%u mask %04x\n",
dev_name(&ps->udev->dev),
ps->ep->desc.bEndpointAddress,
ps->tt_usecs,
ps->bw_phase, ps->phase_uf,
ps->bw_period, ps->cs_mask);
size -= temp;
next += temp;
}
}
spin_unlock_irq(&ehci->lock);

return next - buf->output_buf;
Expand Down
22 changes: 22 additions & 0 deletions drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
#include "ehci.h"
#include "pci-quirks.h"

static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE],
struct ehci_tt *tt);

/*
* The MosChip MCS9990 controller updates its microframe counter
* a little before the frame counter, and occasionally we will read
Expand Down Expand Up @@ -484,6 +487,7 @@ static int ehci_init(struct usb_hcd *hcd)
INIT_LIST_HEAD(&ehci->intr_qh_list);
INIT_LIST_HEAD(&ehci->cached_itd_list);
INIT_LIST_HEAD(&ehci->cached_sitd_list);
INIT_LIST_HEAD(&ehci->tt_list);

if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
/* periodic schedule size can be smaller than default */
Expand Down Expand Up @@ -1051,6 +1055,19 @@ static int ehci_get_frame (struct usb_hcd *hcd)

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

/* Device addition and removal */

static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);

spin_lock_irq(&ehci->lock);
drop_tt(udev);
spin_unlock_irq(&ehci->lock);
}

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

#ifdef CONFIG_PM

/* suspend/resume, section 4.3 */
Expand Down Expand Up @@ -1194,6 +1211,11 @@ static const struct hc_driver ehci_hc_driver = {
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,

/*
* device support
*/
.free_dev = ehci_remove_device,
};

void ehci_init_driver(struct hc_driver *drv,
Expand Down
Loading

0 comments on commit b35c500

Please sign in to comment.