static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)

{

    int dir;

    size_t len = 0, pktlen = 0;

#ifdef DEBUG_PACKET

    const char *str = NULL;

#endif

    int pid;

    int ret;

    int i;

    USBDevice *dev;

    struct ohci_td td;

    uint32_t addr;

    int flag_r;

    int completion;



    addr = ed->head & OHCI_DPTR_MASK;

    /* See if this TD has already been submitted to the device.  */

    completion = (addr == ohci->async_td);

    if (completion && !ohci->async_complete) {

#ifdef DEBUG_PACKET

        DPRINTF("Skipping async TD\n");

#endif

        return 1;

    }

    if (!ohci_read_td(ohci, addr, &td)) {

        fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);

        return 0;

    }



    dir = OHCI_BM(ed->flags, ED_D);

    switch (dir) {

    case OHCI_TD_DIR_OUT:

    case OHCI_TD_DIR_IN:

        /* Same value.  */

        break;

    default:

        dir = OHCI_BM(td.flags, TD_DP);

        break;

    }



    switch (dir) {

    case OHCI_TD_DIR_IN:

#ifdef DEBUG_PACKET

        str = "in";

#endif

        pid = USB_TOKEN_IN;

        break;

    case OHCI_TD_DIR_OUT:

#ifdef DEBUG_PACKET

        str = "out";

#endif

        pid = USB_TOKEN_OUT;

        break;

    case OHCI_TD_DIR_SETUP:

#ifdef DEBUG_PACKET

        str = "setup";

#endif

        pid = USB_TOKEN_SETUP;

        break;

    default:

        fprintf(stderr, "usb-ohci: Bad direction\n");

        return 1;

    }

    if (td.cbp && td.be) {

        if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {

            len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);

        } else {

            len = (td.be - td.cbp) + 1;

        }



        pktlen = len;

        if (len && dir != OHCI_TD_DIR_IN) {

            /* The endpoint may not allow us to transfer it all now */

            pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT;

            if (pktlen > len) {

                pktlen = len;

            }

            if (!completion) {

                ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen, 0);

            }

        }

    }



    flag_r = (td.flags & OHCI_TD_R) != 0;

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64

            " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

            addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be);



    if (pktlen > 0 && dir != OHCI_TD_DIR_IN) {

        DPRINTF("  data:");

        for (i = 0; i < pktlen; i++) {

            printf(" %.2x", ohci->usb_buf[i]);

        }

        DPRINTF("\n");

    }

#endif

    if (completion) {

        ret = ohci->usb_packet.result;

        ohci->async_td = 0;

        ohci->async_complete = 0;

    } else {

        if (ohci->async_td) {

            /* ??? The hardware should allow one active packet per

               endpoint.  We only allow one active packet per controller.

               This should be sufficient as long as devices respond in a

               timely manner.

            */

#ifdef DEBUG_PACKET

            DPRINTF("Too many pending packets\n");

#endif

            return 1;

        }

        usb_packet_setup(&ohci->usb_packet, pid,

                         OHCI_BM(ed->flags, ED_FA),

                         OHCI_BM(ed->flags, ED_EN));

        usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);

        dev = ohci_find_device(ohci, ohci->usb_packet.devaddr);

        ret = usb_handle_packet(dev, &ohci->usb_packet);

#ifdef DEBUG_PACKET

        DPRINTF("ret=%d\n", ret);

#endif

        if (ret == USB_RET_ASYNC) {

            ohci->async_td = addr;

            return 1;

        }

    }

    if (ret >= 0) {

        if (dir == OHCI_TD_DIR_IN) {

            ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1);

#ifdef DEBUG_PACKET

            DPRINTF("  data:");

            for (i = 0; i < ret; i++)

                printf(" %.2x", ohci->usb_buf[i]);

            DPRINTF("\n");

#endif

        } else {

            ret = pktlen;

        }

    }



    /* Writeback */

    if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {

        /* Transmission succeeded.  */

        if (ret == len) {

            td.cbp = 0;

        } else {

            if ((td.cbp & 0xfff) + ret > 0xfff) {

                td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);

            } else {

                td.cbp += ret;

            }

        }

        td.flags |= OHCI_TD_T1;

        td.flags ^= OHCI_TD_T0;

        OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);

        OHCI_SET_BM(td.flags, TD_EC, 0);



        if ((dir != OHCI_TD_DIR_IN) && (ret != len)) {

            /* Partial packet transfer: TD not ready to retire yet */

            goto exit_no_retire;

        }



        /* Setting ED_C is part of the TD retirement process */

        ed->head &= ~OHCI_ED_C;

        if (td.flags & OHCI_TD_T0)

            ed->head |= OHCI_ED_C;

    } else {

        if (ret >= 0) {

            DPRINTF("usb-ohci: Underrun\n");

            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);

        } else {

            switch (ret) {

            case USB_RET_NODEV:

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);

            case USB_RET_NAK:

                DPRINTF("usb-ohci: got NAK\n");

                return 1;

            case USB_RET_STALL:

                DPRINTF("usb-ohci: got STALL\n");

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);

                break;

            case USB_RET_BABBLE:

                DPRINTF("usb-ohci: got BABBLE\n");

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);

                break;

            default:

                fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);

                OHCI_SET_BM(td.flags, TD_EC, 3);

                break;

            }

        }

        ed->head |= OHCI_ED_H;

    }



    /* Retire this TD */

    ed->head &= ~OHCI_DPTR_MASK;

    ed->head |= td.next & OHCI_DPTR_MASK;

    td.next = ohci->done;

    ohci->done = addr;

    i = OHCI_BM(td.flags, TD_DI);

    if (i < ohci->done_count)

        ohci->done_count = i;

exit_no_retire:

    ohci_put_td(ohci, addr, &td);

    return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;

}

static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)

{

    int dir;

    size_t len = 0, pktlen = 0;

#ifdef DEBUG_PACKET

    const char *str = NULL;

#endif

    int pid;

    int ret;

    int i;

    USBDevice *dev;

    struct ohci_td td;

    uint32_t addr;

    int flag_r;

    int completion;



    addr = ed->head & OHCI_DPTR_MASK;

    

    completion = (addr == ohci->async_td);

    if (completion && !ohci->async_complete) {

#ifdef DEBUG_PACKET

        DPRINTF("Skipping async TD\n");

#endif

        return 1;

    }

    if (!ohci_read_td(ohci, addr, &td)) {

        fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);

        return 0;

    }



    dir = OHCI_BM(ed->flags, ED_D);

    switch (dir) {

    case OHCI_TD_DIR_OUT:

    case OHCI_TD_DIR_IN:

        

        break;

    default:

        dir = OHCI_BM(td.flags, TD_DP);

        break;

    }



    switch (dir) {

    case OHCI_TD_DIR_IN:

#ifdef DEBUG_PACKET

        str = "in";

#endif

        pid = USB_TOKEN_IN;

        break;

    case OHCI_TD_DIR_OUT:

#ifdef DEBUG_PACKET

        str = "out";

#endif

        pid = USB_TOKEN_OUT;

        break;

    case OHCI_TD_DIR_SETUP:

#ifdef DEBUG_PACKET

        str = "setup";

#endif

        pid = USB_TOKEN_SETUP;

        break;

    default:

        fprintf(stderr, "usb-ohci: Bad direction\n");

        return 1;

    }

    if (td.cbp && td.be) {

        if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {

            len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);

        } else {

            len = (td.be - td.cbp) + 1;

        }



        pktlen = len;

        if (len && dir != OHCI_TD_DIR_IN) {

            

            pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT;

            if (pktlen > len) {

                pktlen = len;

            }

            if (!completion) {

                ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen, 0);

            }

        }

    }



    flag_r = (td.flags & OHCI_TD_R) != 0;

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64

            " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

            addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be);



    if (pktlen > 0 && dir != OHCI_TD_DIR_IN) {

        DPRINTF("  data:");

        for (i = 0; i < pktlen; i++) {

            printf(" %.2x", ohci->usb_buf[i]);

        }

        DPRINTF("\n");

    }

#endif

    if (completion) {

        ret = ohci->usb_packet.result;

        ohci->async_td = 0;

        ohci->async_complete = 0;

    } else {

        if (ohci->async_td) {

            









#ifdef DEBUG_PACKET

            DPRINTF("Too many pending packets\n");

#endif

            return 1;

        }

        usb_packet_setup(&ohci->usb_packet, pid,

                         OHCI_BM(ed->flags, ED_FA),

                         OHCI_BM(ed->flags, ED_EN));

        usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);

        dev = ohci_find_device(ohci, ohci->usb_packet.devaddr);

        ret = usb_handle_packet(dev, &ohci->usb_packet);

#ifdef DEBUG_PACKET

        DPRINTF("ret=%d\n", ret);

#endif

        if (ret == USB_RET_ASYNC) {

            ohci->async_td = addr;

            return 1;

        }

    }

    if (ret >= 0) {

        if (dir == OHCI_TD_DIR_IN) {

            ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1);

#ifdef DEBUG_PACKET

            DPRINTF("  data:");

            for (i = 0; i < ret; i++)

                printf(" %.2x", ohci->usb_buf[i]);

            DPRINTF("\n");

#endif

        } else {

            ret = pktlen;

        }

    }



    

    if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {

        

        if (ret == len) {

            td.cbp = 0;

        } else {

            if ((td.cbp & 0xfff) + ret > 0xfff) {

                td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);

            } else {

                td.cbp += ret;

            }

        }

        td.flags |= OHCI_TD_T1;

        td.flags ^= OHCI_TD_T0;

        OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);

        OHCI_SET_BM(td.flags, TD_EC, 0);



        if ((dir != OHCI_TD_DIR_IN) && (ret != len)) {

            

            goto exit_no_retire;

        }



        

        ed->head &= ~OHCI_ED_C;

        if (td.flags & OHCI_TD_T0)

            ed->head |= OHCI_ED_C;

    } else {

        if (ret >= 0) {

            DPRINTF("usb-ohci: Underrun\n");

            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);

        } else {

            switch (ret) {

            case USB_RET_NODEV:

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);

            case USB_RET_NAK:

                DPRINTF("usb-ohci: got NAK\n");

                return 1;

            case USB_RET_STALL:

                DPRINTF("usb-ohci: got STALL\n");

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);

                break;

            case USB_RET_BABBLE:

                DPRINTF("usb-ohci: got BABBLE\n");

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);

                break;

            default:

                fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);

                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);

                OHCI_SET_BM(td.flags, TD_EC, 3);

                break;

            }

        }

        ed->head |= OHCI_ED_H;

    }



    

    ed->head &= ~OHCI_DPTR_MASK;

    ed->head |= td.next & OHCI_DPTR_MASK;

    td.next = ohci->done;

    ohci->done = addr;

    i = OHCI_BM(td.flags, TD_DI);

    if (i < ohci->done_count)

        ohci->done_count = i;

exit_no_retire:

    ohci_put_td(ohci, addr, &td);

    return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;

}

static int FUNC_0(OHCIState *VAR_0, struct ohci_ed *VAR_1)

{

    int VAR_2;

    size_t len = 0, pktlen = 0;

#ifdef DEBUG_PACKET

    const char *str = NULL;

#endif

    int VAR_3;

    int VAR_4;

    int VAR_5;

    USBDevice *dev;

    struct ohci_td VAR_6;

    uint32_t addr;

    int VAR_7;

    int VAR_8;



    addr = VAR_1->head & OHCI_DPTR_MASK;

    

    VAR_8 = (addr == VAR_0->async_td);

    if (VAR_8 && !VAR_0->async_complete) {

#ifdef DEBUG_PACKET

        DPRINTF("Skipping async TD\n");

#endif

        return 1;

    }

    if (!ohci_read_td(VAR_0, addr, &VAR_6)) {

        fprintf(stderr, "usb-VAR_0: TD read error at %x\n", addr);

        return 0;

    }



    VAR_2 = OHCI_BM(VAR_1->flags, ED_D);

    switch (VAR_2) {

    case OHCI_TD_DIR_OUT:

    case OHCI_TD_DIR_IN:

        

        break;

    default:

        VAR_2 = OHCI_BM(VAR_6.flags, TD_DP);

        break;

    }



    switch (VAR_2) {

    case OHCI_TD_DIR_IN:

#ifdef DEBUG_PACKET

        str = "in";

#endif

        VAR_3 = USB_TOKEN_IN;

        break;

    case OHCI_TD_DIR_OUT:

#ifdef DEBUG_PACKET

        str = "out";

#endif

        VAR_3 = USB_TOKEN_OUT;

        break;

    case OHCI_TD_DIR_SETUP:

#ifdef DEBUG_PACKET

        str = "setup";

#endif

        VAR_3 = USB_TOKEN_SETUP;

        break;

    default:

        fprintf(stderr, "usb-VAR_0: Bad direction\n");

        return 1;

    }

    if (VAR_6.cbp && VAR_6.be) {

        if ((VAR_6.cbp & 0xfffff000) != (VAR_6.be & 0xfffff000)) {

            len = (VAR_6.be & 0xfff) + 0x1001 - (VAR_6.cbp & 0xfff);

        } else {

            len = (VAR_6.be - VAR_6.cbp) + 1;

        }



        pktlen = len;

        if (len && VAR_2 != OHCI_TD_DIR_IN) {

            

            pktlen = (VAR_1->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT;

            if (pktlen > len) {

                pktlen = len;

            }

            if (!VAR_8) {

                ohci_copy_td(VAR_0, &VAR_6, VAR_0->usb_buf, pktlen, 0);

            }

        }

    }



    VAR_7 = (VAR_6.flags & OHCI_TD_R) != 0;

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64

            " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

            addr, (int64_t)pktlen, (int64_t)len, str, VAR_7, VAR_6.cbp, VAR_6.be);



    if (pktlen > 0 && VAR_2 != OHCI_TD_DIR_IN) {

        DPRINTF("  data:");

        for (VAR_5 = 0; VAR_5 < pktlen; VAR_5++) {

            printf(" %.2x", VAR_0->usb_buf[VAR_5]);

        }

        DPRINTF("\n");

    }

#endif

    if (VAR_8) {

        VAR_4 = VAR_0->usb_packet.result;

        VAR_0->async_td = 0;

        VAR_0->async_complete = 0;

    } else {

        if (VAR_0->async_td) {

            









#ifdef DEBUG_PACKET

            DPRINTF("Too many pending packets\n");

#endif

            return 1;

        }

        usb_packet_setup(&VAR_0->usb_packet, VAR_3,

                         OHCI_BM(VAR_1->flags, ED_FA),

                         OHCI_BM(VAR_1->flags, ED_EN));

        usb_packet_addbuf(&VAR_0->usb_packet, VAR_0->usb_buf, pktlen);

        dev = ohci_find_device(VAR_0, VAR_0->usb_packet.devaddr);

        VAR_4 = usb_handle_packet(dev, &VAR_0->usb_packet);

#ifdef DEBUG_PACKET

        DPRINTF("VAR_4=%d\n", VAR_4);

#endif

        if (VAR_4 == USB_RET_ASYNC) {

            VAR_0->async_td = addr;

            return 1;

        }

    }

    if (VAR_4 >= 0) {

        if (VAR_2 == OHCI_TD_DIR_IN) {

            ohci_copy_td(VAR_0, &VAR_6, VAR_0->usb_buf, VAR_4, 1);

#ifdef DEBUG_PACKET

            DPRINTF("  data:");

            for (VAR_5 = 0; VAR_5 < VAR_4; VAR_5++)

                printf(" %.2x", VAR_0->usb_buf[VAR_5]);

            DPRINTF("\n");

#endif

        } else {

            VAR_4 = pktlen;

        }

    }



    

    if (VAR_4 == pktlen || (VAR_2 == OHCI_TD_DIR_IN && VAR_4 >= 0 && VAR_7)) {

        

        if (VAR_4 == len) {

            VAR_6.cbp = 0;

        } else {

            if ((VAR_6.cbp & 0xfff) + VAR_4 > 0xfff) {

                VAR_6.cbp = (VAR_6.be & ~0xfff) + ((VAR_6.cbp + VAR_4) & 0xfff);

            } else {

                VAR_6.cbp += VAR_4;

            }

        }

        VAR_6.flags |= OHCI_TD_T1;

        VAR_6.flags ^= OHCI_TD_T0;

        OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_NOERROR);

        OHCI_SET_BM(VAR_6.flags, TD_EC, 0);



        if ((VAR_2 != OHCI_TD_DIR_IN) && (VAR_4 != len)) {

            

            goto exit_no_retire;

        }



        

        VAR_1->head &= ~OHCI_ED_C;

        if (VAR_6.flags & OHCI_TD_T0)

            VAR_1->head |= OHCI_ED_C;

    } else {

        if (VAR_4 >= 0) {

            DPRINTF("usb-VAR_0: Underrun\n");

            OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DATAUNDERRUN);

        } else {

            switch (VAR_4) {

            case USB_RET_NODEV:

                OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);

            case USB_RET_NAK:

                DPRINTF("usb-VAR_0: got NAK\n");

                return 1;

            case USB_RET_STALL:

                DPRINTF("usb-VAR_0: got STALL\n");

                OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_STALL);

                break;

            case USB_RET_BABBLE:

                DPRINTF("usb-VAR_0: got BABBLE\n");

                OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DATAOVERRUN);

                break;

            default:

                fprintf(stderr, "usb-VAR_0: Bad device response %d\n", VAR_4);

                OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);

                OHCI_SET_BM(VAR_6.flags, TD_EC, 3);

                break;

            }

        }

        VAR_1->head |= OHCI_ED_H;

    }



    

    VAR_1->head &= ~OHCI_DPTR_MASK;

    VAR_1->head |= VAR_6.next & OHCI_DPTR_MASK;

    VAR_6.next = VAR_0->done;

    VAR_0->done = addr;

    VAR_5 = OHCI_BM(VAR_6.flags, TD_DI);

    if (VAR_5 < VAR_0->done_count)

        VAR_0->done_count = VAR_5;

exit_no_retire:

    ohci_put_td(VAR_0, addr, &VAR_6);

    return OHCI_BM(VAR_6.flags, TD_CC) != OHCI_CC_NOERROR;

}

static int FUNC_0(OHCIState *VAR_0, struct ohci_ed *VAR_1)
{ int VAR_2; size_t len = 0, pktlen = 0; #ifdef DEBUG_PACKET
const char *str = NULL; #endif
int VAR_3; int VAR_4; int VAR_5; USBDevice *dev; struct ohci_td VAR_6; uint32_t addr; int VAR_7; int VAR_8; addr = VAR_1->head & OHCI_DPTR_MASK; VAR_8 = (addr == VAR_0->async_td); if (VAR_8 && !VAR_0->async_complete) { #ifdef DEBUG_PACKET
DPRINTF("Skipping async TD\n"); #endif
return 1; } if (!ohci_read_td(VAR_0, addr, &VAR_6)) { fprintf(stderr, "usb-VAR_0: TD read error at %x\n", addr); return 0; } VAR_2 = OHCI_BM(VAR_1->flags, ED_D); switch (VAR_2) { case OHCI_TD_DIR_OUT:
case OHCI_TD_DIR_IN:
break; default:
VAR_2 = OHCI_BM(VAR_6.flags, TD_DP); break; } switch (VAR_2) { case OHCI_TD_DIR_IN:
#ifdef DEBUG_PACKET
str = "in"; #endif
VAR_3 = USB_TOKEN_IN; break; case OHCI_TD_DIR_OUT:
#ifdef DEBUG_PACKET
str = "out"; #endif
VAR_3 = USB_TOKEN_OUT; break; case OHCI_TD_DIR_SETUP:
#ifdef DEBUG_PACKET
str = "setup"; #endif
VAR_3 = USB_TOKEN_SETUP; break; default:
fprintf(stderr, "usb-VAR_0: Bad direction\n"); return 1; } if (VAR_6.cbp && VAR_6.be) { if ((VAR_6.cbp & 0xfffff000) != (VAR_6.be & 0xfffff000)) { len = (VAR_6.be & 0xfff) + 0x1001 - (VAR_6.cbp & 0xfff); } else { len = (VAR_6.be - VAR_6.cbp) + 1; } pktlen = len; if (len && VAR_2 != OHCI_TD_DIR_IN) { pktlen = (VAR_1->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT; if (pktlen > len) { pktlen = len; } if (!VAR_8) { ohci_copy_td(VAR_0, &VAR_6, VAR_0->usb_buf, pktlen, 0); } } } VAR_7 = (VAR_6.flags & OHCI_TD_R) != 0; #ifdef DEBUG_PACKET
DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64
" bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
addr, (int64_t)pktlen, (int64_t)len, str, VAR_7, VAR_6.cbp, VAR_6.be); if (pktlen > 0 && VAR_2 != OHCI_TD_DIR_IN) { DPRINTF("  data:"); for (VAR_5 = 0; VAR_5 < pktlen; VAR_5++) { printf(" %.2x", VAR_0->usb_buf[VAR_5]); } DPRINTF("\n"); } #endif
if (VAR_8) { VAR_4 = VAR_0->usb_packet.result; VAR_0->async_td = 0; VAR_0->async_complete = 0; } else { if (VAR_0->async_td) { #ifdef DEBUG_PACKET
DPRINTF("Too many pending packets\n"); #endif
return 1; } usb_packet_setup(&VAR_0->usb_packet, VAR_3,
OHCI_BM(VAR_1->flags, ED_FA),
OHCI_BM(VAR_1->flags, ED_EN)); usb_packet_addbuf(&VAR_0->usb_packet, VAR_0->usb_buf, pktlen); dev = ohci_find_device(VAR_0, VAR_0->usb_packet.devaddr); VAR_4 = usb_handle_packet(dev, &VAR_0->usb_packet); #ifdef DEBUG_PACKET
DPRINTF("VAR_4=%d\n", VAR_4); #endif
if (VAR_4 == USB_RET_ASYNC) { VAR_0->async_td = addr; return 1; } } if (VAR_4 >= 0) { if (VAR_2 == OHCI_TD_DIR_IN) { ohci_copy_td(VAR_0, &VAR_6, VAR_0->usb_buf, VAR_4, 1); #ifdef DEBUG_PACKET
DPRINTF("  data:"); for (VAR_5 = 0; VAR_5 < VAR_4; VAR_5++) printf(" %.2x", VAR_0->usb_buf[VAR_5]); DPRINTF("\n"); #endif
} else { VAR_4 = pktlen; } } if (VAR_4 == pktlen || (VAR_2 == OHCI_TD_DIR_IN && VAR_4 >= 0 && VAR_7)) { if (VAR_4 == len) { VAR_6.cbp = 0; } else { if ((VAR_6.cbp & 0xfff) + VAR_4 > 0xfff) { VAR_6.cbp = (VAR_6.be & ~0xfff) + ((VAR_6.cbp + VAR_4) & 0xfff); } else { VAR_6.cbp += VAR_4; } } VAR_6.flags |= OHCI_TD_T1; VAR_6.flags ^= OHCI_TD_T0; OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_NOERROR); OHCI_SET_BM(VAR_6.flags, TD_EC, 0); if ((VAR_2 != OHCI_TD_DIR_IN) && (VAR_4 != len)) { goto exit_no_retire; } VAR_1->head &= ~OHCI_ED_C; if (VAR_6.flags & OHCI_TD_T0)
VAR_1->head |= OHCI_ED_C; } else { if (VAR_4 >= 0) { DPRINTF("usb-VAR_0: Underrun\n"); OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DATAUNDERRUN); } else { switch (VAR_4) { case USB_RET_NODEV:
OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING); case USB_RET_NAK:
DPRINTF("usb-VAR_0: got NAK\n"); return 1; case USB_RET_STALL:
DPRINTF("usb-VAR_0: got STALL\n"); OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_STALL); break; case USB_RET_BABBLE:
DPRINTF("usb-VAR_0: got BABBLE\n"); OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_DATAOVERRUN); break; default:
fprintf(stderr, "usb-VAR_0: Bad device response %d\n", VAR_4); OHCI_SET_BM(VAR_6.flags, TD_CC, OHCI_CC_UNDEXPETEDPID); OHCI_SET_BM(VAR_6.flags, TD_EC, 3); break; } } VAR_1->head |= OHCI_ED_H; } VAR_1->head &= ~OHCI_DPTR_MASK; VAR_1->head |= VAR_6.next & OHCI_DPTR_MASK; VAR_6.next = VAR_0->done; VAR_0->done = addr; VAR_5 = OHCI_BM(VAR_6.flags, TD_DI); if (VAR_5 < VAR_0->done_count)
VAR_0->done_count = VAR_5; exit_no_retire:
ohci_put_td(VAR_0, addr, &VAR_6); return OHCI_BM(VAR_6.flags, TD_CC) != OHCI_CC_NOERROR; }