These patches are against kernels 2.6.18 through at least 2.6.18-git7.
patch 11: adds necessary calls such that the shadow budget is actively
maintained, but the rest of the scheduler is not yet using the shadow
budget to make any decisions.
Signed-off-by: Christopher "Monty" Montgomery <[EMAIL PROTECTED]>
---
diff -X b/Documentation/dontdiff -upr a/drivers/usb/host/ehci-hcd.c
b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c 2006-09-26 22:19:16.000000000 -0400
+++ b/drivers/usb/host/ehci-hcd.c 2006-09-26 22:30:54.000000000 -0400
@@ -255,6 +255,8 @@ static void ehci_quiesce (struct ehci_hc
/*-------------------------------------------------------------------------*/
static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs);
+static void budget_unlink_entries_by_owner(struct ehci_hcd *ehci,void *owner);
+static unsigned sched_verbose = 0;
#include "ehci-hub.c"
#include "ehci-mem.c"
diff -X b/Documentation/dontdiff -upr a/drivers/usb/host/ehci-mem.c
b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c 2006-09-26 22:30:47.000000000 -0400
+++ b/drivers/usb/host/ehci-mem.c 2006-09-26 22:30:54.000000000 -0400
@@ -73,6 +73,15 @@ static void qh_destroy (struct kref *kre
ehci_dbg (ehci, "unused qh not empty!\n");
BUG ();
}
+
+ /* remove from shadow budget */
+ if(sched_verbose)
+ ehci_info(ehci, "Removing QH %p from budget:\n", qh);
+
+ if(qh->budget)
+ budget_unlink_entries_by_owner(ehci,qh);
+ qh->budget = NULL;
+
if (qh->dummy)
ehci_qtd_free (ehci, qh->dummy);
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
diff -X b/Documentation/dontdiff -upr a/drivers/usb/host/ehci-q.c
b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c 2006-09-26 22:29:36.000000000 -0400
+++ b/drivers/usb/host/ehci-q.c 2006-09-26 22:30:54.000000000 -0400
@@ -682,8 +682,23 @@ qh_make (
} else {
struct usb_tt *tt = urb->dev->tt;
- int think_time;
+ int think_time, think_bytes;
+ think_time = tt ? tt->think_time : 0;
+ think_bytes = (think_time+665)/666;
+
+ if(urb->dev->speed == USB_SPEED_FULL)
+ /* full speed bytes +
+ think time [TT host delay] +
+ FS non-iso protocol overhead */
+ qh->tt_bytes = think_bytes + maxp + 14;
+ else
+ /* low speed bytes +
+ think time [TT host delay] +
+ low speed protocol overhead */
+ /* expressed in full speed bytes */
+ qh->tt_bytes = think_bytes + maxp*8 + 98;
+
/* gap is f(FS/LS transfer times) */
qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
is_input, 0, maxp) / (125 * 1000);
@@ -697,7 +712,6 @@ qh_make (
qh->c_usecs = HS_USECS (0);
}
- think_time = tt ? tt->think_time : 0;
qh->tt_usecs = NS_TO_US (think_time +
usb_calc_bus_time (urb->dev->speed,
is_input, 0, max_packet (maxp)));
diff -X b/Documentation/dontdiff -upr a/drivers/usb/host/ehci-sched.c
b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c 2006-09-26 22:30:47.000000000 -0400
+++ b/drivers/usb/host/ehci-sched.c 2006-09-26 22:30:54.000000000 -0400
@@ -104,7 +104,6 @@
/* enable/disable shedule-specific debugging output */
-static unsigned sched_verbose = 0;
module_param (sched_verbose, uint, S_IRUGO);
MODULE_PARM_DESC (sched_verbose,
"schedule verbose: dump additional scheduling-specific "
@@ -1938,6 +1937,15 @@ static int periodic_qh_schedule (struct
qh->hw_next = EHCI_LIST_END;
frame = qh->start;
+ /* budget the qh if not already budgeted */
+ if(!qh->budget){
+
+ status = budget_add_endpoint (ehci, qh, BUDGET_TYPE_QH,
+ qh->period);
+ if(status)
+ return status;
+ }
+
/* reuse the previous schedule slots, if we can */
if (frame < period) {
uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
@@ -1987,6 +1995,10 @@ static int periodic_qh_schedule (struct
/* stuff into the periodic schedule */
status = periodic_qh_link (ehci, qh);
done:
+ if(status){
+ budget_unlink_entries_by_owner(ehci,qh);
+ qh->budget = NULL;
+ }
return status;
}
@@ -2167,7 +2179,7 @@ iso_stream_init (
} else {
u32 addr;
- int think_time;
+ int think_time, think_bytes;
int hs_transfers;
addr = dev->ttport << 24;
@@ -2178,23 +2190,60 @@ iso_stream_init (
addr |= epnum << 8;
addr |= dev->devnum;
stream->usecs = HS_USECS_ISO (maxp);
+
think_time = dev->tt ? dev->tt->think_time : 0;
+ think_bytes = (think_time+665)/666;
+
stream->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->c_usecs = stream->usecs + HS_USECS_ISO (1);
stream->usecs = HS_USECS_ISO (1);
+
+ if(dev->speed == USB_SPEED_FULL){
+ /* full speed bytes + think time [TT
+ * host delay] + FS non-iso protocol
+ * overhead */
+ stream->tt_bytes = think_bytes + maxp + 11;
+ }else{
+ /* low speed bytes + think time [TT
+ * host delay] + low speed protocol
+ * overhead */
+ /* expressed in full speed bytes */
+ stream->tt_bytes = think_bytes + maxp*8 + 98;
+ }
+
stream->raw_mask = 1;
/* c-mask as specified in USB 2.0 11.18.4 3.c */
tmp = (1 << (hs_transfers + 2)) - 1;
stream->raw_mask |= tmp << (8 + 2);
- } else
+ } else {
+ /* out */
+
+ stream->usecs += HS_USECS_ISO (1);
+
+ if(dev->speed == USB_SPEED_FULL){
+ /* full speed bytes + think time [TT
+ * host delay] + FS non-iso protocol
+ * overhead */
+ stream->tt_bytes = think_bytes + maxp + 10;
+ }else{
+ /* low speed bytes + think time [TT
+ * host delay] + low speed protocol
+ * overhead */
+ /* expressed in full speed bytes */
+ stream->tt_bytes = think_bytes + maxp*8 + 98;
+ }
+
stream->raw_mask = smask_out [hs_transfers - 1];
+ }
bandwidth = stream->usecs + stream->c_usecs;
bandwidth /= 1 << (interval + 2);
@@ -2268,6 +2317,13 @@ iso_stream_put(struct ehci_hcd *ehci, st
);
}
+ /* eliminate this stream from the shadow budget */
+ if(sched_verbose)
+ ehci_info(ehci, "Releasing bandwidth for ISO %p\n",
+ stream);
+ budget_unlink_entries_by_owner(ehci,stream);
+ stream->budget_state = 0;
+
/* potentially shut off periodic schedule */
deref_periodic(ehci);
@@ -2486,13 +2542,20 @@ static int iso_stream_schedule (
goto fail;
}
- /* first scheduling attempt? */
+ /* has this endpoint already been submitted into the shadow budget? */
if(!stream->budget_state){
+ /* no, budget this endpoint */
+
+ status = budget_add_endpoint(ehci, stream, BUDGET_TYPE_ITD,
+ stream->interval);
+
+ if(status)goto fail;
+
/* potentially turn on the periodic hardware */
status=enable_periodic (ehci);
if(status)goto fail;
-
+
stream->budget_state = 1;
}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel