Skip to content

Commit

Permalink
UHCI: fix bandwidth allocation
Browse files Browse the repository at this point in the history
This patch (as840) fixes the bandwidth allocation mechanism in
uhci-hcd.  It has never worked correctly.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Feb 7, 2007
1 parent 6a6c957 commit 3ca2a32
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 69 deletions.
21 changes: 18 additions & 3 deletions drivers/usb/host/uhci-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
space, "", qh, qtype,
le32_to_cpu(qh->link), le32_to_cpu(element));
if (qh->type == USB_ENDPOINT_XFER_ISOC)
out += sprintf(out, "%*s period %d frame %x desc [%p]\n",
space, "", qh->period, qh->iso_frame,
qh->iso_packet_desc);
out += sprintf(out, "%*s period %d phase %d load %d us, "
"frame %x desc [%p]\n",
space, "", qh->period, qh->phase, qh->load,
qh->iso_frame, qh->iso_packet_desc);
else if (qh->type == USB_ENDPOINT_XFER_INT)
out += sprintf(out, "%*s period %d phase %d load %d us\n",
space, "", qh->period, qh->phase, qh->load);

if (element & UHCI_PTR_QH)
out += sprintf(out, "%*s Element points to QH (bug?)\n", space, "");
Expand Down Expand Up @@ -352,6 +356,17 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
out += sprintf(out, "HC status\n");
out += uhci_show_status(uhci, out, len - (out - buf));

out += sprintf(out, "Periodic load table\n");
for (i = 0; i < MAX_PHASE; ++i) {
out += sprintf(out, "\t%d", uhci->load[i]);
if (i % 8 == 7)
*out++ = '\n';
}
out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n",
uhci->total_load,
uhci_to_hcd(uhci)->self.bandwidth_int_reqs,
uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs);
if (debug <= 1)
return out - buf;

Expand Down
8 changes: 8 additions & 0 deletions drivers/usb/host/uhci-hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames
* can be scheduled */
#define MAX_PHASE 32 /* Periodic scheduling length */

/* When no queues need Full-Speed Bandwidth Reclamation,
* delay this long before turning FSBR off */
Expand Down Expand Up @@ -141,6 +142,8 @@ struct uhci_qh {
unsigned long advance_jiffies; /* Time of last queue advance */
unsigned int unlink_frame; /* When the QH was unlinked */
unsigned int period; /* For Interrupt and Isochronous QHs */
short phase; /* Between 0 and period-1 */
short load; /* Periodic time requirement, in us */
unsigned int iso_frame; /* Frame # for iso_packet_desc */
int iso_status; /* Status for Isochronous URBs */

Expand All @@ -153,6 +156,8 @@ struct uhci_qh {
unsigned int needs_fixup:1; /* Must fix the TD toggle values */
unsigned int is_stopped:1; /* Queue was stopped by error/unlink */
unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */
unsigned int bandwidth_reserved:1; /* Periodic bandwidth has
* been allocated */
} __attribute__((aligned(16)));

/*
Expand Down Expand Up @@ -414,6 +419,9 @@ struct uhci_hcd {

wait_queue_head_t waitqh; /* endpoint_disable waiters */
int num_waiting; /* Number of waiters */

int total_load; /* Sum of array values */
short load[MAX_PHASE]; /* Periodic allocations */
};

/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
Expand Down
Loading

0 comments on commit 3ca2a32

Please sign in to comment.