Revision daf25307 hw/usb/hcd-ehci.c
b/hw/usb/hcd-ehci.c | ||
---|---|---|
586 | 586 |
s->usbsts_pending = 0; |
587 | 587 |
} |
588 | 588 |
|
589 |
static void ehci_update_halt(EHCIState *s) |
|
590 |
{ |
|
591 |
if (s->usbcmd & USBCMD_RUNSTOP) { |
|
592 |
ehci_clear_usbsts(s, USBSTS_HALT); |
|
593 |
} else { |
|
594 |
if (s->astate == EST_INACTIVE && s->pstate == EST_INACTIVE) { |
|
595 |
ehci_set_usbsts(s, USBSTS_HALT); |
|
596 |
} |
|
597 |
} |
|
598 |
} |
|
599 |
|
|
589 | 600 |
static void ehci_set_state(EHCIState *s, int async, int state) |
590 | 601 |
{ |
591 | 602 |
if (async) { |
... | ... | |
593 | 604 |
s->astate = state; |
594 | 605 |
if (s->astate == EST_INACTIVE) { |
595 | 606 |
ehci_clear_usbsts(s, USBSTS_ASS); |
607 |
ehci_update_halt(s); |
|
596 | 608 |
} else { |
597 | 609 |
ehci_set_usbsts(s, USBSTS_ASS); |
598 | 610 |
} |
... | ... | |
601 | 613 |
s->pstate = state; |
602 | 614 |
if (s->pstate == EST_INACTIVE) { |
603 | 615 |
ehci_clear_usbsts(s, USBSTS_PSS); |
616 |
ehci_update_halt(s); |
|
604 | 617 |
} else { |
605 | 618 |
ehci_set_usbsts(s, USBSTS_PSS); |
606 | 619 |
} |
... | ... | |
1138 | 1151 |
break; |
1139 | 1152 |
} |
1140 | 1153 |
|
1141 |
if ((val & USBCMD_RUNSTOP) && !(s->usbcmd & USBCMD_RUNSTOP)) { |
|
1142 |
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); |
|
1143 |
SET_LAST_RUN_CLOCK(s); |
|
1144 |
ehci_clear_usbsts(s, USBSTS_HALT); |
|
1145 |
} |
|
1146 |
|
|
1147 |
if (!(val & USBCMD_RUNSTOP) && (s->usbcmd & USBCMD_RUNSTOP)) { |
|
1148 |
qemu_del_timer(s->frame_timer); |
|
1149 |
qemu_bh_cancel(s->async_bh); |
|
1150 |
ehci_queues_rip_all(s, 0); |
|
1151 |
ehci_queues_rip_all(s, 1); |
|
1152 |
ehci_set_usbsts(s, USBSTS_HALT); |
|
1154 |
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) != |
|
1155 |
((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) { |
|
1156 |
if (!ehci_enabled(s)) { |
|
1157 |
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); |
|
1158 |
SET_LAST_RUN_CLOCK(s); |
|
1159 |
} |
|
1160 |
ehci_update_halt(s); |
|
1153 | 1161 |
} |
1154 | 1162 |
|
1155 |
|
|
1156 | 1163 |
/* not supporting dynamic frame list size at the moment */ |
1157 | 1164 |
if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) { |
1158 | 1165 |
fprintf(stderr, "attempt to set frame list size -- value %d\n", |
... | ... | |
2291 | 2298 |
frames = ns_elapsed / FRAME_TIMER_NS; |
2292 | 2299 |
|
2293 | 2300 |
for (i = 0; i < frames; i++) { |
2294 |
if ( !(ehci->usbsts & USBSTS_HALT)) {
|
|
2301 |
if (ehci_enabled(ehci)) {
|
|
2295 | 2302 |
ehci->frindex += 8; |
2296 | 2303 |
|
2297 | 2304 |
if (ehci->frindex == 0x00002000) { |
... | ... | |
2324 | 2331 |
*/ |
2325 | 2332 |
qemu_bh_schedule(ehci->async_bh); |
2326 | 2333 |
|
2327 |
qemu_mod_timer(ehci->frame_timer, expire_time); |
|
2334 |
if (ehci_enabled(ehci)) { |
|
2335 |
qemu_mod_timer(ehci->frame_timer, expire_time); |
|
2336 |
} |
|
2328 | 2337 |
} |
2329 | 2338 |
|
2330 | 2339 |
static void ehci_async_bh(void *opaque) |
Also available in: Unified diff