[SeaBIOS] [PATCH 13/19] usb: Move code around in usb controller code.

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


No code changes - just movement of code to place pipe allocater
functions next to each other.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/usb-ehci.c |  222 +++++++++++++++++++++++++++---------------------------
 src/usb-ohci.c |  158 +++++++++++++++++++-------------------
 src/usb-uhci.c |  228 ++++++++++++++++++++++++++++----------------------------
 3 files changed, 304 insertions(+), 304 deletions(-)

diff --git a/src/usb-ehci.c b/src/usb-ehci.c
index 477b1cf..67b8450 100644
--- a/src/usb-ehci.c
+++ b/src/usb-ehci.c
@@ -380,45 +380,80 @@ ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci)
  * End point communication
  ****************************************************************/
 
-static void
-ehci_reset_pipe(struct ehci_pipe *pipe)
+struct usb_pipe *
+ehci_alloc_intr_pipe(struct usbdevice_s *usbdev
+                     , struct usb_endpoint_descriptor *epdesc)
 {
-    SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM);
-    SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM);
-    barrier();
-    SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE);
-}
+    if (! CONFIG_USB_EHCI)
+        return NULL;
+    struct usb_ehci_s *cntl = container_of(
+        usbdev->hub->cntl, struct usb_ehci_s, usb);
+    int frameexp = usb_getFrameExp(usbdev, epdesc);
+    dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
 
-static int
-ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout)
-{
-    u64 end = calc_future_tsc(timeout);
-    u32 status;
-    for (;;) {
-        status = td->token;
-        if (!(status & QTD_STS_ACTIVE))
-            break;
-        if (check_tsc(end)) {
-            u32 cur = GET_FLATPTR(pipe->qh.current);
-            u32 tok = GET_FLATPTR(pipe->qh.token);
-            u32 next = GET_FLATPTR(pipe->qh.qtd_next);
-            warn_timeout();
-            dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n"
-                    , pipe, cur, tok, next, td, status);
-            ehci_reset_pipe(pipe);
-            struct usb_ehci_s *cntl = container_of(
-                GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb);
-            ehci_waittick(cntl);
-            return -1;
-        }
-        yield();
+    if (frameexp > 10)
+        frameexp = 10;
+    int maxpacket = epdesc->wMaxPacketSize;
+    // Determine number of entries needed for 2 timer ticks.
+    int ms = 1<<frameexp;
+    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
+    struct ehci_pipe *pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe));
+    struct ehci_qtd *tds = memalign_low(EHCI_QTD_ALIGN, sizeof(*tds) * count);
+    void *data = malloc_low(maxpacket * count);
+    if (!pipe || !tds || !data) {
+        warn_noalloc();
+        goto fail;
     }
-    if (status & QTD_STS_HALT) {
-        dprintf(1, "ehci_wait_td error - status=%x\n", status);
-        ehci_reset_pipe(pipe);
-        return -2;
+    memset(pipe, 0, sizeof(*pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
+    pipe->next_td = pipe->tds = tds;
+    pipe->data = data;
+
+    pipe->qh.info1 = (
+        (1 << QH_MULT_SHIFT)
+        | (maxpacket << QH_MAXPACKET_SHIFT)
+        | (pipe->pipe.speed << QH_SPEED_SHIFT)
+        | (pipe->pipe.ep << QH_EP_SHIFT)
+        | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT));
+    pipe->qh.info2 = ((1 << QH_MULT_SHIFT)
+                      | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT)
+                      | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT)
+                      | (0x01 << QH_SMASK_SHIFT)
+                      | (0x1c << QH_CMASK_SHIFT));
+    pipe->qh.qtd_next = (u32)tds;
+
+    int i;
+    for (i=0; i<count; i++) {
+        struct ehci_qtd *td = &tds[i];
+        td->qtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]);
+        td->alt_next = EHCI_PTR_TERM;
+        td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE
+                     | QTD_PID_IN | ehci_maxerr(3));
+        td->buf[0] = (u32)data + maxpacket * i;
     }
-    return 0;
+
+    // Add to interrupt schedule.
+    struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase);
+    if (frameexp == 0) {
+        // Add to existing interrupt entry.
+        struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS);
+        pipe->qh.next = intr_qh->next;
+        barrier();
+        intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH;
+    } else {
+        int startpos = 1<<(frameexp-1);
+        pipe->qh.next = fl->links[startpos];
+        barrier();
+        for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
+            fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH;
+    }
+
+    return &pipe->pipe;
+fail:
+    free(pipe);
+    free(tds);
+    free(data);
+    return NULL;
 }
 
 struct usb_pipe *
@@ -461,6 +496,47 @@ ehci_alloc_async_pipe(struct usbdevice_s *usbdev
     return &pipe->pipe;
 }
 
+static void
+ehci_reset_pipe(struct ehci_pipe *pipe)
+{
+    SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM);
+    SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM);
+    barrier();
+    SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE);
+}
+
+static int
+ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout)
+{
+    u64 end = calc_future_tsc(timeout);
+    u32 status;
+    for (;;) {
+        status = td->token;
+        if (!(status & QTD_STS_ACTIVE))
+            break;
+        if (check_tsc(end)) {
+            u32 cur = GET_FLATPTR(pipe->qh.current);
+            u32 tok = GET_FLATPTR(pipe->qh.token);
+            u32 next = GET_FLATPTR(pipe->qh.qtd_next);
+            warn_timeout();
+            dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n"
+                    , pipe, cur, tok, next, td, status);
+            ehci_reset_pipe(pipe);
+            struct usb_ehci_s *cntl = container_of(
+                GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb);
+            ehci_waittick(cntl);
+            return -1;
+        }
+        yield();
+    }
+    if (status & QTD_STS_HALT) {
+        dprintf(1, "ehci_wait_td error - status=%x\n", status);
+        ehci_reset_pipe(pipe);
+        return -2;
+    }
+    return 0;
+}
+
 static int
 fillTDbuffer(struct ehci_qtd *td, u16 maxpacket, const void *buf, int bytes)
 {
@@ -620,82 +696,6 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
     return 0;
 }
 
-struct usb_pipe *
-ehci_alloc_intr_pipe(struct usbdevice_s *usbdev
-                     , struct usb_endpoint_descriptor *epdesc)
-{
-    if (! CONFIG_USB_EHCI)
-        return NULL;
-    struct usb_ehci_s *cntl = container_of(
-        usbdev->hub->cntl, struct usb_ehci_s, usb);
-    int frameexp = usb_getFrameExp(usbdev, epdesc);
-    dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
-
-    if (frameexp > 10)
-        frameexp = 10;
-    int maxpacket = epdesc->wMaxPacketSize;
-    // Determine number of entries needed for 2 timer ticks.
-    int ms = 1<<frameexp;
-    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
-    struct ehci_pipe *pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe));
-    struct ehci_qtd *tds = memalign_low(EHCI_QTD_ALIGN, sizeof(*tds) * count);
-    void *data = malloc_low(maxpacket * count);
-    if (!pipe || !tds || !data) {
-        warn_noalloc();
-        goto fail;
-    }
-    memset(pipe, 0, sizeof(*pipe));
-    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
-    pipe->next_td = pipe->tds = tds;
-    pipe->data = data;
-
-    pipe->qh.info1 = (
-        (1 << QH_MULT_SHIFT)
-        | (maxpacket << QH_MAXPACKET_SHIFT)
-        | (pipe->pipe.speed << QH_SPEED_SHIFT)
-        | (pipe->pipe.ep << QH_EP_SHIFT)
-        | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT));
-    pipe->qh.info2 = ((1 << QH_MULT_SHIFT)
-                      | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT)
-                      | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT)
-                      | (0x01 << QH_SMASK_SHIFT)
-                      | (0x1c << QH_CMASK_SHIFT));
-    pipe->qh.qtd_next = (u32)tds;
-
-    int i;
-    for (i=0; i<count; i++) {
-        struct ehci_qtd *td = &tds[i];
-        td->qtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]);
-        td->alt_next = EHCI_PTR_TERM;
-        td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE
-                     | QTD_PID_IN | ehci_maxerr(3));
-        td->buf[0] = (u32)data + maxpacket * i;
-    }
-
-    // Add to interrupt schedule.
-    struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase);
-    if (frameexp == 0) {
-        // Add to existing interrupt entry.
-        struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS);
-        pipe->qh.next = intr_qh->next;
-        barrier();
-        intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH;
-    } else {
-        int startpos = 1<<(frameexp-1);
-        pipe->qh.next = fl->links[startpos];
-        barrier();
-        for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
-            fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH;
-    }
-
-    return &pipe->pipe;
-fail:
-    free(pipe);
-    free(tds);
-    free(data);
-    return NULL;
-}
-
 int
 ehci_poll_intr(struct usb_pipe *p, void *data)
 {
diff --git a/src/usb-ohci.c b/src/usb-ohci.c
index a012c6c..39ed92a 100644
--- a/src/usb-ohci.c
+++ b/src/usb-ohci.c
@@ -302,20 +302,71 @@ ohci_init(struct pci_device *pci, int busid)
  * End point communication
  ****************************************************************/
 
-static int
-wait_ed(struct ohci_ed *ed)
+struct usb_pipe *
+ohci_alloc_intr_pipe(struct usbdevice_s *usbdev
+                     , struct usb_endpoint_descriptor *epdesc)
 {
-    // XXX - 500ms just a guess
-    u64 end = calc_future_tsc(500);
-    for (;;) {
-        if (ed->hwHeadP == ed->hwTailP)
-            return 0;
-        if (check_tsc(end)) {
-            warn_timeout();
-            return -1;
-        }
-        yield();
+    if (! CONFIG_USB_OHCI)
+        return NULL;
+    struct usb_ohci_s *cntl = container_of(
+        usbdev->hub->cntl, struct usb_ohci_s, usb);
+    int frameexp = usb_getFrameExp(usbdev, epdesc);
+    dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
+
+    if (frameexp > 5)
+        frameexp = 5;
+    int maxpacket = epdesc->wMaxPacketSize;
+    // Determine number of entries needed for 2 timer ticks.
+    int ms = 1<<frameexp;
+    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms)+1;
+    struct ohci_pipe *pipe = malloc_low(sizeof(*pipe));
+    struct ohci_td *tds = malloc_low(sizeof(*tds) * count);
+    void *data = malloc_low(maxpacket * count);
+    if (!pipe || !tds || !data)
+        goto err;
+    memset(pipe, 0, sizeof(*pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
+    int lowspeed = pipe->pipe.speed;
+    int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
+    pipe->data = data;
+    pipe->count = count;
+    pipe->tds = tds;
+
+    struct ohci_ed *ed = &pipe->ed;
+    ed->hwHeadP = (u32)&tds[0];
+    ed->hwTailP = (u32)&tds[count-1];
+    ed->hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0);
+
+    int i;
+    for (i=0; i<count-1; i++) {
+        tds[i].hwINFO = TD_DP_IN | TD_T_TOGGLE | TD_CC;
+        tds[i].hwCBP = (u32)data + maxpacket * i;
+        tds[i].hwNextTD = (u32)&tds[i+1];
+        tds[i].hwBE = tds[i].hwCBP + maxpacket - 1;
     }
+
+    // Add to interrupt schedule.
+    barrier();
+    struct ohci_hcca *hcca = (void*)cntl->regs->hcca;
+    if (frameexp == 0) {
+        // Add to existing interrupt entry.
+        struct ohci_ed *intr_ed = (void*)hcca->int_table[0];
+        ed->hwNextED = intr_ed->hwNextED;
+        intr_ed->hwNextED = (u32)ed;
+    } else {
+        int startpos = 1<<(frameexp-1);
+        ed->hwNextED = hcca->int_table[startpos];
+        for (i=startpos; i<ARRAY_SIZE(hcca->int_table); i+=ms)
+            hcca->int_table[i] = (u32)ed;
+    }
+
+    return &pipe->pipe;
+
+err:
+    free(pipe);
+    free(tds);
+    free(data);
+    return NULL;
 }
 
 struct usb_pipe *
@@ -357,6 +408,22 @@ ohci_alloc_async_pipe(struct usbdevice_s *usbdev
     return &pipe->pipe;
 }
 
+static int
+wait_ed(struct ohci_ed *ed)
+{
+    // XXX - 500ms just a guess
+    u64 end = calc_future_tsc(500);
+    for (;;) {
+        if (ed->hwHeadP == ed->hwTailP)
+            return 0;
+        if (check_tsc(end)) {
+            warn_timeout();
+            return -1;
+        }
+        yield();
+    }
+}
+
 int
 ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
              , void *data, int datasize)
@@ -424,73 +491,6 @@ ohci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
     return -1;
 }
 
-struct usb_pipe *
-ohci_alloc_intr_pipe(struct usbdevice_s *usbdev
-                     , struct usb_endpoint_descriptor *epdesc)
-{
-    if (! CONFIG_USB_OHCI)
-        return NULL;
-    struct usb_ohci_s *cntl = container_of(
-        usbdev->hub->cntl, struct usb_ohci_s, usb);
-    int frameexp = usb_getFrameExp(usbdev, epdesc);
-    dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
-
-    if (frameexp > 5)
-        frameexp = 5;
-    int maxpacket = epdesc->wMaxPacketSize;
-    // Determine number of entries needed for 2 timer ticks.
-    int ms = 1<<frameexp;
-    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms)+1;
-    struct ohci_pipe *pipe = malloc_low(sizeof(*pipe));
-    struct ohci_td *tds = malloc_low(sizeof(*tds) * count);
-    void *data = malloc_low(maxpacket * count);
-    if (!pipe || !tds || !data)
-        goto err;
-    memset(pipe, 0, sizeof(*pipe));
-    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
-    int lowspeed = pipe->pipe.speed;
-    int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
-    pipe->data = data;
-    pipe->count = count;
-    pipe->tds = tds;
-
-    struct ohci_ed *ed = &pipe->ed;
-    ed->hwHeadP = (u32)&tds[0];
-    ed->hwTailP = (u32)&tds[count-1];
-    ed->hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0);
-
-    int i;
-    for (i=0; i<count-1; i++) {
-        tds[i].hwINFO = TD_DP_IN | TD_T_TOGGLE | TD_CC;
-        tds[i].hwCBP = (u32)data + maxpacket * i;
-        tds[i].hwNextTD = (u32)&tds[i+1];
-        tds[i].hwBE = tds[i].hwCBP + maxpacket - 1;
-    }
-
-    // Add to interrupt schedule.
-    barrier();
-    struct ohci_hcca *hcca = (void*)cntl->regs->hcca;
-    if (frameexp == 0) {
-        // Add to existing interrupt entry.
-        struct ohci_ed *intr_ed = (void*)hcca->int_table[0];
-        ed->hwNextED = intr_ed->hwNextED;
-        intr_ed->hwNextED = (u32)ed;
-    } else {
-        int startpos = 1<<(frameexp-1);
-        ed->hwNextED = hcca->int_table[startpos];
-        for (i=startpos; i<ARRAY_SIZE(hcca->int_table); i+=ms)
-            hcca->int_table[i] = (u32)ed;
-    }
-
-    return &pipe->pipe;
-
-err:
-    free(pipe);
-    free(tds);
-    free(data);
-    return NULL;
-}
-
 int
 ohci_poll_intr(struct usb_pipe *p, void *data)
 {
diff --git a/src/usb-uhci.c b/src/usb-uhci.c
index 50d98fc..aa49681 100644
--- a/src/usb-uhci.c
+++ b/src/usb-uhci.c
@@ -268,28 +268,76 @@ uhci_init(struct pci_device *pci, int busid)
  * End point communication
  ****************************************************************/
 
-static int
-wait_pipe(struct uhci_pipe *pipe, int timeout)
+struct usb_pipe *
+uhci_alloc_intr_pipe(struct usbdevice_s *usbdev
+                     , struct usb_endpoint_descriptor *epdesc)
 {
-    u64 end = calc_future_tsc(timeout);
-    for (;;) {
-        u32 el_link = GET_FLATPTR(pipe->qh.element);
-        if (el_link & UHCI_PTR_TERM)
-            return 0;
-        if (check_tsc(end)) {
-            warn_timeout();
-            u16 iobase = GET_FLATPTR(pipe->iobase);
-            struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS);
-            dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n"
-                    , pipe, (void*)el_link, GET_FLATPTR(td->status)
-                    , inw(iobase + USBCMD)
-                    , inw(iobase + USBSTS));
-            SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM);
-            uhci_waittick(iobase);
-            return -1;
-        }
-        yield();
+    if (! CONFIG_USB_UHCI)
+        return NULL;
+    struct usb_uhci_s *cntl = container_of(
+        usbdev->hub->cntl, struct usb_uhci_s, usb);
+    int frameexp = usb_getFrameExp(usbdev, epdesc);
+    dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
+
+    if (frameexp > 10)
+        frameexp = 10;
+    int maxpacket = epdesc->wMaxPacketSize;
+    // Determine number of entries needed for 2 timer ticks.
+    int ms = 1<<frameexp;
+    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
+    count = ALIGN(count, 2);
+    struct uhci_pipe *pipe = malloc_low(sizeof(*pipe));
+    struct uhci_td *tds = malloc_low(sizeof(*tds) * count);
+    void *data = malloc_low(maxpacket * count);
+    if (!pipe || !tds || !data) {
+        warn_noalloc();
+        goto fail;
+    }
+    memset(pipe, 0, sizeof(*pipe));
+    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
+    int lowspeed = pipe->pipe.speed;
+    int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
+    pipe->qh.element = (u32)tds;
+    pipe->next_td = &tds[0];
+    pipe->iobase = cntl->iobase;
+
+    int toggle = 0;
+    int i;
+    for (i=0; i<count; i++) {
+        tds[i].link = (i==count-1 ? (u32)&tds[0] : (u32)&tds[i+1]);
+        tds[i].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
+                         | TD_CTRL_ACTIVE);
+        tds[i].token = (uhci_explen(maxpacket) | toggle
+                        | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
+                        | USB_PID_IN);
+        tds[i].buffer = data + maxpacket * i;
+        toggle ^= TD_TOKEN_TOGGLE;
     }
+
+    // Add to interrupt schedule.
+    struct uhci_framelist *fl = cntl->framelist;
+    if (frameexp == 0) {
+        // Add to existing interrupt entry.
+        struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS);
+        pipe->qh.link = intr_qh->link;
+        barrier();
+        intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH;
+        if (cntl->control_qh == intr_qh)
+            cntl->control_qh = &pipe->qh;
+    } else {
+        int startpos = 1<<(frameexp-1);
+        pipe->qh.link = fl->links[startpos];
+        barrier();
+        for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
+            fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH;
+    }
+
+    return &pipe->pipe;
+fail:
+    free(pipe);
+    free(tds);
+    free(data);
+    return NULL;
 }
 
 struct usb_pipe *
@@ -335,6 +383,52 @@ uhci_alloc_async_pipe(struct usbdevice_s *usbdev
     return &pipe->pipe;
 }
 
+static int
+wait_pipe(struct uhci_pipe *pipe, int timeout)
+{
+    u64 end = calc_future_tsc(timeout);
+    for (;;) {
+        u32 el_link = GET_FLATPTR(pipe->qh.element);
+        if (el_link & UHCI_PTR_TERM)
+            return 0;
+        if (check_tsc(end)) {
+            warn_timeout();
+            u16 iobase = GET_FLATPTR(pipe->iobase);
+            struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS);
+            dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n"
+                    , pipe, (void*)el_link, GET_FLATPTR(td->status)
+                    , inw(iobase + USBCMD)
+                    , inw(iobase + USBSTS));
+            SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM);
+            uhci_waittick(iobase);
+            return -1;
+        }
+        yield();
+    }
+}
+
+static int
+wait_td(struct uhci_td *td)
+{
+    u64 end = calc_future_tsc(5000); // XXX - lookup real time.
+    u32 status;
+    for (;;) {
+        status = td->status;
+        if (!(status & TD_CTRL_ACTIVE))
+            break;
+        if (check_tsc(end)) {
+            warn_timeout();
+            return -1;
+        }
+        yield();
+    }
+    if (status & TD_CTRL_ANY_ERROR) {
+        dprintf(1, "wait_td error - status=%x\n", status);
+        return -2;
+    }
+    return 0;
+}
+
 int
 uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
              , void *data, int datasize)
@@ -392,28 +486,6 @@ uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
     return ret;
 }
 
-static int
-wait_td(struct uhci_td *td)
-{
-    u64 end = calc_future_tsc(5000); // XXX - lookup real time.
-    u32 status;
-    for (;;) {
-        status = td->status;
-        if (!(status & TD_CTRL_ACTIVE))
-            break;
-        if (check_tsc(end)) {
-            warn_timeout();
-            return -1;
-        }
-        yield();
-    }
-    if (status & TD_CTRL_ANY_ERROR) {
-        dprintf(1, "wait_td error - status=%x\n", status);
-        return -2;
-    }
-    return 0;
-}
-
 #define STACKTDS 4
 #define TDALIGN 16
 
@@ -474,78 +546,6 @@ fail:
     return -1;
 }
 
-struct usb_pipe *
-uhci_alloc_intr_pipe(struct usbdevice_s *usbdev
-                     , struct usb_endpoint_descriptor *epdesc)
-{
-    if (! CONFIG_USB_UHCI)
-        return NULL;
-    struct usb_uhci_s *cntl = container_of(
-        usbdev->hub->cntl, struct usb_uhci_s, usb);
-    int frameexp = usb_getFrameExp(usbdev, epdesc);
-    dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
-
-    if (frameexp > 10)
-        frameexp = 10;
-    int maxpacket = epdesc->wMaxPacketSize;
-    // Determine number of entries needed for 2 timer ticks.
-    int ms = 1<<frameexp;
-    int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
-    count = ALIGN(count, 2);
-    struct uhci_pipe *pipe = malloc_low(sizeof(*pipe));
-    struct uhci_td *tds = malloc_low(sizeof(*tds) * count);
-    void *data = malloc_low(maxpacket * count);
-    if (!pipe || !tds || !data) {
-        warn_noalloc();
-        goto fail;
-    }
-    memset(pipe, 0, sizeof(*pipe));
-    usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
-    int lowspeed = pipe->pipe.speed;
-    int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
-    pipe->qh.element = (u32)tds;
-    pipe->next_td = &tds[0];
-    pipe->iobase = cntl->iobase;
-
-    int toggle = 0;
-    int i;
-    for (i=0; i<count; i++) {
-        tds[i].link = (i==count-1 ? (u32)&tds[0] : (u32)&tds[i+1]);
-        tds[i].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
-                         | TD_CTRL_ACTIVE);
-        tds[i].token = (uhci_explen(maxpacket) | toggle
-                        | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
-                        | USB_PID_IN);
-        tds[i].buffer = data + maxpacket * i;
-        toggle ^= TD_TOKEN_TOGGLE;
-    }
-
-    // Add to interrupt schedule.
-    struct uhci_framelist *fl = cntl->framelist;
-    if (frameexp == 0) {
-        // Add to existing interrupt entry.
-        struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS);
-        pipe->qh.link = intr_qh->link;
-        barrier();
-        intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH;
-        if (cntl->control_qh == intr_qh)
-            cntl->control_qh = &pipe->qh;
-    } else {
-        int startpos = 1<<(frameexp-1);
-        pipe->qh.link = fl->links[startpos];
-        barrier();
-        for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
-            fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH;
-    }
-
-    return &pipe->pipe;
-fail:
-    free(pipe);
-    free(tds);
-    free(data);
-    return NULL;
-}
-
 int
 uhci_poll_intr(struct usb_pipe *p, void *data)
 {
-- 
1.7.6.5




More information about the SeaBIOS mailing list