[SeaBIOS] [PATCH 2/3] xhci: Use the same endpoint initialization code in xhci_alloc_pipe()

Kevin O'Connor kevin at koconnor.net
Mon Jan 27 18:29:42 CET 2014


Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/hw/usb-xhci.c | 74 ++++++++++++++++++++++---------------------------------
 1 file changed, 29 insertions(+), 45 deletions(-)

diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c
index 3366f09..b307c5e 100644
--- a/src/hw/usb-xhci.c
+++ b/src/hw/usb-xhci.c
@@ -804,7 +804,7 @@ static struct usbhub_op_s xhci_hub_ops = {
 
 
 static struct xhci_inctx *
-xhci_alloc_inctx(struct usbdevice_s *usbdev)
+xhci_alloc_inctx(struct usbdevice_s *usbdev, int maxepid)
 {
     struct usb_xhci_s *xhci = container_of(
         usbdev->hub->cntl, struct usb_xhci_s, usb);
@@ -816,9 +816,8 @@ xhci_alloc_inctx(struct usbdevice_s *usbdev)
     }
     memset(in, 0, size);
 
-    in->add = 0x01;
     struct xhci_slotctx *slot = (void*)&in[1 << xhci->context64];
-    slot->ctx[0]    |= (1 << 27); // context entries
+    slot->ctx[0]    |= maxepid << 27; // context entries
     slot->ctx[0]    |= speed_to_xhci[usbdev->speed] << 20;
 
     // Set high-speed hub flags.
@@ -859,9 +858,10 @@ static int xhci_config_hub(struct usbhub_s *hub)
     if ((hdslot->ctx[3] >> 27) == 3)
         // Already configured
         return 0;
-    struct xhci_inctx *in = xhci_alloc_inctx(hub->usbdev);
+    struct xhci_inctx *in = xhci_alloc_inctx(hub->usbdev, 1);
     if (!in)
         return -1;
+    in->add = 0x01;
     struct xhci_slotctx *slot = (void*)&in[1 << xhci->context64];
     slot->ctx[0] |= 1 << 26;
     slot->ctx[1] |= hub->portcount << 24;
@@ -911,6 +911,23 @@ xhci_alloc_pipe(struct usbdevice_s *usbdev
     if (eptype == USB_ENDPOINT_XFER_INT)
         pipe->buf = malloc_low(pipe->pipe.maxpacket);
 
+    // Allocate input context and initialize endpoint info.
+    struct xhci_inctx *in = xhci_alloc_inctx(usbdev, epid);
+    if (!in)
+        goto fail;
+    in->add = 0x01 | (1 << epid);
+    struct xhci_epctx *ep = (void*)&in[(pipe->epid+1) << xhci->context64];
+    if (eptype == USB_ENDPOINT_XFER_INT)
+        ep->ctx[0] = (usb_getFrameExp(usbdev, epdesc) + 3) << 16;
+    ep->ctx[1]   |= eptype << 3;
+    if (epdesc->bEndpointAddress & USB_DIR_IN
+        || eptype == USB_ENDPOINT_XFER_CONTROL)
+        ep->ctx[1] |= 1 << 5;
+    ep->ctx[1]   |= pipe->pipe.maxpacket << 16;
+    ep->deq_low  = (u32)&pipe->reqs.ring[0];
+    ep->deq_low  |= 1;         // dcs
+    ep->length   = pipe->pipe.maxpacket;
+
     dprintf(3, "%s: usbdev %p, ring %p, slotid %d, epid %d\n", __func__,
             usbdev, &pipe->reqs, pipe->slotid, pipe->epid);
     if (pipe->epid == 1) {
@@ -920,7 +937,7 @@ xhci_alloc_pipe(struct usbdevice_s *usbdev
             if (ret)
                 goto fail;
         }
-        // Enable slot and send set_address command.
+        // Enable slot.
         u32 size = (sizeof(struct xhci_slotctx) * 32) << xhci->context64;
         struct xhci_slotctx *dev = memalign_high(1024 << xhci->context64, size);
         if (!dev) {
@@ -934,65 +951,32 @@ xhci_alloc_pipe(struct usbdevice_s *usbdev
             goto fail;
         }
         dprintf(3, "%s: enable slot: got slotid %d\n", __func__, slotid);
-
         memset(dev, 0, size);
         pipe->slotid = usbdev->slotid = slotid;
         xhci->devs[slotid].ptr_low = (u32)dev;
         xhci->devs[slotid].ptr_high = 0;
 
-        struct xhci_inctx *in = xhci_alloc_inctx(usbdev);
-        if (!in)
-            goto fail;
-        in->add |= (1 << 1);
-
-        struct xhci_epctx *ep = (void*)&in[2 << xhci->context64];
-        ep->ctx[0]   |= (3 << 16); // interval: 1ms
-        ep->ctx[1]   |= (4 << 3);  // control pipe
-        ep->ctx[1]   |= (pipe->pipe.maxpacket << 16);
-
-        ep->deq_low  = (u32)&pipe->reqs.ring[0];
-        ep->deq_low  |= 1;         // dcs
-        ep->deq_high = 0;
-        ep->length   = pipe->pipe.maxpacket;
-
+        // Send set_address command.
         int cc = xhci_cmd_address_device(xhci, slotid, in);
-        free(in);
         if (cc != CC_SUCCESS) {
             dprintf(1, "%s: address device: failed (cc %d)\n", __func__, cc);
             goto fail;
         }
     } else {
-        struct xhci_inctx *in = xhci_alloc_inctx(usbdev);
-        if (!in)
-            goto fail;
-        in->add |= (1 << pipe->epid);
-        struct xhci_slotctx *slot = (void*)&in[1 << xhci->context64];
-        slot->ctx[0] = (slot->ctx[0] & ~0xf8000000) | (pipe->epid << 27);
-
-        struct xhci_epctx *ep = (void*)&in[(pipe->epid+1) << xhci->context64];
-        if (eptype == USB_ENDPOINT_XFER_INT)
-            ep->ctx[0] = (usb_getFrameExp(usbdev, epdesc) + 3) << 16;
-        ep->ctx[1]   |= (eptype << 3);
-        if (epdesc->bEndpointAddress & USB_DIR_IN)
-            ep->ctx[1] |= (1 << 5);
-        ep->ctx[1]   |= (pipe->pipe.maxpacket << 16);
-        ep->deq_low  = (u32)&pipe->reqs.ring[0];
-        ep->deq_low  |= 1;         // dcs
-        ep->deq_high = 0;
-        ep->length   = pipe->pipe.maxpacket;
-
         pipe->slotid = usbdev->slotid;
+        // Send configure command.
         int cc = xhci_cmd_configure_endpoint(xhci, pipe->slotid, in);
-        free(in);
         if (cc != CC_SUCCESS) {
             dprintf(1, "%s: configure endpoint: failed (cc %d)\n", __func__, cc);
             goto fail;
         }
     }
-
+    free(in);
     return &pipe->pipe;
+
 fail:
     free(pipe);
+    free(in);
     return NULL;
 }
 
@@ -1010,11 +994,11 @@ xhci_update_pipe(struct usbdevice_s *usbdev, struct usb_pipe *upipe
     dprintf(3, "%s: usbdev %p, ring %p, slotid %d, epid %d\n", __func__,
             usbdev, &pipe->reqs, pipe->slotid, pipe->epid);
     if (eptype == USB_ENDPOINT_XFER_CONTROL &&
-        pipe->pipe.maxpacket !=  epdesc->wMaxPacketSize) {
+        pipe->pipe.maxpacket != epdesc->wMaxPacketSize) {
         dprintf(1, "%s: reconf ctl endpoint pkt size: %d -> %d\n",
                 __func__, pipe->pipe.maxpacket, epdesc->wMaxPacketSize);
         pipe->pipe.maxpacket = epdesc->wMaxPacketSize;
-        struct xhci_inctx *in = xhci_alloc_inctx(usbdev);
+        struct xhci_inctx *in = xhci_alloc_inctx(usbdev, 1);
         if (!in)
             return upipe;
         in->add = (1 << 1);
-- 
1.8.5.3




More information about the SeaBIOS mailing list