[SeaBIOS] [PATCH 11/19] usb: Pass 'struct usbdevice_s' into controller alloc_async functions.

Kevin O'Connor kevin at koconnor.net
Sun Mar 11 03:46:24 CET 2012


Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/usb-ehci.c |   19 ++++++++++++++-----
 src/usb-ehci.h |    5 ++++-
 src/usb-ohci.c |   17 +++++++++++++----
 src/usb-ohci.h |    5 ++++-
 src/usb-uhci.c |   21 +++++++++++++++------
 src/usb-uhci.h |    5 ++++-
 src/usb.c      |   41 +++++++++++++++++++----------------------
 src/usb.h      |    3 +++
 8 files changed, 76 insertions(+), 40 deletions(-)

diff --git a/src/usb-ehci.c b/src/usb-ehci.c
index 6115610..9721568 100644
--- a/src/usb-ehci.c
+++ b/src/usb-ehci.c
@@ -422,17 +422,26 @@ ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout)
 }
 
 struct usb_pipe *
-ehci_alloc_async_pipe(struct usb_pipe *dummy)
+ehci_alloc_async_pipe(struct usbdevice_s *usbdev
+                      , struct usb_endpoint_descriptor *epdesc)
 {
     if (! CONFIG_USB_EHCI)
         return NULL;
     struct usb_ehci_s *cntl = container_of(
-        dummy->cntl, struct usb_ehci_s, usb);
-    dprintf(7, "ehci_alloc_async_pipe %p %d\n", &cntl->usb, dummy->eptype);
+        usbdev->hub->cntl, struct usb_ehci_s, usb);
+    u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+    dprintf(7, "ehci_alloc_async_pipe %p %d\n", &cntl->usb, eptype);
+
+    struct usb_pipe *usbpipe = usb_getFreePipe(&cntl->usb, eptype);
+    if (usbpipe) {
+        // Use previously allocated pipe.
+        usb_desc2pipe(usbpipe, usbdev, epdesc);
+        return usbpipe;
+    }
 
     // Allocate a new queue head.
     struct ehci_pipe *pipe;
-    if (dummy->eptype == USB_ENDPOINT_XFER_CONTROL)
+    if (eptype == USB_ENDPOINT_XFER_CONTROL)
         pipe = memalign_tmphigh(EHCI_QH_ALIGN, sizeof(*pipe));
     else
         pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe));
@@ -441,7 +450,7 @@ ehci_alloc_async_pipe(struct usb_pipe *dummy)
         return NULL;
     }
     memset(pipe, 0, sizeof(*pipe));
-    memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
     pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM;
 
     // Add queue head to controller list.
diff --git a/src/usb-ehci.h b/src/usb-ehci.h
index a4fbb77..ed2c3f7 100644
--- a/src/usb-ehci.h
+++ b/src/usb-ehci.h
@@ -3,8 +3,11 @@
 
 // usb-ehci.c
 int ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci);
+struct usbdevice_s;
+struct usb_endpoint_descriptor;
+struct usb_pipe *ehci_alloc_async_pipe(struct usbdevice_s *usbdev
+                                       , struct usb_endpoint_descriptor *epdesc);
 struct usb_pipe;
-struct usb_pipe *ehci_alloc_async_pipe(struct usb_pipe *dummy);
 int ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
                  , void *data, int datasize);
 int ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize);
diff --git a/src/usb-ohci.c b/src/usb-ohci.c
index 9522309..8703b26 100644
--- a/src/usb-ohci.c
+++ b/src/usb-ohci.c
@@ -319,18 +319,27 @@ wait_ed(struct ohci_ed *ed)
 }
 
 struct usb_pipe *
-ohci_alloc_async_pipe(struct usb_pipe *dummy)
+ohci_alloc_async_pipe(struct usbdevice_s *usbdev
+                      , struct usb_endpoint_descriptor *epdesc)
 {
     if (! CONFIG_USB_OHCI)
         return NULL;
-    if (dummy->eptype != USB_ENDPOINT_XFER_CONTROL) {
+    u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+    if (eptype != USB_ENDPOINT_XFER_CONTROL) {
         dprintf(1, "OHCI Bulk transfers not supported.\n");
         return NULL;
     }
     struct usb_ohci_s *cntl = container_of(
-        dummy->cntl, struct usb_ohci_s, usb);
+        usbdev->hub->cntl, struct usb_ohci_s, usb);
     dprintf(7, "ohci_alloc_async_pipe %p\n", &cntl->usb);
 
+    struct usb_pipe *usbpipe = usb_getFreePipe(&cntl->usb, eptype);
+    if (usbpipe) {
+        // Use previously allocated pipe.
+        usb_desc2pipe(usbpipe, usbdev, epdesc);
+        return usbpipe;
+    }
+
     // Allocate a new queue head.
     struct ohci_pipe *pipe = malloc_tmphigh(sizeof(*pipe));
     if (!pipe) {
@@ -338,7 +347,7 @@ ohci_alloc_async_pipe(struct usb_pipe *dummy)
         return NULL;
     }
     memset(pipe, 0, sizeof(*pipe));
-    memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
     pipe->ed.hwINFO = ED_SKIP;
 
     // Add queue head to controller list.
diff --git a/src/usb-ohci.h b/src/usb-ohci.h
index 6085355..bc6eb7b 100644
--- a/src/usb-ohci.h
+++ b/src/usb-ohci.h
@@ -3,8 +3,11 @@
 
 // usb-ohci.c
 void ohci_init(struct pci_device *pci, int busid);
+struct usbdevice_s;
+struct usb_endpoint_descriptor;
+struct usb_pipe *ohci_alloc_async_pipe(struct usbdevice_s *usbdev
+                                       , struct usb_endpoint_descriptor *epdesc);
 struct usb_pipe;
-struct usb_pipe *ohci_alloc_async_pipe(struct usb_pipe *dummy);
 int ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
                  , void *data, int datasize);
 int ohci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize);
diff --git a/src/usb-uhci.c b/src/usb-uhci.c
index 1c911c6..0da4eff 100644
--- a/src/usb-uhci.c
+++ b/src/usb-uhci.c
@@ -293,17 +293,26 @@ wait_pipe(struct uhci_pipe *pipe, int timeout)
 }
 
 struct usb_pipe *
-uhci_alloc_async_pipe(struct usb_pipe *dummy)
+uhci_alloc_async_pipe(struct usbdevice_s *usbdev
+                      , struct usb_endpoint_descriptor *epdesc)
 {
     if (! CONFIG_USB_UHCI)
         return NULL;
     struct usb_uhci_s *cntl = container_of(
-        dummy->cntl, struct usb_uhci_s, usb);
-    dprintf(7, "uhci_alloc_async_pipe %p %d\n", &cntl->usb, dummy->eptype);
+        usbdev->hub->cntl, struct usb_uhci_s, usb);
+    u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+    dprintf(7, "uhci_alloc_async_pipe %p %d\n", &cntl->usb, eptype);
+
+    struct usb_pipe *usbpipe = usb_getFreePipe(&cntl->usb, eptype);
+    if (usbpipe) {
+        // Use previously allocated pipe.
+        usb_desc2pipe(usbpipe, usbdev, epdesc);
+        return usbpipe;
+    }
 
     // Allocate a new queue head.
     struct uhci_pipe *pipe;
-    if (dummy->eptype == USB_ENDPOINT_XFER_CONTROL)
+    if (eptype == USB_ENDPOINT_XFER_CONTROL)
         pipe = malloc_tmphigh(sizeof(*pipe));
     else
         pipe = malloc_low(sizeof(*pipe));
@@ -312,7 +321,7 @@ uhci_alloc_async_pipe(struct usb_pipe *dummy)
         return NULL;
     }
     memset(pipe, 0, sizeof(*pipe));
-    memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
     pipe->qh.element = UHCI_PTR_TERM;
     pipe->iobase = cntl->iobase;
 
@@ -321,7 +330,7 @@ uhci_alloc_async_pipe(struct usb_pipe *dummy)
     pipe->qh.link = control_qh->link;
     barrier();
     control_qh->link = (u32)&pipe->qh | UHCI_PTR_QH;
-    if (dummy->eptype == USB_ENDPOINT_XFER_CONTROL)
+    if (eptype == USB_ENDPOINT_XFER_CONTROL)
         cntl->control_qh = &pipe->qh;
     return &pipe->pipe;
 }
diff --git a/src/usb-uhci.h b/src/usb-uhci.h
index 0706e8f..035a565 100644
--- a/src/usb-uhci.h
+++ b/src/usb-uhci.h
@@ -3,8 +3,11 @@
 
 // usb-uhci.c
 void uhci_init(struct pci_device *pci, int busid);
+struct usbdevice_s;
+struct usb_endpoint_descriptor;
+struct usb_pipe *uhci_alloc_async_pipe(struct usbdevice_s *usbdev
+                                       , struct usb_endpoint_descriptor *epdesc);
 struct usb_pipe;
-struct usb_pipe *uhci_alloc_async_pipe(struct usb_pipe *dummy);
 int uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
                  , void *data, int datasize);
 int uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize);
diff --git a/src/usb.c b/src/usb.c
index 50f8b50..b61fbc1 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -37,11 +37,10 @@ free_pipe(struct usb_pipe *pipe)
 }
 
 // Fill "pipe" endpoint info from an endpoint descriptor.
-static void
-desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
-          , struct usb_endpoint_descriptor *epdesc)
+void
+usb_desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
+              , struct usb_endpoint_descriptor *epdesc)
 {
-    memset(pipe, 0, sizeof(*pipe));
     pipe->cntl = usbdev->hub->cntl;
     pipe->type = usbdev->hub->cntl->type;
     pipe->ep = epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
@@ -64,38 +63,36 @@ desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
     }
 }
 
-// Allocate an async pipe (control or bulk).
+// Check for an available pipe on the freelist.
 struct usb_pipe *
-alloc_async_pipe(struct usbdevice_s *usbdev
-                , struct usb_endpoint_descriptor *epdesc)
+usb_getFreePipe(struct usb_s *cntl, u8 eptype)
 {
-    struct usb_pipe dummy;
-    desc2pipe(&dummy, usbdev, epdesc);
-
-    // Check for an available pipe on the freelist.
-    struct usb_pipe **pfree = &dummy.cntl->freelist;
+    struct usb_pipe **pfree = &cntl->freelist;
     for (;;) {
         struct usb_pipe *pipe = *pfree;
         if (!pipe)
-            break;
-        if (pipe->eptype == dummy.eptype) {
-            // Use previously allocated pipe.
+            return NULL;
+        if (pipe->eptype == eptype) {
             *pfree = pipe->freenext;
-            memcpy(pipe, &dummy, sizeof(*pipe));
             return pipe;
         }
         pfree = &pipe->freenext;
     }
+}
 
-    // Allocate a new pipe.
-    switch (dummy.type) {
+// Allocate an async pipe (control or bulk).
+struct usb_pipe *
+alloc_async_pipe(struct usbdevice_s *usbdev
+                 , struct usb_endpoint_descriptor *epdesc)
+{
+    switch (usbdev->hub->cntl->type) {
     default:
     case USB_TYPE_UHCI:
-        return uhci_alloc_async_pipe(&dummy);
+        return uhci_alloc_async_pipe(usbdev, epdesc);
     case USB_TYPE_OHCI:
-        return ohci_alloc_async_pipe(&dummy);
+        return ohci_alloc_async_pipe(usbdev, epdesc);
     case USB_TYPE_EHCI:
-        return ehci_alloc_async_pipe(&dummy);
+        return ehci_alloc_async_pipe(usbdev, epdesc);
     }
 }
 
@@ -135,7 +132,7 @@ alloc_intr_pipe(struct usbdevice_s *usbdev
                 , struct usb_endpoint_descriptor *epdesc)
 {
     struct usb_pipe dummy;
-    desc2pipe(&dummy, usbdev, epdesc);
+    usb_desc2pipe(&dummy, usbdev, epdesc);
     // Find the exponential period of the requested time.
     int period = epdesc->bInterval;
     int frameexp;
diff --git a/src/usb.h b/src/usb.h
index fff54e5..c792376 100644
--- a/src/usb.h
+++ b/src/usb.h
@@ -218,6 +218,9 @@ int send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *re
                          , void *data);
 int usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize);
 void free_pipe(struct usb_pipe *pipe);
+void usb_desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
+                   , struct usb_endpoint_descriptor *epdesc);
+struct usb_pipe *usb_getFreePipe(struct usb_s *cntl, u8 eptype);
 struct usb_pipe *alloc_async_pipe(struct usbdevice_s *usbdev
                                   , struct usb_endpoint_descriptor *epdesc);
 struct usb_pipe *alloc_intr_pipe(struct usbdevice_s *usbdev
-- 
1.7.6.5




More information about the SeaBIOS mailing list