Lines Matching refs:ehci

373 static inline int get_dwords(EHCIState *ehci, uint32_t addr,  in get_dwords()  argument
378 if (!ehci->as) { in get_dwords()
379 ehci_raise_irq(ehci, USBSTS_HSE); in get_dwords()
380 ehci->usbcmd &= ~USBCMD_RUNSTOP; in get_dwords()
386 dma_memory_read(ehci->as, addr, buf, sizeof(*buf), in get_dwords()
395 static inline int put_dwords(EHCIState *ehci, uint32_t addr, in put_dwords() argument
400 if (!ehci->as) { in put_dwords()
401 ehci_raise_irq(ehci, USBSTS_HSE); in put_dwords()
402 ehci->usbcmd &= ~USBCMD_RUNSTOP; in put_dwords()
409 dma_memory_write(ehci->as, addr, &tmp, sizeof(tmp), in put_dwords()
485 get_dwords(q->ehci, NLPTR_GET(q->qhaddr), in ehci_writeback_async_complete_packet()
487 get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), in ehci_writeback_async_complete_packet()
495 state = ehci_get_state(q->ehci, q->async); in ehci_writeback_async_complete_packet()
501 ehci_set_state(q->ehci, q->async, state); in ehci_writeback_async_complete_packet()
547 static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async) in ehci_alloc_queue() argument
549 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_alloc_queue()
553 q->ehci = ehci; in ehci_alloc_queue()
608 EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues; in ehci_free_queue()
614 ehci_trace_guest_bug(q->ehci, warn); in ehci_free_queue()
620 static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr, in ehci_find_queue_by_qh() argument
623 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_find_queue_by_qh()
634 static void ehci_queues_rip_unused(EHCIState *ehci, int async) in ehci_queues_rip_unused() argument
636 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_queues_rip_unused()
638 uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4; in ehci_queues_rip_unused()
644 q->ts = ehci->last_run_ns; in ehci_queues_rip_unused()
647 if (ehci->last_run_ns < q->ts + maxage) { in ehci_queues_rip_unused()
654 static void ehci_queues_rip_unseen(EHCIState *ehci, int async) in ehci_queues_rip_unseen() argument
656 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_queues_rip_unseen()
666 static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async) in ehci_queues_rip_device() argument
668 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_queues_rip_device()
679 static void ehci_queues_rip_all(EHCIState *ehci, int async) in ehci_queues_rip_all() argument
681 EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; in ehci_queues_rip_all()
828 static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr) in ehci_find_device() argument
835 port = &ehci->ports[i]; in ehci_find_device()
836 if (!(ehci->portsc[i] & PORTSC_PED)) { in ehci_find_device()
1131 put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3); in ehci_flush_qh()
1194 qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as); in ehci_init_transfer()
1289 ehci_raise_irq(q->ehci, USBSTS_ERRINT); in ehci_execute_complete()
1293 ehci_raise_irq(q->ehci, USBSTS_ERRINT); in ehci_execute_complete()
1300 ehci_raise_irq(q->ehci, USBSTS_ERRINT); in ehci_execute_complete()
1314 ehci_raise_irq(q->ehci, USBSTS_INT); in ehci_execute_complete()
1316 q->ehci->int_req_by_async = true; in ehci_execute_complete()
1334 ehci_raise_irq(q->ehci, USBSTS_INT); in ehci_execute_complete()
1336 q->ehci->int_req_by_async = true; in ehci_execute_complete()
1357 ehci_trace_guest_bug(p->queue->ehci, in ehci_execute()
1403 static int ehci_process_itd(EHCIState *ehci, in ehci_process_itd() argument
1412 ehci->periodic_sched_active = PERIODIC_ACTIVE; in ehci_process_itd()
1434 qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as); in ehci_process_itd()
1438 qemu_sglist_destroy(&ehci->isgl); in ehci_process_itd()
1444 qemu_sglist_add(&ehci->isgl, ptr1 + off, len1); in ehci_process_itd()
1445 qemu_sglist_add(&ehci->isgl, ptr2, len2); in ehci_process_itd()
1447 qemu_sglist_add(&ehci->isgl, ptr1 + off, len); in ehci_process_itd()
1450 dev = ehci_find_device(ehci, devaddr); in ehci_process_itd()
1452 ehci_trace_guest_bug(ehci, "no device found"); in ehci_process_itd()
1453 ehci->ipacket.status = USB_RET_NODEV; in ehci_process_itd()
1454 ehci->ipacket.actual_length = 0; in ehci_process_itd()
1459 usb_packet_setup(&ehci->ipacket, pid, ep, 0, addr, false, in ehci_process_itd()
1461 if (usb_packet_map(&ehci->ipacket, &ehci->isgl)) { in ehci_process_itd()
1462 qemu_sglist_destroy(&ehci->isgl); in ehci_process_itd()
1465 usb_handle_packet(dev, &ehci->ipacket); in ehci_process_itd()
1466 usb_packet_unmap(&ehci->ipacket, &ehci->isgl); in ehci_process_itd()
1469 ehci->ipacket.status = USB_RET_NAK; in ehci_process_itd()
1470 ehci->ipacket.actual_length = 0; in ehci_process_itd()
1473 qemu_sglist_destroy(&ehci->isgl); in ehci_process_itd()
1475 switch (ehci->ipacket.status) { in ehci_process_itd()
1480 ehci->ipacket.status); in ehci_process_itd()
1487 ehci_raise_irq(ehci, USBSTS_ERRINT); in ehci_process_itd()
1492 ehci_raise_irq(ehci, USBSTS_ERRINT); in ehci_process_itd()
1496 ehci->ipacket.actual_length = 0; in ehci_process_itd()
1500 set_field(&itd->transact[i], len - ehci->ipacket.actual_length, in ehci_process_itd()
1503 set_field(&itd->transact[i], ehci->ipacket.actual_length, in ehci_process_itd()
1507 ehci_raise_irq(ehci, USBSTS_INT); in ehci_process_itd()
1519 static int ehci_state_waitlisthead(EHCIState *ehci, int async) in ehci_state_waitlisthead() argument
1524 uint32_t entry = ehci->asynclistaddr; in ehci_state_waitlisthead()
1528 ehci_set_usbsts(ehci, USBSTS_REC); in ehci_state_waitlisthead()
1531 ehci_queues_rip_unused(ehci, async); in ehci_state_waitlisthead()
1535 if (get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh, in ehci_state_waitlisthead()
1546 ehci_set_fetch_addr(ehci, async, entry); in ehci_state_waitlisthead()
1547 ehci_set_state(ehci, async, EST_FETCHENTRY); in ehci_state_waitlisthead()
1553 if (entry == ehci->asynclistaddr) { in ehci_state_waitlisthead()
1560 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_state_waitlisthead()
1570 static int ehci_state_fetchentry(EHCIState *ehci, int async) in ehci_state_fetchentry() argument
1573 uint32_t entry = ehci_get_fetch_addr(ehci, async); in ehci_state_fetchentry()
1576 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_state_fetchentry()
1588 ehci_set_state(ehci, async, EST_FETCHQH); in ehci_state_fetchentry()
1593 ehci_set_state(ehci, async, EST_FETCHITD); in ehci_state_fetchentry()
1598 ehci_set_state(ehci, async, EST_FETCHSITD); in ehci_state_fetchentry()
1613 static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) in ehci_state_fetchqh() argument
1619 entry = ehci_get_fetch_addr(ehci, async); in ehci_state_fetchqh()
1620 q = ehci_find_queue_by_qh(ehci, entry, async); in ehci_state_fetchqh()
1622 q = ehci_alloc_queue(ehci, entry, async); in ehci_state_fetchqh()
1628 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_state_fetchqh()
1633 if (get_dwords(ehci, NLPTR_GET(q->qhaddr), in ehci_state_fetchqh()
1646 ehci_trace_guest_bug(ehci, "guest updated active QH"); in ehci_state_fetchqh()
1657 q->dev = ehci_find_device(q->ehci, in ehci_state_fetchqh()
1664 if (ehci->usbsts & USBSTS_REC) { in ehci_state_fetchqh()
1665 ehci_clear_usbsts(ehci, USBSTS_REC); in ehci_state_fetchqh()
1669 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_state_fetchqh()
1687 ehci_set_state(ehci, async, EST_HORIZONTALQH); in ehci_state_fetchqh()
1693 ehci_set_state(ehci, async, EST_FETCHQTD); in ehci_state_fetchqh()
1697 ehci_set_state(ehci, async, EST_ADVANCEQUEUE); in ehci_state_fetchqh()
1704 static int ehci_state_fetchitd(EHCIState *ehci, int async) in ehci_state_fetchitd() argument
1710 entry = ehci_get_fetch_addr(ehci, async); in ehci_state_fetchitd()
1712 if (get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd, in ehci_state_fetchitd()
1716 ehci_trace_itd(ehci, entry, &itd); in ehci_state_fetchitd()
1718 if (ehci_process_itd(ehci, &itd, entry) != 0) { in ehci_state_fetchitd()
1722 put_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd, in ehci_state_fetchitd()
1724 ehci_set_fetch_addr(ehci, async, itd.next); in ehci_state_fetchitd()
1725 ehci_set_state(ehci, async, EST_FETCHENTRY); in ehci_state_fetchitd()
1730 static int ehci_state_fetchsitd(EHCIState *ehci, int async) in ehci_state_fetchsitd() argument
1736 entry = ehci_get_fetch_addr(ehci, async); in ehci_state_fetchsitd()
1738 if (get_dwords(ehci, NLPTR_GET(entry), (uint32_t *)&sitd, in ehci_state_fetchsitd()
1742 ehci_trace_sitd(ehci, entry, &sitd); in ehci_state_fetchsitd()
1751 ehci_set_fetch_addr(ehci, async, sitd.next); in ehci_state_fetchsitd()
1752 ehci_set_state(ehci, async, EST_FETCHENTRY); in ehci_state_fetchsitd()
1765 ehci_set_state(ehci, async, EST_HORIZONTALQH); in ehci_state_advqueue()
1776 ehci_set_state(q->ehci, q->async, EST_FETCHQTD); in ehci_state_advqueue()
1783 ehci_set_state(q->ehci, q->async, EST_FETCHQTD); in ehci_state_advqueue()
1789 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_advqueue()
1804 if (get_dwords(q->ehci, addr + 8, &qtd.token, 1) < 0) { in ehci_state_fetchqtd()
1808 if (get_dwords(q->ehci, addr + 0, &qtd.next, 1) < 0 || in ehci_state_fetchqtd()
1809 get_dwords(q->ehci, addr + 4, &qtd.altnext, 1) < 0 || in ehci_state_fetchqtd()
1810 get_dwords(q->ehci, addr + 12, qtd.bufptr, in ehci_state_fetchqtd()
1821 ehci_trace_guest_bug(q->ehci, "guest updated active qTD"); in ehci_state_fetchqtd()
1831 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_fetchqtd()
1837 ehci_set_state(q->ehci, q->async, EST_EXECUTE); in ehci_state_fetchqtd()
1843 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_fetchqtd()
1847 ehci_set_state(q->ehci, q->async, EST_EXECUTING); in ehci_state_fetchqtd()
1851 ehci_trace_guest_bug(q->ehci, "no device attached to queue"); in ehci_state_fetchqtd()
1852 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_fetchqtd()
1857 ehci_set_state(q->ehci, q->async, EST_EXECUTE); in ehci_state_fetchqtd()
1867 if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) { in ehci_state_horizqh()
1868 ehci_set_fetch_addr(q->ehci, q->async, q->qh.next); in ehci_state_horizqh()
1869 ehci_set_state(q->ehci, q->async, EST_FETCHENTRY); in ehci_state_horizqh()
1872 ehci_set_state(q->ehci, q->async, EST_ACTIVE); in ehci_state_horizqh()
1900 if (get_dwords(q->ehci, NLPTR_GET(qtdaddr), in ehci_fill_queue()
1909 ehci_trace_guest_bug(q->ehci, "guest queued token with wrong pid"); in ehci_fill_queue()
1943 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_execute()
1949 ehci_set_usbsts(q->ehci, USBSTS_REC); in ehci_state_execute()
1960 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_execute()
1969 ehci_set_state(q->ehci, q->async, EST_EXECUTING); in ehci_state_execute()
1992 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_executing()
1994 ehci_set_state(q->ehci, q->async, EST_WRITEBACK); in ehci_state_executing()
2016 put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qtd + 3, 1); in ehci_state_writeback()
2018 put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 1); in ehci_state_writeback()
2030 ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); in ehci_state_writeback()
2033 ehci_set_state(q->ehci, q->async, EST_ADVANCEQUEUE); in ehci_state_writeback()
2043 static void ehci_advance_state(EHCIState *ehci, int async) in ehci_advance_state() argument
2050 switch(ehci_get_state(ehci, async)) { in ehci_advance_state()
2052 again = ehci_state_waitlisthead(ehci, async); in ehci_advance_state()
2056 again = ehci_state_fetchentry(ehci, async); in ehci_advance_state()
2060 q = ehci_state_fetchqh(ehci, async); in ehci_advance_state()
2070 again = ehci_state_fetchitd(ehci, async); in ehci_advance_state()
2075 again = ehci_state_fetchsitd(ehci, async); in ehci_advance_state()
2098 ehci->async_stepdown = 0; in ehci_advance_state()
2105 ehci->async_stepdown = 0; in ehci_advance_state()
2114 ehci->periodic_sched_active = PERIODIC_ACTIVE; in ehci_advance_state()
2126 ehci_reset(ehci); in ehci_advance_state()
2133 static void ehci_advance_async_state(EHCIState *ehci) in ehci_advance_async_state() argument
2137 switch(ehci_get_state(ehci, async)) { in ehci_advance_async_state()
2139 if (!ehci_async_enabled(ehci)) { in ehci_advance_async_state()
2142 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_advance_async_state()
2146 if (!ehci_async_enabled(ehci)) { in ehci_advance_async_state()
2147 ehci_queues_rip_all(ehci, async); in ehci_advance_async_state()
2148 ehci_set_state(ehci, async, EST_INACTIVE); in ehci_advance_async_state()
2154 if (ehci->usbsts & USBSTS_IAA) { in ehci_advance_async_state()
2160 if (ehci->asynclistaddr == 0) { in ehci_advance_async_state()
2164 ehci_set_state(ehci, async, EST_WAITLISTHEAD); in ehci_advance_async_state()
2165 ehci_advance_state(ehci, async); in ehci_advance_async_state()
2171 if (ehci->usbcmd & USBCMD_IAAD) { in ehci_advance_async_state()
2173 ehci_queues_rip_unseen(ehci, async); in ehci_advance_async_state()
2175 ehci->usbcmd &= ~USBCMD_IAAD; in ehci_advance_async_state()
2176 ehci_raise_irq(ehci, USBSTS_IAA); in ehci_advance_async_state()
2183 "Resetting to active\n", ehci->astate); in ehci_advance_async_state()
2188 static void ehci_advance_periodic_state(EHCIState *ehci) in ehci_advance_periodic_state() argument
2196 switch(ehci_get_state(ehci, async)) { in ehci_advance_periodic_state()
2198 if (!(ehci->frindex & 7) && ehci_periodic_enabled(ehci)) { in ehci_advance_periodic_state()
2199 ehci_set_state(ehci, async, EST_ACTIVE); in ehci_advance_periodic_state()
2205 if (!(ehci->frindex & 7) && !ehci_periodic_enabled(ehci)) { in ehci_advance_periodic_state()
2206 ehci_queues_rip_all(ehci, async); in ehci_advance_periodic_state()
2207 ehci_set_state(ehci, async, EST_INACTIVE); in ehci_advance_periodic_state()
2211 list = ehci->periodiclistbase & 0xfffff000; in ehci_advance_periodic_state()
2216 list |= ((ehci->frindex & 0x1ff8) >> 1); in ehci_advance_periodic_state()
2218 if (get_dwords(ehci, list, &entry, 1) < 0) { in ehci_advance_periodic_state()
2223 ehci->frindex / 8, list, entry); in ehci_advance_periodic_state()
2224 ehci_set_fetch_addr(ehci, async,entry); in ehci_advance_periodic_state()
2225 ehci_set_state(ehci, async, EST_FETCHENTRY); in ehci_advance_periodic_state()
2226 ehci_advance_state(ehci, async); in ehci_advance_periodic_state()
2227 ehci_queues_rip_unused(ehci, async); in ehci_advance_periodic_state()
2233 "Resetting to active\n", ehci->pstate); in ehci_advance_periodic_state()
2238 static void ehci_update_frindex(EHCIState *ehci, int uframes) in ehci_update_frindex() argument
2240 if (!ehci_enabled(ehci) && ehci->pstate == EST_INACTIVE) { in ehci_update_frindex()
2245 if ((ehci->frindex % 0x2000) + uframes >= 0x2000) { in ehci_update_frindex()
2246 ehci_raise_irq(ehci, USBSTS_FLR); in ehci_update_frindex()
2252 int rollovers = (ehci->frindex + uframes) / 0x4000; in ehci_update_frindex()
2254 if (ehci->usbsts_frindex >= (rollovers * 0x4000)) { in ehci_update_frindex()
2255 ehci->usbsts_frindex -= 0x4000 * rollovers; in ehci_update_frindex()
2257 ehci->usbsts_frindex = 0; in ehci_update_frindex()
2261 ehci->frindex = (ehci->frindex + uframes) % 0x4000; in ehci_update_frindex()
2266 EHCIState *ehci = opaque; in ehci_work_bh() local
2273 if (ehci->working) { in ehci_work_bh()
2276 ehci->working = true; in ehci_work_bh()
2279 ns_elapsed = t_now - ehci->last_run_ns; in ehci_work_bh()
2282 if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) { in ehci_work_bh()
2285 if (uframes > (ehci->maxframes * 8)) { in ehci_work_bh()
2286 skipped_uframes = uframes - (ehci->maxframes * 8); in ehci_work_bh()
2287 ehci_update_frindex(ehci, skipped_uframes); in ehci_work_bh()
2288 ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes; in ehci_work_bh()
2302 ehci_commit_irq(ehci); in ehci_work_bh()
2303 if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) { in ehci_work_bh()
2307 if (ehci->periodic_sched_active) { in ehci_work_bh()
2308 ehci->periodic_sched_active--; in ehci_work_bh()
2310 ehci_update_frindex(ehci, 1); in ehci_work_bh()
2311 if ((ehci->frindex & 7) == 0) { in ehci_work_bh()
2312 ehci_advance_periodic_state(ehci); in ehci_work_bh()
2314 ehci->last_run_ns += UFRAME_TIMER_NS; in ehci_work_bh()
2317 ehci->periodic_sched_active = 0; in ehci_work_bh()
2318 ehci_update_frindex(ehci, uframes); in ehci_work_bh()
2319 ehci->last_run_ns += UFRAME_TIMER_NS * uframes; in ehci_work_bh()
2322 if (ehci->periodic_sched_active) { in ehci_work_bh()
2323 ehci->async_stepdown = 0; in ehci_work_bh()
2324 } else if (ehci->async_stepdown < ehci->maxframes / 2) { in ehci_work_bh()
2325 ehci->async_stepdown++; in ehci_work_bh()
2331 if (ehci_async_enabled(ehci) || ehci->astate != EST_INACTIVE) { in ehci_work_bh()
2333 ehci_advance_async_state(ehci); in ehci_work_bh()
2336 ehci_commit_irq(ehci); in ehci_work_bh()
2337 if (ehci->usbsts_pending) { in ehci_work_bh()
2339 ehci->async_stepdown = 0; in ehci_work_bh()
2342 if (ehci_enabled(ehci) && (ehci->usbintr & USBSTS_FLR)) { in ehci_work_bh()
2349 if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) { in ehci_work_bh()
2352 ehci->int_req_by_async = false; in ehci_work_bh()
2355 * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ); in ehci_work_bh()
2357 timer_mod(ehci->frame_timer, expire_time); in ehci_work_bh()
2360 ehci->working = false; in ehci_work_bh()
2365 EHCIState *ehci = opaque; in ehci_work_timer() local
2367 qemu_bh_schedule(ehci->async_bh); in ehci_work_timer()
2414 EHCIState *ehci = opaque; in usb_ehci_pre_save() local
2418 new_frindex = ehci->frindex & ~7; in usb_ehci_pre_save()
2419 ehci->last_run_ns -= (ehci->frindex - new_frindex) * UFRAME_TIMER_NS; in usb_ehci_pre_save()
2420 ehci->frindex = new_frindex; in usb_ehci_pre_save()
2447 EHCIState *ehci = opaque; in usb_ehci_vm_state_change() local
2456 ehci_advance_async_state(ehci); in usb_ehci_vm_state_change()
2466 ehci_advance_async_state(ehci); in usb_ehci_vm_state_change()
2467 ehci_queues_rip_unseen(ehci, 1); in usb_ehci_vm_state_change()