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
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to