static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)

{

    UHCIAsync *async;

    int len = 0, max_len;

    uint8_t pid;



    /* Is active ? */

    if (!(td->ctrl & TD_CTRL_ACTIVE))

        return 1;



    async = uhci_async_find_td(s, addr, td->token);

    if (async) {

        /* Already submitted */

        async->valid = 32;



        if (!async->done)

            return 1;



        uhci_async_unlink(s, async);

        goto done;

    }



    /* Allocate new packet */

    async = uhci_async_alloc(s);

    if (!async)

        return 1;



    async->valid = 10;

    async->td    = addr;

    async->token = td->token;



    max_len = ((td->token >> 21) + 1) & 0x7ff;

    pid = td->token & 0xff;



    async->packet.pid     = pid;

    async->packet.devaddr = (td->token >> 8) & 0x7f;

    async->packet.devep   = (td->token >> 15) & 0xf;

    async->packet.data    = async->buffer;

    async->packet.len     = max_len;

    async->packet.complete_cb     = uhci_async_complete;

    async->packet.complete_opaque = s;



    switch(pid) {

    case USB_TOKEN_OUT:

    case USB_TOKEN_SETUP:

        cpu_physical_memory_read(td->buffer, async->buffer, max_len);

        len = uhci_broadcast_packet(s, &async->packet);

        if (len >= 0)

            len = max_len;

        break;



    case USB_TOKEN_IN:

        len = uhci_broadcast_packet(s, &async->packet);

        break;



    default:

        /* invalid pid : frame interrupted */

        uhci_async_free(s, async);

        s->status |= UHCI_STS_HCPERR;

        uhci_update_irq(s);

        return -1;

    }

 

    if (len == USB_RET_ASYNC) {

        uhci_async_link(s, async);

        return 2;

    }



    async->packet.len = len;



done:

    len = uhci_complete_td(s, td, async, int_mask);

    uhci_async_free(s, async);

    return len;

}

static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)

{

    UHCIAsync *async;

    int len = 0, max_len;

    uint8_t pid;



    

    if (!(td->ctrl & TD_CTRL_ACTIVE))

        return 1;



    async = uhci_async_find_td(s, addr, td->token);

    if (async) {

        

        async->valid = 32;



        if (!async->done)

            return 1;



        uhci_async_unlink(s, async);

        goto done;

    }



    

    async = uhci_async_alloc(s);

    if (!async)

        return 1;



    async->valid = 10;

    async->td    = addr;

    async->token = td->token;



    max_len = ((td->token >> 21) + 1) & 0x7ff;

    pid = td->token & 0xff;



    async->packet.pid     = pid;

    async->packet.devaddr = (td->token >> 8) & 0x7f;

    async->packet.devep   = (td->token >> 15) & 0xf;

    async->packet.data    = async->buffer;

    async->packet.len     = max_len;

    async->packet.complete_cb     = uhci_async_complete;

    async->packet.complete_opaque = s;



    switch(pid) {

    case USB_TOKEN_OUT:

    case USB_TOKEN_SETUP:

        cpu_physical_memory_read(td->buffer, async->buffer, max_len);

        len = uhci_broadcast_packet(s, &async->packet);

        if (len >= 0)

            len = max_len;

        break;



    case USB_TOKEN_IN:

        len = uhci_broadcast_packet(s, &async->packet);

        break;



    default:

        

        uhci_async_free(s, async);

        s->status |= UHCI_STS_HCPERR;

        uhci_update_irq(s);

        return -1;

    }

 

    if (len == USB_RET_ASYNC) {

        uhci_async_link(s, async);

        return 2;

    }



    async->packet.len = len;



done:

    len = uhci_complete_td(s, td, async, int_mask);

    uhci_async_free(s, async);

    return len;

}

static int FUNC_0(UHCIState *VAR_0, uint32_t VAR_1, UHCI_TD *VAR_2, uint32_t *VAR_3)

{

    UHCIAsync *async;

    int VAR_4 = 0, VAR_5;

    uint8_t pid;



    

    if (!(VAR_2->ctrl & TD_CTRL_ACTIVE))

        return 1;



    async = uhci_async_find_td(VAR_0, VAR_1, VAR_2->token);

    if (async) {

        

        async->valid = 32;



        if (!async->done)

            return 1;



        uhci_async_unlink(VAR_0, async);

        goto done;

    }



    

    async = uhci_async_alloc(VAR_0);

    if (!async)

        return 1;



    async->valid = 10;

    async->VAR_2    = VAR_1;

    async->token = VAR_2->token;



    VAR_5 = ((VAR_2->token >> 21) + 1) & 0x7ff;

    pid = VAR_2->token & 0xff;



    async->packet.pid     = pid;

    async->packet.devaddr = (VAR_2->token >> 8) & 0x7f;

    async->packet.devep   = (VAR_2->token >> 15) & 0xf;

    async->packet.data    = async->buffer;

    async->packet.VAR_4     = VAR_5;

    async->packet.complete_cb     = uhci_async_complete;

    async->packet.complete_opaque = VAR_0;



    switch(pid) {

    case USB_TOKEN_OUT:

    case USB_TOKEN_SETUP:

        cpu_physical_memory_read(VAR_2->buffer, async->buffer, VAR_5);

        VAR_4 = uhci_broadcast_packet(VAR_0, &async->packet);

        if (VAR_4 >= 0)

            VAR_4 = VAR_5;

        break;



    case USB_TOKEN_IN:

        VAR_4 = uhci_broadcast_packet(VAR_0, &async->packet);

        break;



    default:

        

        uhci_async_free(VAR_0, async);

        VAR_0->status |= UHCI_STS_HCPERR;

        uhci_update_irq(VAR_0);

        return -1;

    }

 

    if (VAR_4 == USB_RET_ASYNC) {

        uhci_async_link(VAR_0, async);

        return 2;

    }



    async->packet.VAR_4 = VAR_4;



done:

    VAR_4 = uhci_complete_td(VAR_0, VAR_2, async, VAR_3);

    uhci_async_free(VAR_0, async);

    return VAR_4;

}

static int FUNC_0(UHCIState *VAR_0, uint32_t VAR_1, UHCI_TD *VAR_2, uint32_t *VAR_3)
{ UHCIAsync *async; int VAR_4 = 0, VAR_5; uint8_t pid; if (!(VAR_2->ctrl & TD_CTRL_ACTIVE))
return 1; async = uhci_async_find_td(VAR_0, VAR_1, VAR_2->token); if (async) { async->valid = 32; if (!async->done)
return 1; uhci_async_unlink(VAR_0, async); goto done; } async = uhci_async_alloc(VAR_0); if (!async)
return 1; async->valid = 10; async->VAR_2    = VAR_1; async->token = VAR_2->token; VAR_5 = ((VAR_2->token >> 21) + 1) & 0x7ff; pid = VAR_2->token & 0xff; async->packet.pid     = pid; async->packet.devaddr = (VAR_2->token >> 8) & 0x7f; async->packet.devep   = (VAR_2->token >> 15) & 0xf; async->packet.data    = async->buffer; async->packet.VAR_4     = VAR_5; async->packet.complete_cb     = uhci_async_complete; async->packet.complete_opaque = VAR_0; switch(pid) { case USB_TOKEN_OUT:
case USB_TOKEN_SETUP:
cpu_physical_memory_read(VAR_2->buffer, async->buffer, VAR_5); VAR_4 = uhci_broadcast_packet(VAR_0, &async->packet); if (VAR_4 >= 0)
VAR_4 = VAR_5; break; case USB_TOKEN_IN:
VAR_4 = uhci_broadcast_packet(VAR_0, &async->packet); break; default:
uhci_async_free(VAR_0, async); VAR_0->status |= UHCI_STS_HCPERR; uhci_update_irq(VAR_0); return -1; } if (VAR_4 == USB_RET_ASYNC) { uhci_async_link(VAR_0, async); return 2; } async->packet.VAR_4 = VAR_4; done:
VAR_4 = uhci_complete_td(VAR_0, VAR_2, async, VAR_3); uhci_async_free(VAR_0, async); return VAR_4; }