Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 46658
b: refs/heads/master
c: f3fe239
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Feb 7, 2007
1 parent e3b82fb commit 229488e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f38649fee955c19f4df9b9e7267f87702712d973
refs/heads/master: f3fe239b67424d88104e32076aec902c0642925f
48 changes: 43 additions & 5 deletions trunk/drivers/usb/host/uhci-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
struct uhci_qh *qh;
struct uhci_td *td;
struct list_head *tmp, *head;
int nframes, nerrs;

out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
out += sprintf(out, "HC status\n");
Expand All @@ -355,23 +356,60 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
return out - buf;

out += sprintf(out, "Frame List\n");
nframes = 10;
nerrs = 0;
for (i = 0; i < UHCI_NUMFRAMES; ++i) {
__le32 link, qh_dma;

j = 0;
td = uhci->frame_cpu[i];
link = uhci->frame[i];
if (!td)
continue;
goto check_link;

out += sprintf(out, "- Frame %d\n", i); \
if (td->dma_handle != (dma_addr_t)uhci->frame[i])
out += sprintf(out, " frame list does not match td->dma_handle!\n");
if (nframes > 0) {
out += sprintf(out, "- Frame %d -> (%08x)\n",
i, le32_to_cpu(link));
j = 1;
}

head = &td->fl_list;
tmp = head;
do {
td = list_entry(tmp, struct uhci_td, fl_list);
tmp = tmp->next;
out += uhci_show_td(td, out, len - (out - buf), 4);
if (cpu_to_le32(td->dma_handle) != link) {
if (nframes > 0)
out += sprintf(out, " link does "
"not match list entry!\n");
else
++nerrs;
}
if (nframes > 0)
out += uhci_show_td(td, out,
len - (out - buf), 4);
link = td->link;
} while (tmp != head);

check_link:
qh_dma = uhci_frame_skel_link(uhci, i);
if (link != qh_dma) {
if (nframes > 0) {
if (!j) {
out += sprintf(out,
"- Frame %d -> (%08x)\n",
i, le32_to_cpu(link));
j = 1;
}
out += sprintf(out, " link does not match "
"QH (%08x)!\n", le32_to_cpu(qh_dma));
} else
++nerrs;
}
nframes -= j;
}
if (nerrs > 0)
out += sprintf(out, "Skipped %d bad links\n", nerrs);

out += sprintf(out, "Skeleton QHs\n");

Expand Down
51 changes: 29 additions & 22 deletions trunk/drivers/usb/host/uhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,34 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
static void wakeup_rh(struct uhci_hcd *uhci);
static void uhci_get_current_frame_number(struct uhci_hcd *uhci);

/*
* Calculate the link pointer DMA value for the first Skeleton QH in a frame.
*/
static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
{
int skelnum;

/*
* The interrupt queues will be interleaved as evenly as possible.
* There's not much to be done about period-1 interrupts; they have
* to occur in every frame. But we can schedule period-2 interrupts
* in odd-numbered frames, period-4 interrupts in frames congruent
* to 2 (mod 4), and so on. This way each frame only has two
* interrupt QHs, which will help spread out bandwidth utilization.
*
* ffs (Find First bit Set) does exactly what we need:
* 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8],
* 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
* ffs >= 7 => not on any high-period queue, so use
* skel_int1_qh = skelqh[9].
* Add in UHCI_NUMFRAMES to insure at least one bit is set.
*/
skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
if (skelnum <= 1)
skelnum = 9;
return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle);
}

#include "uhci-debug.c"
#include "uhci-q.c"
#include "uhci-hub.c"
Expand Down Expand Up @@ -631,32 +659,11 @@ static int uhci_start(struct usb_hcd *hcd)
/*
* Fill the frame list: make all entries point to the proper
* interrupt queue.
*
* The interrupt queues will be interleaved as evenly as possible.
* There's not much to be done about period-1 interrupts; they have
* to occur in every frame. But we can schedule period-2 interrupts
* in odd-numbered frames, period-4 interrupts in frames congruent
* to 2 (mod 4), and so on. This way each frame only has two
* interrupt QHs, which will help spread out bandwidth utilization.
*/
for (i = 0; i < UHCI_NUMFRAMES; i++) {
int irq;

/*
* ffs (Find First bit Set) does exactly what we need:
* 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8],
* 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
* ffs >= 7 => not on any high-period queue, so use
* skel_int1_qh = skelqh[9].
* Add UHCI_NUMFRAMES to insure at least one bit is set.
*/
irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES);
if (irq <= 1)
irq = 9;

/* Only place we don't use the frame list routines */
uhci->frame[i] = UHCI_PTR_QH |
cpu_to_le32(uhci->skelqh[irq]->dma_handle);
uhci->frame[i] = uhci_frame_skel_link(uhci, i);
}

/*
Expand Down

0 comments on commit 229488e

Please sign in to comment.