static void ehci_frame_timer(void *opaque)

{

    EHCIState *ehci = opaque;

    int need_timer = 0;

    int64_t expire_time, t_now;

    uint64_t ns_elapsed;

    uint64_t uframes, skipped_uframes;

    int i;



    t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

    ns_elapsed = t_now - ehci->last_run_ns;

    uframes = ns_elapsed / UFRAME_TIMER_NS;



    if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {

        need_timer++;



        if (uframes > (ehci->maxframes * 8)) {

            skipped_uframes = uframes - (ehci->maxframes * 8);

            ehci_update_frindex(ehci, skipped_uframes);

            ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes;

            uframes -= skipped_uframes;

            DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes);

        }



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

            /*

             * If we're running behind schedule, we should not catch up

             * too fast, as that will make some guests unhappy:

             * 1) We must process a minimum of MIN_UFR_PER_TICK frames,

             *    otherwise we will never catch up

             * 2) Process frames until the guest has requested an irq (IOC)

             */

            if (i >= MIN_UFR_PER_TICK) {

                ehci_commit_irq(ehci);

                if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {

                    break;

                }

            }

            if (ehci->periodic_sched_active) {

                ehci->periodic_sched_active--;

            }

            ehci_update_frindex(ehci, 1);

            if ((ehci->frindex & 7) == 0) {

                ehci_advance_periodic_state(ehci);

            }

            ehci->last_run_ns += UFRAME_TIMER_NS;

        }

    } else {

        ehci->periodic_sched_active = 0;

        ehci_update_frindex(ehci, uframes);

        ehci->last_run_ns += UFRAME_TIMER_NS * uframes;

    }



    if (ehci->periodic_sched_active) {

        ehci->async_stepdown = 0;

    } else if (ehci->async_stepdown < ehci->maxframes / 2) {

        ehci->async_stepdown++;

    }



    /*  Async is not inside loop since it executes everything it can once

     *  called

     */

    if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) {

        need_timer++;

        ehci_advance_async_state(ehci);

    }



    ehci_commit_irq(ehci);

    if (ehci->usbsts_pending) {

        need_timer++;

        ehci->async_stepdown = 0;

    }



    if (ehci_enabled(ehci) && (ehci->usbintr & USBSTS_FLR)) {

        need_timer++;

    }



    if (need_timer) {

        /* If we've raised int, we speed up the timer, so that we quickly

         * notice any new packets queued up in response */

        if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {

            expire_time = t_now +

                NANOSECONDS_PER_SECOND / (FRAME_TIMER_FREQ * 4);

            ehci->int_req_by_async = false;

        } else {

            expire_time = t_now + (NANOSECONDS_PER_SECOND

                               * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);

        }

        timer_mod(ehci->frame_timer, expire_time);

    }

}

static void ehci_frame_timer(void *opaque)

{

    EHCIState *ehci = opaque;

    int need_timer = 0;

    int64_t expire_time, t_now;

    uint64_t ns_elapsed;

    uint64_t uframes, skipped_uframes;

    int i;



    t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

    ns_elapsed = t_now - ehci->last_run_ns;

    uframes = ns_elapsed / UFRAME_TIMER_NS;



    if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {

        need_timer++;



        if (uframes > (ehci->maxframes * 8)) {

            skipped_uframes = uframes - (ehci->maxframes * 8);

            ehci_update_frindex(ehci, skipped_uframes);

            ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes;

            uframes -= skipped_uframes;

            DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes);

        }



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

            













            if (i >= MIN_UFR_PER_TICK) {

                ehci_commit_irq(ehci);

                if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {

                    break;

                }

            }

            if (ehci->periodic_sched_active) {

                ehci->periodic_sched_active--;

            }

            ehci_update_frindex(ehci, 1);

            if ((ehci->frindex & 7) == 0) {

                ehci_advance_periodic_state(ehci);

            }

            ehci->last_run_ns += UFRAME_TIMER_NS;

        }

    } else {

        ehci->periodic_sched_active = 0;

        ehci_update_frindex(ehci, uframes);

        ehci->last_run_ns += UFRAME_TIMER_NS * uframes;

    }



    if (ehci->periodic_sched_active) {

        ehci->async_stepdown = 0;

    } else if (ehci->async_stepdown < ehci->maxframes / 2) {

        ehci->async_stepdown++;

    }



    





    if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) {

        need_timer++;

        ehci_advance_async_state(ehci);

    }



    ehci_commit_irq(ehci);

    if (ehci->usbsts_pending) {

        need_timer++;

        ehci->async_stepdown = 0;

    }



    if (ehci_enabled(ehci) && (ehci->usbintr & USBSTS_FLR)) {

        need_timer++;

    }



    if (need_timer) {

        



        if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {

            expire_time = t_now +

                NANOSECONDS_PER_SECOND / (FRAME_TIMER_FREQ * 4);

            ehci->int_req_by_async = false;

        } else {

            expire_time = t_now + (NANOSECONDS_PER_SECOND

                               * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);

        }

        timer_mod(ehci->frame_timer, expire_time);

    }

}

static void ehci_frame_timer(void *opaque)
static void FUNC_0(void *VAR_0)

{

    EHCIState *ehci = VAR_0;

    int VAR_1 = 0;

    int64_t expire_time, t_now;

    uint64_t ns_elapsed;

    uint64_t uframes, skipped_uframes;

    int VAR_2;



    t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

    ns_elapsed = t_now - ehci->last_run_ns;

    uframes = ns_elapsed / UFRAME_TIMER_NS;



    if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {

        VAR_1++;



        if (uframes > (ehci->maxframes * 8)) {

            skipped_uframes = uframes - (ehci->maxframes * 8);

            ehci_update_frindex(ehci, skipped_uframes);

            ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes;

            uframes -= skipped_uframes;

            DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes);

        }



        for (VAR_2 = 0; VAR_2 < uframes; VAR_2++) {

            













            if (VAR_2 >= MIN_UFR_PER_TICK) {

                ehci_commit_irq(ehci);

                if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {

                    break;

                }

            }

            if (ehci->periodic_sched_active) {

                ehci->periodic_sched_active--;

            }

            ehci_update_frindex(ehci, 1);

            if ((ehci->frindex & 7) == 0) {

                ehci_advance_periodic_state(ehci);

            }

            ehci->last_run_ns += UFRAME_TIMER_NS;

        }

    } else {

        ehci->periodic_sched_active = 0;

        ehci_update_frindex(ehci, uframes);

        ehci->last_run_ns += UFRAME_TIMER_NS * uframes;

    }



    if (ehci->periodic_sched_active) {

        ehci->async_stepdown = 0;

    } else if (ehci->async_stepdown < ehci->maxframes / 2) {

        ehci->async_stepdown++;

    }



    





    if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) {

        VAR_1++;

        ehci_advance_async_state(ehci);

    }



    ehci_commit_irq(ehci);

    if (ehci->usbsts_pending) {

        VAR_1++;

        ehci->async_stepdown = 0;

    }



    if (ehci_enabled(ehci) && (ehci->usbintr & USBSTS_FLR)) {

        VAR_1++;

    }



    if (VAR_1) {

        



        if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {

            expire_time = t_now +

                NANOSECONDS_PER_SECOND / (FRAME_TIMER_FREQ * 4);

            ehci->int_req_by_async = false;

        } else {

            expire_time = t_now + (NANOSECONDS_PER_SECOND

                               * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);

        }

        timer_mod(ehci->frame_timer, expire_time);

    }

}

static void FUNC_0(void *VAR_0)
{ EHCIState *ehci = VAR_0; int VAR_1 = 0; int64_t expire_time, t_now; uint64_t ns_elapsed; uint64_t uframes, skipped_uframes; int VAR_2; t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ns_elapsed = t_now - ehci->last_run_ns; uframes = ns_elapsed / UFRAME_TIMER_NS; if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) { VAR_1++; if (uframes > (ehci->maxframes * 8)) { skipped_uframes = uframes - (ehci->maxframes * 8); ehci_update_frindex(ehci, skipped_uframes); ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes; uframes -= skipped_uframes; DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes); } for (VAR_2 = 0; VAR_2 < uframes; VAR_2++) { if (VAR_2 >= MIN_UFR_PER_TICK) { ehci_commit_irq(ehci); if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) { break; } } if (ehci->periodic_sched_active) { ehci->periodic_sched_active--; } ehci_update_frindex(ehci, 1); if ((ehci->frindex & 7) == 0) { ehci_advance_periodic_state(ehci); } ehci->last_run_ns += UFRAME_TIMER_NS; } } else { ehci->periodic_sched_active = 0; ehci_update_frindex(ehci, uframes); ehci->last_run_ns += UFRAME_TIMER_NS * uframes; } if (ehci->periodic_sched_active) { ehci->async_stepdown = 0; } else if (ehci->async_stepdown < ehci->maxframes / 2) { ehci->async_stepdown++; } if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) { VAR_1++; ehci_advance_async_state(ehci); } ehci_commit_irq(ehci); if (ehci->usbsts_pending) { VAR_1++; ehci->async_stepdown = 0; } if (ehci_enabled(ehci) && (ehci->usbintr & USBSTS_FLR)) { VAR_1++; } if (VAR_1) { if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) { expire_time = t_now +
NANOSECONDS_PER_SECOND / (FRAME_TIMER_FREQ * 4); ehci->int_req_by_async = false; } else { expire_time = t_now + (NANOSECONDS_PER_SECOND
* (ehci->async_stepdown+1) / FRAME_TIMER_FREQ); } timer_mod(ehci->frame_timer, expire_time); } }