static void ehci_advance_async_state(EHCIState *ehci)

{

    const int async = 1;



    switch(ehci_get_state(ehci, async)) {

    case EST_INACTIVE:

        if (!ehci_async_enabled(ehci)) {

            break;

        }

        ehci_set_state(ehci, async, EST_ACTIVE);

        // No break, fall through to ACTIVE



    case EST_ACTIVE:

        if (!ehci_async_enabled(ehci)) {

            ehci_queues_rip_all(ehci, async);

            ehci_set_state(ehci, async, EST_INACTIVE);

            break;

        }



        /* make sure guest has acknowledged the doorbell interrupt */

        /* TO-DO: is this really needed? */

        if (ehci->usbsts & USBSTS_IAA) {

            DPRINTF("IAA status bit still set.\n");

            break;

        }



        /* check that address register has been set */

        if (ehci->asynclistaddr == 0) {

            break;

        }



        ehci_set_state(ehci, async, EST_WAITLISTHEAD);

        ehci_advance_state(ehci, async);



        /* If the doorbell is set, the guest wants to make a change to the

         * schedule. The host controller needs to release cached data.

         * (section 4.8.2)

         */

        if (ehci->usbcmd & USBCMD_IAAD) {

            /* Remove all unseen qhs from the async qhs queue */

            ehci_queues_rip_unused(ehci, async, 1);

            DPRINTF("ASYNC: doorbell request acknowledged\n");

            ehci->usbcmd &= ~USBCMD_IAAD;

            ehci_set_interrupt(ehci, USBSTS_IAA);

        }

        break;



    default:

        /* this should only be due to a developer mistake */

        fprintf(stderr, "ehci: Bad asynchronous state %d. "

                "Resetting to active\n", ehci->astate);

        assert(0);

    }

}

static void ehci_advance_async_state(EHCIState *ehci)

{

    const int async = 1;



    switch(ehci_get_state(ehci, async)) {

    case EST_INACTIVE:

        if (!ehci_async_enabled(ehci)) {

            break;

        }

        ehci_set_state(ehci, async, EST_ACTIVE);

        



    case EST_ACTIVE:

        if (!ehci_async_enabled(ehci)) {

            ehci_queues_rip_all(ehci, async);

            ehci_set_state(ehci, async, EST_INACTIVE);

            break;

        }



        

        

        if (ehci->usbsts & USBSTS_IAA) {

            DPRINTF("IAA status bit still set.\n");

            break;

        }



        

        if (ehci->asynclistaddr == 0) {

            break;

        }



        ehci_set_state(ehci, async, EST_WAITLISTHEAD);

        ehci_advance_state(ehci, async);



        







        if (ehci->usbcmd & USBCMD_IAAD) {

            

            ehci_queues_rip_unused(ehci, async, 1);

            DPRINTF("ASYNC: doorbell request acknowledged\n");

            ehci->usbcmd &= ~USBCMD_IAAD;

            ehci_set_interrupt(ehci, USBSTS_IAA);

        }

        break;



    default:

        

        fprintf(stderr, "ehci: Bad asynchronous state %d. "

                "Resetting to active\n", ehci->astate);

        assert(0);

    }

}

static void FUNC_0(EHCIState *VAR_0)

{

    const int VAR_1 = 1;



    switch(ehci_get_state(VAR_0, VAR_1)) {

    case EST_INACTIVE:

        if (!ehci_async_enabled(VAR_0)) {

            break;

        }

        ehci_set_state(VAR_0, VAR_1, EST_ACTIVE);

        



    case EST_ACTIVE:

        if (!ehci_async_enabled(VAR_0)) {

            ehci_queues_rip_all(VAR_0, VAR_1);

            ehci_set_state(VAR_0, VAR_1, EST_INACTIVE);

            break;

        }



        

        

        if (VAR_0->usbsts & USBSTS_IAA) {

            DPRINTF("IAA status bit still set.\n");

            break;

        }



        

        if (VAR_0->asynclistaddr == 0) {

            break;

        }



        ehci_set_state(VAR_0, VAR_1, EST_WAITLISTHEAD);

        ehci_advance_state(VAR_0, VAR_1);



        







        if (VAR_0->usbcmd & USBCMD_IAAD) {

            

            ehci_queues_rip_unused(VAR_0, VAR_1, 1);

            DPRINTF("ASYNC: doorbell request acknowledged\n");

            VAR_0->usbcmd &= ~USBCMD_IAAD;

            ehci_set_interrupt(VAR_0, USBSTS_IAA);

        }

        break;



    default:

        

        fprintf(stderr, "VAR_0: Bad asynchronous state %d. "

                "Resetting to active\n", VAR_0->astate);

        assert(0);

    }

}

static void FUNC_0(EHCIState *VAR_0)
{ const int VAR_1 = 1; switch(ehci_get_state(VAR_0, VAR_1)) { case EST_INACTIVE:
if (!ehci_async_enabled(VAR_0)) { break; } ehci_set_state(VAR_0, VAR_1, EST_ACTIVE); case EST_ACTIVE:
if (!ehci_async_enabled(VAR_0)) { ehci_queues_rip_all(VAR_0, VAR_1); ehci_set_state(VAR_0, VAR_1, EST_INACTIVE); break; } if (VAR_0->usbsts & USBSTS_IAA) { DPRINTF("IAA status bit still set.\n"); break; } if (VAR_0->asynclistaddr == 0) { break; } ehci_set_state(VAR_0, VAR_1, EST_WAITLISTHEAD); ehci_advance_state(VAR_0, VAR_1); if (VAR_0->usbcmd & USBCMD_IAAD) { ehci_queues_rip_unused(VAR_0, VAR_1, 1); DPRINTF("ASYNC: doorbell request acknowledged\n"); VAR_0->usbcmd &= ~USBCMD_IAAD; ehci_set_interrupt(VAR_0, USBSTS_IAA); } break; default:
fprintf(stderr, "VAR_0: Bad asynchronous state %d. "
"Resetting to active\n", VAR_0->astate); assert(0); } }