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

{

    int dir;

    size_t len = 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;

        }



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

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

        }

    }



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

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

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



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

        DPRINTF("  data:");

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

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

        DPRINTF("\n");

    }

#endif

    if (completion) {

        ret = ohci->usb_packet.len;

        ohci->async_td = 0;

        ohci->async_complete = 0;

    } else {

        ret = USB_RET_NODEV;

        for (i = 0; i < ohci->num_ports; i++) {

            dev = ohci->rhport[i].port.dev;

            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)

                continue;



            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;

            }

            ohci->usb_packet.pid = pid;

            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);

            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);

            ohci->usb_packet.data = ohci->usb_buf;

            ohci->usb_packet.len = len;

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

            if (ret != USB_RET_NODEV)

                break;

        }

#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 = len;

        }

    }



    /* Writeback */

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

        /* Transmission succeeded.  */

        if (ret == len) {

            td.cbp = 0;

        } else {

            td.cbp += ret;

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

                td.cbp &= 0xfff;

                td.cbp |= td.be & ~0xfff;

            }

        }

        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);



        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;

    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;

#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;

        }



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

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

        }

    }



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

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

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



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

        DPRINTF("  data:");

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

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

        DPRINTF("\n");

    }

#endif

    if (completion) {

        ret = ohci->usb_packet.len;

        ohci->async_td = 0;

        ohci->async_complete = 0;

    } else {

        ret = USB_RET_NODEV;

        for (i = 0; i < ohci->num_ports; i++) {

            dev = ohci->rhport[i].port.dev;

            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)

                continue;



            if (ohci->async_td) {

                









#ifdef DEBUG_PACKET

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

#endif

                return 1;

            }

            ohci->usb_packet.pid = pid;

            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);

            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);

            ohci->usb_packet.data = ohci->usb_buf;

            ohci->usb_packet.len = len;

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

            if (ret != USB_RET_NODEV)

                break;

        }

#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 = len;

        }

    }



    

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

        

        if (ret == len) {

            td.cbp = 0;

        } else {

            td.cbp += ret;

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

                td.cbp &= 0xfff;

                td.cbp |= td.be & ~0xfff;

            }

        }

        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);



        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;

    ohci_put_td(ohci, addr, &td);

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

}

        ret = ohci->usb_packet.len;             ohci->usb_packet.pid = pid;             ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);             ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);             ohci->usb_packet.data = ohci->usb_buf;             ohci->usb_packet.len = len;         ret = ohci->usb_packet.len;             ohci->usb_packet.pid = pid;             ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);             ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);             ohci->usb_packet.data = ohci->usb_buf;             ohci->usb_packet.len = len;     int i;
static int FUNC_0(OHCIState *VAR_0, struct ohci_ed *VAR_1)

{

    int VAR_2;

    size_t len = 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;

        }



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

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

        }

    }



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

#ifdef DEBUG_PACKET

    DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",

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



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

        DPRINTF("  data:");

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

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

        DPRINTF("\n");

    }

#endif

    if (VAR_8) {

        VAR_4 = VAR_0->usb_packet.len;

        VAR_0->async_td = 0;

        VAR_0->async_complete = 0;

    } else {

        VAR_4 = USB_RET_NODEV;

        for (VAR_5 = 0; VAR_5 < VAR_0->num_ports; VAR_5++) {

            dev = VAR_0->rhport[VAR_5].port.dev;

            if ((VAR_0->rhport[VAR_5].ctrl & OHCI_PORT_PES) == 0)

                continue;



            if (VAR_0->async_td) {

                









#ifdef DEBUG_PACKET

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

#endif

                return 1;

            }

            VAR_0->usb_packet.VAR_3 = VAR_3;

            VAR_0->usb_packet.devaddr = OHCI_BM(VAR_1->flags, ED_FA);

            VAR_0->usb_packet.devep = OHCI_BM(VAR_1->flags, ED_EN);

            VAR_0->usb_packet.data = VAR_0->usb_buf;

            VAR_0->usb_packet.len = len;

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

            if (VAR_4 != USB_RET_NODEV)

                break;

        }

#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 = len;

        }

    }



    

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

        

        if (VAR_4 == len) {

            VAR_6.cbp = 0;

        } else {

            VAR_6.cbp += VAR_4;

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

                VAR_6.cbp &= 0xfff;

                VAR_6.cbp |= VAR_6.be & ~0xfff;

            }

        }

        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);



        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;

    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; #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; } if (len && VAR_2 != OHCI_TD_DIR_IN && !VAR_8) { ohci_copy_td(VAR_0, &VAR_6, VAR_0->usb_buf, len, 0); } } VAR_7 = (VAR_6.flags & OHCI_TD_R) != 0; #ifdef DEBUG_PACKET
DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
addr, (int64_t)len, str, VAR_7, VAR_6.cbp, VAR_6.be); if (len > 0 && VAR_2 != OHCI_TD_DIR_IN) { DPRINTF("  data:"); for (VAR_5 = 0; VAR_5 < len; VAR_5++) printf(" %.2x", VAR_0->usb_buf[VAR_5]); DPRINTF("\n"); } #endif
if (VAR_8) { VAR_4 = VAR_0->usb_packet.len; VAR_0->async_td = 0; VAR_0->async_complete = 0; } else { VAR_4 = USB_RET_NODEV; for (VAR_5 = 0; VAR_5 < VAR_0->num_ports; VAR_5++) { dev = VAR_0->rhport[VAR_5].port.dev; if ((VAR_0->rhport[VAR_5].ctrl & OHCI_PORT_PES) == 0)
continue; if (VAR_0->async_td) { #ifdef DEBUG_PACKET
DPRINTF("Too many pending packets\n"); #endif
return 1; } VAR_0->usb_packet.VAR_3 = VAR_3; VAR_0->usb_packet.devaddr = OHCI_BM(VAR_1->flags, ED_FA); VAR_0->usb_packet.devep = OHCI_BM(VAR_1->flags, ED_EN); VAR_0->usb_packet.data = VAR_0->usb_buf; VAR_0->usb_packet.len = len; VAR_4 = usb_handle_packet(dev, &VAR_0->usb_packet); if (VAR_4 != USB_RET_NODEV)
break; } #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 = len; } } if (VAR_4 == len || (VAR_2 == OHCI_TD_DIR_IN && VAR_4 >= 0 && VAR_7)) { if (VAR_4 == len) { VAR_6.cbp = 0; } else { VAR_6.cbp += VAR_4; if ((VAR_6.cbp & 0xfff) + VAR_4 > 0xfff) { VAR_6.cbp &= 0xfff; VAR_6.cbp |= VAR_6.be & ~0xfff; } } 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); 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; ohci_put_td(VAR_0, addr, &VAR_6); return OHCI_BM(VAR_6.flags, TD_CC) != OHCI_CC_NOERROR; }