예제 #1
0
static void
ehci_free_pipes(struct usb_ehci_s *cntl)
{
    dprintf(7, "ehci_free_pipes %p\n", cntl);

    struct ehci_qh *start = cntl->async_qh;
    struct ehci_qh *pos = start;
    for (;;) {
        struct ehci_qh *next = (void*)(pos->next & ~EHCI_PTR_BITS);
        if (next == start)
            break;
        struct ehci_pipe *pipe = container_of(next, struct ehci_pipe, qh);
        if (pipe->pipe.cntl != &cntl->usb)
            pos->next = next->next;
        else
            pos = next;
    }
    ehci_waittick(cntl);
    for (;;) {
        struct usb_pipe *usbpipe = cntl->usb.freelist;
        if (!usbpipe)
            break;
        cntl->usb.freelist = usbpipe->freenext;
        struct ehci_pipe *pipe = container_of(usbpipe, struct ehci_pipe, pipe);
        free(pipe);
    }
}
예제 #2
0
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_LOWFLAT(pipe->qh.current);
            u32 tok = GET_LOWFLAT(pipe->qh.token);
            u32 next = GET_LOWFLAT(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_LOWFLAT(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;
}
예제 #3
0
void
ehci_free_pipe(struct usb_pipe *p)
{
    if (! CONFIG_USB_EHCI)
        return;
    dprintf(7, "ehci_free_pipe %p\n", p);
    struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
    struct usb_ehci_s *cntl = container_of(
        pipe->pipe.cntl, struct usb_ehci_s, usb);

    struct ehci_qh *start = cntl->async_qh;
    struct ehci_qh *pos = start;
    for (;;) {
        struct ehci_qh *next = (void*)(pos->next & ~EHCI_PTR_BITS);
        if (next == start) {
            // Not found?!  Exit without freeing.
            warn_internalerror();
            return;
        }
        if (next == &pipe->qh) {
            pos->next = next->next;
            ehci_waittick(cntl);
            free(pipe);
            return;
        }
        pos = next;
    }
}