Lines Matching +full:qemu +full:- +full:bundle

5  * Date: 2011-05-11 ;  Author: Hector Martin <hector@marcansoft.com>
6 * Based on usb-ohci.c, emulates Renesas NEC USB 3.0
22 #include "qemu/osdep.h"
23 #include "qemu/timer.h"
24 #include "qemu/log.h"
25 #include "qemu/module.h"
26 #include "qemu/queue.h"
28 #include "hw/qdev-properties.h"
32 #include "hcd-xhci.h"
415 return lookup_name(event->ccode, TRBCCode_names, in event_name()
427 return xhci->flags & (1 << bit); in xhci_get_flag()
432 xhci->flags |= (1 << bit); in xhci_set_flag()
438 return (now - xhci->mfindex_start) / 125000; in xhci_mfindex_get()
447 if ((xhci->usbcmd & bits) == bits) { in xhci_mfwrap_update()
449 mfindex = ((now - xhci->mfindex_start) / 125000) & 0x3fff; in xhci_mfwrap_update()
450 left = 0x4000 - mfindex; in xhci_mfwrap_update()
451 timer_mod(xhci->mfwrap_timer, now + left * 125000); in xhci_mfwrap_update()
453 timer_del(xhci->mfwrap_timer); in xhci_mfwrap_update()
468 xhci->usbsts |= USBSTS_HCE; in xhci_die()
497 if (dma_memory_read(xhci->as, addr, buf, len, in xhci_dma_read_u32s()
524 if (dma_memory_write(xhci->as, addr, tmp, len, in xhci_dma_write_u32s()
537 if (!uport->dev) { in xhci_lookup_port()
540 switch (uport->dev->speed) { in xhci_lookup_port()
544 index = uport->index + xhci->numports_3; in xhci_lookup_port()
547 index = uport->index; in xhci_lookup_port()
552 return &xhci->ports[index]; in xhci_lookup_port()
560 if (xhci->intr[0].iman & IMAN_IP && in xhci_intr_update()
561 xhci->intr[0].iman & IMAN_IE && in xhci_intr_update()
562 xhci->usbcmd & USBCMD_INTE) { in xhci_intr_update()
565 if (xhci->intr_raise) { in xhci_intr_update()
566 if (xhci->intr_raise(xhci, 0, level)) { in xhci_intr_update()
567 xhci->intr[0].iman &= ~IMAN_IP; in xhci_intr_update()
571 if (xhci->intr_update) { in xhci_intr_update()
572 xhci->intr_update(xhci, v, in xhci_intr_update()
573 xhci->intr[v].iman & IMAN_IE); in xhci_intr_update()
579 bool pending = (xhci->intr[v].erdp_low & ERDP_EHB); in xhci_intr_raise()
581 xhci->intr[v].erdp_low |= ERDP_EHB; in xhci_intr_raise()
582 xhci->intr[v].iman |= IMAN_IP; in xhci_intr_raise()
583 xhci->usbsts |= USBSTS_EINT; in xhci_intr_raise()
588 if (!(xhci->intr[v].iman & IMAN_IE)) { in xhci_intr_raise()
592 if (!(xhci->usbcmd & USBCMD_INTE)) { in xhci_intr_raise()
595 if (xhci->intr_raise) { in xhci_intr_raise()
596 if (xhci->intr_raise(xhci, v, true)) { in xhci_intr_raise()
597 xhci->intr[v].iman &= ~IMAN_IP; in xhci_intr_raise()
604 return !(xhci->usbsts & USBSTS_HCH); in xhci_running()
609 XHCIInterrupter *intr = &xhci->intr[v]; in xhci_write_event()
613 ev_trb.parameter = cpu_to_le64(event->ptr); in xhci_write_event()
614 ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24)); in xhci_write_event()
615 ev_trb.control = (event->slotid << 24) | (event->epid << 16) | in xhci_write_event()
616 event->flags | (event->type << TRB_TYPE_SHIFT); in xhci_write_event()
617 if (intr->er_pcs) { in xhci_write_event()
622 trace_usb_xhci_queue_event(v, intr->er_ep_idx, trb_name(&ev_trb), in xhci_write_event()
626 addr = intr->er_start + TRB_SIZE*intr->er_ep_idx; in xhci_write_event()
627 if (dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, in xhci_write_event()
634 intr->er_ep_idx++; in xhci_write_event()
635 if (intr->er_ep_idx >= intr->er_size) { in xhci_write_event()
636 intr->er_ep_idx = 0; in xhci_write_event()
637 intr->er_pcs = !intr->er_pcs; in xhci_write_event()
647 if (xhci->numintrs == 1 || in xhci_event()
648 (xhci->intr_mapping_supported && !xhci->intr_mapping_supported(xhci))) { in xhci_event()
652 if (v >= xhci->numintrs) { in xhci_event()
653 DPRINTF("intr nr out of range (%d >= %d)\n", v, xhci->numintrs); in xhci_event()
656 intr = &xhci->intr[v]; in xhci_event()
658 erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); in xhci_event()
659 if (erdp < intr->er_start || in xhci_event()
660 erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) { in xhci_event()
663 v, intr->er_start, intr->er_size); in xhci_event()
668 dp_idx = (erdp - intr->er_start) / TRB_SIZE; in xhci_event()
669 assert(dp_idx < intr->er_size); in xhci_event()
671 if ((intr->er_ep_idx + 2) % intr->er_size == dp_idx) { in xhci_event()
675 } else if ((intr->er_ep_idx + 1) % intr->er_size == dp_idx) { in xhci_event()
687 ring->dequeue = base; in xhci_ring_init()
688 ring->ccs = 1; in xhci_ring_init()
698 if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE, in xhci_ring_fetch()
704 trb->addr = ring->dequeue; in xhci_ring_fetch()
705 trb->ccs = ring->ccs; in xhci_ring_fetch()
706 le64_to_cpus(&trb->parameter); in xhci_ring_fetch()
707 le32_to_cpus(&trb->status); in xhci_ring_fetch()
708 le32_to_cpus(&trb->control); in xhci_ring_fetch()
710 trace_usb_xhci_fetch_trb(ring->dequeue, trb_name(trb), in xhci_ring_fetch()
711 trb->parameter, trb->status, trb->control); in xhci_ring_fetch()
713 if ((trb->control & TRB_C) != ring->ccs) { in xhci_ring_fetch()
721 *addr = ring->dequeue; in xhci_ring_fetch()
723 ring->dequeue += TRB_SIZE; in xhci_ring_fetch()
727 trace_usb_xhci_enforced_limit("trb-link"); in xhci_ring_fetch()
730 ring->dequeue = xhci_mask64(trb->parameter); in xhci_ring_fetch()
731 if (trb->control & TRB_LK_TC) { in xhci_ring_fetch()
732 ring->ccs = !ring->ccs; in xhci_ring_fetch()
742 dma_addr_t dequeue = ring->dequeue; in xhci_ring_chain_length()
743 bool ccs = ring->ccs; in xhci_ring_chain_length()
744 /* hack to bundle together the two/three TDs that make a setup transfer */ in xhci_ring_chain_length()
750 if (dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, in xhci_ring_chain_length()
754 return -1; in xhci_ring_chain_length()
761 return -length; in xhci_ring_chain_length()
768 return -length; in xhci_ring_chain_length()
799 return -1; in xhci_ring_chain_length()
804 XHCIInterrupter *intr = &xhci->intr[v]; in xhci_er_reset()
806 dma_addr_t erstba = xhci_addr64(intr->erstba_low, intr->erstba_high); in xhci_er_reset()
808 if (intr->erstsz == 0 || erstba == 0) { in xhci_er_reset()
810 intr->er_start = 0; in xhci_er_reset()
811 intr->er_size = 0; in xhci_er_reset()
815 if (intr->erstsz != 1) { in xhci_er_reset()
816 DPRINTF("xhci: invalid value for ERSTSZ: %d\n", intr->erstsz); in xhci_er_reset()
820 if (dma_memory_read(xhci->as, erstba, &seg, sizeof(seg), in xhci_er_reset()
836 intr->er_start = xhci_addr64(seg.addr_low, seg.addr_high); in xhci_er_reset()
837 intr->er_size = seg.size; in xhci_er_reset()
839 intr->er_ep_idx = 0; in xhci_er_reset()
840 intr->er_pcs = 1; in xhci_er_reset()
843 v, intr->er_start, intr->er_size); in xhci_er_reset()
849 xhci->usbsts &= ~USBSTS_HCH; in xhci_run()
850 xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); in xhci_run()
856 xhci->usbsts |= USBSTS_HCH; in xhci_stop()
857 xhci->crcr_low &= ~CRCR_CRR; in xhci_stop()
869 stctx[i].sct = -1; in xhci_alloc_stream_contexts()
878 for (i = 0; i < epctx->nr_pstreams; i++) { in xhci_reset_streams()
879 epctx->pstreams[i].sct = -1; in xhci_reset_streams()
885 assert(epctx->pstreams == NULL); in xhci_alloc_streams()
886 epctx->nr_pstreams = 2 << epctx->max_pstreams; in xhci_alloc_streams()
887 epctx->pstreams = xhci_alloc_stream_contexts(epctx->nr_pstreams, base); in xhci_alloc_streams()
892 assert(epctx->pstreams != NULL); in xhci_free_streams()
894 g_free(epctx->pstreams); in xhci_free_streams()
895 epctx->pstreams = NULL; in xhci_free_streams()
896 epctx->nr_pstreams = 0; in xhci_free_streams()
910 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_epmask_to_eps_with_streams()
912 slot = &xhci->slots[slotid - 1]; in xhci_epmask_to_eps_with_streams()
919 epctx = slot->eps[i - 1]; in xhci_epmask_to_eps_with_streams()
921 if (!epctx || !epctx->nr_pstreams || !ep) { in xhci_epmask_to_eps_with_streams()
941 usb_device_free_streams(eps[0]->dev, eps, nr_eps); in xhci_free_device_streams()
958 req_nr_streams = epctxs[0]->nr_pstreams; in xhci_alloc_device_streams()
959 dev_max_streams = eps[0]->max_streams; in xhci_alloc_device_streams()
967 if (epctxs[i]->nr_pstreams != req_nr_streams) { in xhci_alloc_device_streams()
971 if (eps[i]->max_streams != dev_max_streams) { in xhci_alloc_device_streams()
978 * max-streams in both the device descriptor and in the controller is a in xhci_alloc_device_streams()
995 r = usb_device_alloc_streams(eps[0]->dev, eps, nr_eps, req_nr_streams); in xhci_alloc_device_streams()
1013 if (epctx->lsa) { in xhci_find_stream()
1014 if (streamid >= epctx->nr_pstreams) { in xhci_find_stream()
1018 sctx = epctx->pstreams + streamid; in xhci_find_stream()
1025 if (sctx->sct == -1) { in xhci_find_stream()
1026 xhci_dma_read_u32s(epctx->xhci, sctx->pctx, ctx, sizeof(ctx)); in xhci_find_stream()
1028 if (epctx->lsa && sct != 1) { in xhci_find_stream()
1032 sctx->sct = sct; in xhci_find_stream()
1034 xhci_ring_init(epctx->xhci, &sctx->ring, base); in xhci_find_stream()
1046 xhci_dma_read_u32s(xhci, epctx->pctx, ctx, sizeof(ctx)); in xhci_set_ep_state()
1051 if (epctx->nr_pstreams) { in xhci_set_ep_state()
1053 ring = &sctx->ring; in xhci_set_ep_state()
1054 xhci_dma_read_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2)); in xhci_set_ep_state()
1056 ctx2[0] |= sctx->ring.dequeue | sctx->ring.ccs; in xhci_set_ep_state()
1057 ctx2[1] = (sctx->ring.dequeue >> 16) >> 16; in xhci_set_ep_state()
1058 xhci_dma_write_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2)); in xhci_set_ep_state()
1061 ring = &epctx->ring; in xhci_set_ep_state()
1064 ctx[2] = ring->dequeue | ring->ccs; in xhci_set_ep_state()
1065 ctx[3] = (ring->dequeue >> 16) >> 16; in xhci_set_ep_state()
1068 epctx->pctx, state, ctx[3], ctx[2]); in xhci_set_ep_state()
1071 xhci_dma_write_u32s(xhci, epctx->pctx, ctx, sizeof(ctx)); in xhci_set_ep_state()
1072 if (epctx->state != state) { in xhci_set_ep_state()
1073 trace_usb_xhci_ep_state(epctx->slotid, epctx->epid, in xhci_set_ep_state()
1074 ep_state_name(epctx->state), in xhci_set_ep_state()
1077 epctx->state = state; in xhci_set_ep_state()
1093 epctx->xhci = xhci; in xhci_alloc_epctx()
1094 epctx->slotid = slotid; in xhci_alloc_epctx()
1095 epctx->epid = epid; in xhci_alloc_epctx()
1097 QTAILQ_INIT(&epctx->transfers); in xhci_alloc_epctx()
1098 epctx->kick_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_ep_kick_timer, epctx); in xhci_alloc_epctx()
1110 epctx->type = (ctx[1] >> EP_TYPE_SHIFT) & EP_TYPE_MASK; in xhci_init_epctx()
1111 epctx->pctx = pctx; in xhci_init_epctx()
1112 epctx->max_psize = ctx[1]>>16; in xhci_init_epctx()
1113 epctx->max_psize *= 1+((ctx[1]>>8)&0xff); in xhci_init_epctx()
1114 epctx->max_pstreams = (ctx[0] >> 10) & epctx->xhci->max_pstreams_mask; in xhci_init_epctx()
1115 epctx->lsa = (ctx[0] >> 15) & 1; in xhci_init_epctx()
1116 if (epctx->max_pstreams) { in xhci_init_epctx()
1119 xhci_ring_init(epctx->xhci, &epctx->ring, dequeue); in xhci_init_epctx()
1120 epctx->ring.ccs = ctx[2] & 1; in xhci_init_epctx()
1123 epctx->interval = 1 << ((ctx[0] >> 16) & 0xff); in xhci_init_epctx()
1134 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_enable_ep()
1137 slot = &xhci->slots[slotid-1]; in xhci_enable_ep()
1138 if (slot->eps[epid-1]) { in xhci_enable_ep()
1143 slot->eps[epid-1] = epctx; in xhci_enable_ep()
1147 "size is %d\n", epid/2, epid%2, epctx->type, epctx->max_psize); in xhci_enable_ep()
1149 epctx->mfindex_last = 0; in xhci_enable_ep()
1151 epctx->state = EP_RUNNING; in xhci_enable_ep()
1161 uint32_t limit = epctx->nr_pstreams + 16; in xhci_ep_alloc_xfer()
1164 if (epctx->xfer_count >= limit) { in xhci_ep_alloc_xfer()
1169 xfer->epctx = epctx; in xhci_ep_alloc_xfer()
1170 xfer->trbs = g_new(XHCITRB, length); in xhci_ep_alloc_xfer()
1171 xfer->trb_count = length; in xhci_ep_alloc_xfer()
1172 usb_packet_init(&xfer->packet); in xhci_ep_alloc_xfer()
1174 QTAILQ_INSERT_TAIL(&epctx->transfers, xfer, next); in xhci_ep_alloc_xfer()
1175 epctx->xfer_count++; in xhci_ep_alloc_xfer()
1182 QTAILQ_REMOVE(&xfer->epctx->transfers, xfer, next); in xhci_ep_free_xfer()
1183 xfer->epctx->xfer_count--; in xhci_ep_free_xfer()
1185 usb_packet_cleanup(&xfer->packet); in xhci_ep_free_xfer()
1186 g_free(xfer->trbs); in xhci_ep_free_xfer()
1192 usb_packet_unmap(&xfer->packet, &xfer->sgl); in xhci_xfer_unmap()
1193 qemu_sglist_destroy(&xfer->sgl); in xhci_xfer_unmap()
1200 if (report && (t->running_async || t->running_retry)) { in xhci_ep_nuke_one_xfer()
1201 t->status = report; in xhci_ep_nuke_one_xfer()
1205 if (t->running_async) { in xhci_ep_nuke_one_xfer()
1206 usb_cancel_packet(&t->packet); in xhci_ep_nuke_one_xfer()
1208 t->running_async = 0; in xhci_ep_nuke_one_xfer()
1211 if (t->running_retry) { in xhci_ep_nuke_one_xfer()
1212 if (t->epctx) { in xhci_ep_nuke_one_xfer()
1213 t->epctx->retry = NULL; in xhci_ep_nuke_one_xfer()
1214 timer_del(t->epctx->kick_timer); in xhci_ep_nuke_one_xfer()
1216 t->running_retry = 0; in xhci_ep_nuke_one_xfer()
1219 g_free(t->trbs); in xhci_ep_nuke_one_xfer()
1221 t->trbs = NULL; in xhci_ep_nuke_one_xfer()
1222 t->trb_count = 0; in xhci_ep_nuke_one_xfer()
1235 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_ep_nuke_xfers()
1240 slot = &xhci->slots[slotid-1]; in xhci_ep_nuke_xfers()
1242 if (!slot->eps[epid-1]) { in xhci_ep_nuke_xfers()
1246 epctx = slot->eps[epid-1]; in xhci_ep_nuke_xfers()
1249 xfer = QTAILQ_FIRST(&epctx->transfers); in xhci_ep_nuke_xfers()
1262 usb_device_ep_stopped(ep->dev, ep); in xhci_ep_nuke_xfers()
1274 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_disable_ep()
1277 slot = &xhci->slots[slotid-1]; in xhci_disable_ep()
1279 if (!slot->eps[epid-1]) { in xhci_disable_ep()
1286 epctx = slot->eps[epid-1]; in xhci_disable_ep()
1288 if (epctx->nr_pstreams) { in xhci_disable_ep()
1293 if (xhci->dcbaap_low || xhci->dcbaap_high) { in xhci_disable_ep()
1297 timer_free(epctx->kick_timer); in xhci_disable_ep()
1299 slot->eps[epid-1] = NULL; in xhci_disable_ep()
1311 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_stop_ep()
1318 slot = &xhci->slots[slotid-1]; in xhci_stop_ep()
1320 if (!slot->eps[epid-1]) { in xhci_stop_ep()
1330 epctx = slot->eps[epid-1]; in xhci_stop_ep()
1334 if (epctx->nr_pstreams) { in xhci_stop_ep()
1348 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_reset_ep()
1355 slot = &xhci->slots[slotid-1]; in xhci_reset_ep()
1357 if (!slot->eps[epid-1]) { in xhci_reset_ep()
1362 epctx = slot->eps[epid-1]; in xhci_reset_ep()
1364 if (epctx->state != EP_HALTED) { in xhci_reset_ep()
1366 epid, epctx->state); in xhci_reset_ep()
1375 if (!xhci->slots[slotid-1].uport || in xhci_reset_ep()
1376 !xhci->slots[slotid-1].uport->dev || in xhci_reset_ep()
1377 !xhci->slots[slotid-1].uport->dev->attached) { in xhci_reset_ep()
1383 if (epctx->nr_pstreams) { in xhci_reset_ep()
1399 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_set_ep_dequeue()
1409 slot = &xhci->slots[slotid-1]; in xhci_set_ep_dequeue()
1411 if (!slot->eps[epid-1]) { in xhci_set_ep_dequeue()
1416 epctx = slot->eps[epid-1]; in xhci_set_ep_dequeue()
1418 if (epctx->state != EP_STOPPED) { in xhci_set_ep_dequeue()
1423 if (epctx->nr_pstreams) { in xhci_set_ep_dequeue()
1429 xhci_ring_init(xhci, &sctx->ring, dequeue & ~0xf); in xhci_set_ep_dequeue()
1430 sctx->ring.ccs = dequeue & 1; in xhci_set_ep_dequeue()
1433 xhci_ring_init(xhci, &epctx->ring, dequeue & ~0xF); in xhci_set_ep_dequeue()
1434 epctx->ring.ccs = dequeue & 1; in xhci_set_ep_dequeue()
1444 XHCIState *xhci = xfer->epctx->xhci; in xhci_xfer_create_sgl()
1447 xfer->int_req = false; in xhci_xfer_create_sgl()
1448 qemu_sglist_init(&xfer->sgl, DEVICE(xhci), xfer->trb_count, xhci->as); in xhci_xfer_create_sgl()
1449 for (i = 0; i < xfer->trb_count; i++) { in xhci_xfer_create_sgl()
1450 XHCITRB *trb = &xfer->trbs[i]; in xhci_xfer_create_sgl()
1454 if (trb->control & TRB_TR_IOC) { in xhci_xfer_create_sgl()
1455 xfer->int_req = true; in xhci_xfer_create_sgl()
1460 if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) { in xhci_xfer_create_sgl()
1467 addr = xhci_mask64(trb->parameter); in xhci_xfer_create_sgl()
1468 chunk = trb->status & 0x1ffff; in xhci_xfer_create_sgl()
1469 if (trb->control & TRB_TR_IDT) { in xhci_xfer_create_sgl()
1474 qemu_sglist_add(&xfer->sgl, trb->addr, chunk); in xhci_xfer_create_sgl()
1476 qemu_sglist_add(&xfer->sgl, addr, chunk); in xhci_xfer_create_sgl()
1485 qemu_sglist_destroy(&xfer->sgl); in xhci_xfer_create_sgl()
1487 return -1; in xhci_xfer_create_sgl()
1497 XHCIState *xhci = xfer->epctx->xhci; in xhci_xfer_report()
1500 left = xfer->packet.actual_length; in xhci_xfer_report()
1502 for (i = 0; i < xfer->trb_count; i++) { in xhci_xfer_report()
1503 XHCITRB *trb = &xfer->trbs[i]; in xhci_xfer_report()
1508 chunk = trb->status & 0x1ffff; in xhci_xfer_report()
1516 chunk = trb->status & 0x1ffff; in xhci_xfer_report()
1519 if (xfer->status == CC_SUCCESS) { in xhci_xfer_report()
1523 left -= chunk; in xhci_xfer_report()
1532 if (!reported && ((trb->control & TRB_TR_IOC) || in xhci_xfer_report()
1533 (shortpkt && (trb->control & TRB_TR_ISP)) || in xhci_xfer_report()
1534 (xfer->status != CC_SUCCESS && left == 0))) { in xhci_xfer_report()
1535 event.slotid = xfer->epctx->slotid; in xhci_xfer_report()
1536 event.epid = xfer->epctx->epid; in xhci_xfer_report()
1537 event.length = (trb->status & 0x1ffff) - chunk; in xhci_xfer_report()
1539 event.ptr = trb->addr; in xhci_xfer_report()
1540 if (xfer->status == CC_SUCCESS) { in xhci_xfer_report()
1543 event.ccode = xfer->status; in xhci_xfer_report()
1546 event.ptr = trb->parameter; in xhci_xfer_report()
1554 if (xfer->status != CC_SUCCESS) { in xhci_xfer_report()
1571 XHCIEPContext *epctx = xfer->epctx; in xhci_stall_ep()
1572 XHCIState *xhci = epctx->xhci; in xhci_stall_ep()
1576 if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) { in xhci_stall_ep()
1581 if (epctx->nr_pstreams) { in xhci_stall_ep()
1582 sctx = xhci_find_stream(epctx, xfer->streamid, &err); in xhci_stall_ep()
1586 sctx->ring.dequeue = xfer->trbs[0].addr; in xhci_stall_ep()
1587 sctx->ring.ccs = xfer->trbs[0].ccs; in xhci_stall_ep()
1590 epctx->ring.dequeue = xfer->trbs[0].addr; in xhci_stall_ep()
1591 epctx->ring.ccs = xfer->trbs[0].ccs; in xhci_stall_ep()
1601 dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; in xhci_setup_packet()
1603 if (xfer->packet.ep) { in xhci_setup_packet()
1604 ep = xfer->packet.ep; in xhci_setup_packet()
1606 ep = xhci_epid_to_usbep(xfer->epctx); in xhci_setup_packet()
1609 xfer->epctx->slotid); in xhci_setup_packet()
1610 return -1; in xhci_setup_packet()
1615 usb_packet_setup(&xfer->packet, dir, ep, xfer->streamid, in xhci_setup_packet()
1616 xfer->trbs[0].addr, false, xfer->int_req); in xhci_setup_packet()
1617 if (usb_packet_map(&xfer->packet, &xfer->sgl)) { in xhci_setup_packet()
1618 qemu_sglist_destroy(&xfer->sgl); in xhci_setup_packet()
1619 return -1; in xhci_setup_packet()
1622 xfer->packet.pid, ep->dev->addr, ep->nr); in xhci_setup_packet()
1628 if (xfer->packet.status == USB_RET_ASYNC) { in xhci_try_complete_packet()
1630 xfer->running_async = 1; in xhci_try_complete_packet()
1631 xfer->running_retry = 0; in xhci_try_complete_packet()
1632 xfer->complete = 0; in xhci_try_complete_packet()
1634 } else if (xfer->packet.status == USB_RET_NAK) { in xhci_try_complete_packet()
1636 xfer->running_async = 0; in xhci_try_complete_packet()
1637 xfer->running_retry = 1; in xhci_try_complete_packet()
1638 xfer->complete = 0; in xhci_try_complete_packet()
1641 xfer->running_async = 0; in xhci_try_complete_packet()
1642 xfer->running_retry = 0; in xhci_try_complete_packet()
1643 xfer->complete = 1; in xhci_try_complete_packet()
1647 if (xfer->packet.status == USB_RET_SUCCESS) { in xhci_try_complete_packet()
1648 trace_usb_xhci_xfer_success(xfer, xfer->packet.actual_length); in xhci_try_complete_packet()
1649 xfer->status = CC_SUCCESS; in xhci_try_complete_packet()
1655 trace_usb_xhci_xfer_error(xfer, xfer->packet.status); in xhci_try_complete_packet()
1656 switch (xfer->packet.status) { in xhci_try_complete_packet()
1659 xfer->status = CC_USB_TRANSACTION_ERROR; in xhci_try_complete_packet()
1664 xfer->status = CC_STALL_ERROR; in xhci_try_complete_packet()
1669 xfer->status = CC_BABBLE_DETECTED; in xhci_try_complete_packet()
1675 xfer->packet.status); in xhci_try_complete_packet()
1686 trb_setup = &xfer->trbs[0]; in xhci_fire_ctl_transfer()
1687 trb_status = &xfer->trbs[xfer->trb_count-1]; in xhci_fire_ctl_transfer()
1689 trace_usb_xhci_xfer_start(xfer, xfer->epctx->slotid, in xhci_fire_ctl_transfer()
1690 xfer->epctx->epid, xfer->streamid); in xhci_fire_ctl_transfer()
1693 if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) { in xhci_fire_ctl_transfer()
1694 trb_status--; in xhci_fire_ctl_transfer()
1701 return -1; in xhci_fire_ctl_transfer()
1706 return -1; in xhci_fire_ctl_transfer()
1708 if (!(trb_setup->control & TRB_TR_IDT)) { in xhci_fire_ctl_transfer()
1710 return -1; in xhci_fire_ctl_transfer()
1712 if ((trb_setup->status & 0x1ffff) != 8) { in xhci_fire_ctl_transfer()
1714 (trb_setup->status & 0x1ffff)); in xhci_fire_ctl_transfer()
1715 return -1; in xhci_fire_ctl_transfer()
1718 bmRequestType = trb_setup->parameter; in xhci_fire_ctl_transfer()
1720 xfer->in_xfer = bmRequestType & USB_DIR_IN; in xhci_fire_ctl_transfer()
1721 xfer->iso_xfer = false; in xhci_fire_ctl_transfer()
1722 xfer->timed_xfer = false; in xhci_fire_ctl_transfer()
1725 return -1; in xhci_fire_ctl_transfer()
1727 xfer->packet.parameter = trb_setup->parameter; in xhci_fire_ctl_transfer()
1729 usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); in xhci_fire_ctl_transfer()
1737 uint64_t asap = ((mfindex + epctx->interval - 1) & in xhci_calc_intr_kick()
1738 ~(epctx->interval-1)); in xhci_calc_intr_kick()
1739 uint64_t kick = epctx->mfindex_last + epctx->interval; in xhci_calc_intr_kick()
1741 assert(epctx->interval != 0); in xhci_calc_intr_kick()
1742 xfer->mfindex_kick = MAX(asap, kick); in xhci_calc_intr_kick()
1748 if (xfer->trbs[0].control & TRB_TR_SIA) { in xhci_calc_iso_kick()
1749 uint64_t asap = ((mfindex + epctx->interval - 1) & in xhci_calc_iso_kick()
1750 ~(epctx->interval-1)); in xhci_calc_iso_kick()
1751 if (asap >= epctx->mfindex_last && in xhci_calc_iso_kick()
1752 asap <= epctx->mfindex_last + epctx->interval * 4) { in xhci_calc_iso_kick()
1753 xfer->mfindex_kick = epctx->mfindex_last + epctx->interval; in xhci_calc_iso_kick()
1755 xfer->mfindex_kick = asap; in xhci_calc_iso_kick()
1758 xfer->mfindex_kick = ((xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT) in xhci_calc_iso_kick()
1760 xfer->mfindex_kick |= mfindex & ~0x3fff; in xhci_calc_iso_kick()
1761 if (xfer->mfindex_kick + 0x100 < mfindex) { in xhci_calc_iso_kick()
1762 xfer->mfindex_kick += 0x4000; in xhci_calc_iso_kick()
1770 if (xfer->mfindex_kick > mfindex) { in xhci_check_intr_iso_kick()
1771 timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + in xhci_check_intr_iso_kick()
1772 (xfer->mfindex_kick - mfindex) * 125000); in xhci_check_intr_iso_kick()
1773 xfer->running_retry = 1; in xhci_check_intr_iso_kick()
1775 epctx->mfindex_last = xfer->mfindex_kick; in xhci_check_intr_iso_kick()
1776 timer_del(epctx->kick_timer); in xhci_check_intr_iso_kick()
1777 xfer->running_retry = 0; in xhci_check_intr_iso_kick()
1786 DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", epctx->slotid, epctx->epid); in xhci_submit()
1788 xfer->in_xfer = epctx->type>>2; in xhci_submit()
1790 switch(epctx->type) { in xhci_submit()
1793 xfer->pkts = 0; in xhci_submit()
1794 xfer->iso_xfer = false; in xhci_submit()
1795 xfer->timed_xfer = true; in xhci_submit()
1799 if (xfer->running_retry) { in xhci_submit()
1800 return -1; in xhci_submit()
1805 xfer->pkts = 0; in xhci_submit()
1806 xfer->iso_xfer = false; in xhci_submit()
1807 xfer->timed_xfer = false; in xhci_submit()
1811 xfer->pkts = 1; in xhci_submit()
1812 xfer->iso_xfer = true; in xhci_submit()
1813 xfer->timed_xfer = true; in xhci_submit()
1817 if (xfer->running_retry) { in xhci_submit()
1818 return -1; in xhci_submit()
1822 trace_usb_xhci_unimplemented("endpoint type", epctx->type); in xhci_submit()
1823 return -1; in xhci_submit()
1827 return -1; in xhci_submit()
1829 usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); in xhci_submit()
1836 trace_usb_xhci_xfer_start(xfer, xfer->epctx->slotid, in xhci_fire_transfer()
1837 xfer->epctx->epid, xfer->streamid); in xhci_fire_transfer()
1846 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_kick_ep()
1849 if (!xhci->slots[slotid-1].enabled) { in xhci_kick_ep()
1853 epctx = xhci->slots[slotid-1].eps[epid-1]; in xhci_kick_ep()
1860 if (epctx->kick_active) { in xhci_kick_ep()
1868 return (xhci->slots[slotid - 1].uport && in xhci_slot_ok()
1869 xhci->slots[slotid - 1].uport->dev && in xhci_slot_ok()
1870 xhci->slots[slotid - 1].uport->dev->attached); in xhci_slot_ok()
1875 XHCIState *xhci = epctx->xhci; in xhci_kick_epctx()
1885 trace_usb_xhci_ep_kick(epctx->slotid, epctx->epid, streamid); in xhci_kick_epctx()
1886 assert(!epctx->kick_active); in xhci_kick_epctx()
1890 if (!xhci_slot_ok(xhci, epctx->slotid)) { in xhci_kick_epctx()
1894 if (epctx->retry) { in xhci_kick_epctx()
1895 xfer = epctx->retry; in xhci_kick_epctx()
1898 assert(xfer->running_retry); in xhci_kick_epctx()
1899 if (xfer->timed_xfer) { in xhci_kick_epctx()
1903 if (xfer->running_retry) { in xhci_kick_epctx()
1906 xfer->timed_xfer = 0; in xhci_kick_epctx()
1907 xfer->running_retry = 1; in xhci_kick_epctx()
1909 if (xfer->iso_xfer) { in xhci_kick_epctx()
1914 usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); in xhci_kick_epctx()
1915 assert(xfer->packet.status != USB_RET_NAK); in xhci_kick_epctx()
1922 usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); in xhci_kick_epctx()
1923 if (xfer->packet.status == USB_RET_NAK) { in xhci_kick_epctx()
1929 assert(!xfer->running_retry); in xhci_kick_epctx()
1930 if (xfer->complete) { in xhci_kick_epctx()
1932 xhci_set_ep_state(xhci, epctx, stctx, epctx->state); in xhci_kick_epctx()
1933 xhci_ep_free_xfer(epctx->retry); in xhci_kick_epctx()
1935 epctx->retry = NULL; in xhci_kick_epctx()
1938 if (epctx->state == EP_HALTED) { in xhci_kick_epctx()
1944 if (epctx->nr_pstreams) { in xhci_kick_epctx()
1950 ring = &stctx->ring; in xhci_kick_epctx()
1953 ring = &epctx->ring; in xhci_kick_epctx()
1957 if (!ring->dequeue) { in xhci_kick_epctx()
1961 epctx->kick_active++; in xhci_kick_epctx()
1965 if (epctx->type == ET_ISO_OUT || epctx->type == ET_ISO_IN) { in xhci_kick_epctx()
1968 ev.ccode = epctx->type == ET_ISO_IN ? in xhci_kick_epctx()
1970 ev.slotid = epctx->slotid; in xhci_kick_epctx()
1971 ev.epid = epctx->epid; in xhci_kick_epctx()
1972 ev.ptr = epctx->ring.dequeue; in xhci_kick_epctx()
1973 xhci_event(xhci, &ev, xhci->slots[epctx->slotid-1].intr); in xhci_kick_epctx()
1984 type = xhci_ring_fetch(xhci, ring, &xfer->trbs[i], NULL); in xhci_kick_epctx()
1988 epctx->kick_active--; in xhci_kick_epctx()
1992 xfer->streamid = streamid; in xhci_kick_epctx()
1994 if (epctx->epid == 1) { in xhci_kick_epctx()
1999 if (!xhci_slot_ok(xhci, epctx->slotid)) { in xhci_kick_epctx()
2000 /* surprise removal -> stop processing */ in xhci_kick_epctx()
2003 if (xfer->complete) { in xhci_kick_epctx()
2005 xhci_set_ep_state(xhci, epctx, stctx, epctx->state); in xhci_kick_epctx()
2010 if (epctx->state == EP_HALTED) { in xhci_kick_epctx()
2013 if (xfer != NULL && xfer->running_retry) { in xhci_kick_epctx()
2015 epctx->retry = xfer; in xhci_kick_epctx()
2024 epctx->kick_active--; in xhci_kick_epctx()
2028 usb_device_flush_ep_queue(ep->dev, ep); in xhci_kick_epctx()
2035 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_enable_slot()
2036 xhci->slots[slotid-1].enabled = 1; in xhci_enable_slot()
2037 xhci->slots[slotid-1].uport = NULL; in xhci_enable_slot()
2038 memset(xhci->slots[slotid-1].eps, 0, sizeof(XHCIEPContext*)*31); in xhci_enable_slot()
2048 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_disable_slot()
2051 if (xhci->slots[slotid-1].eps[i-1]) { in xhci_disable_slot()
2056 xhci->slots[slotid-1].enabled = 0; in xhci_disable_slot()
2057 xhci->slots[slotid-1].addressed = 0; in xhci_disable_slot()
2058 xhci->slots[slotid-1].uport = NULL; in xhci_disable_slot()
2059 xhci->slots[slotid-1].intr = 0; in xhci_disable_slot()
2070 if (port < 1 || port > xhci->numports) { in xhci_lookup_uport()
2073 port = xhci->ports[port-1].uport->index+1; in xhci_lookup_uport()
2080 pos += snprintf(path + pos, sizeof(path) - pos, ".%d", port); in xhci_lookup_uport()
2083 QTAILQ_FOREACH(uport, &xhci->bus.used, next) { in xhci_lookup_uport()
2084 if (strcmp(uport->path, path) == 0) { in xhci_lookup_uport()
2105 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_address_slot()
2107 dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); in xhci_address_slot()
2108 ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &poctx, MEMTXATTRS_UNSPECIFIED); in xhci_address_slot()
2137 trace_usb_xhci_slot_address(slotid, uport->path); in xhci_address_slot()
2139 dev = uport->dev; in xhci_address_slot()
2140 if (!dev || !dev->attached) { in xhci_address_slot()
2141 DPRINTF("xhci: port %s not connected\n", uport->path); in xhci_address_slot()
2145 for (i = 0; i < xhci->numslots; i++) { in xhci_address_slot()
2146 if (i == slotid-1) { in xhci_address_slot()
2149 if (xhci->slots[i].uport == uport) { in xhci_address_slot()
2151 uport->path, i+1); in xhci_address_slot()
2156 slot = &xhci->slots[slotid-1]; in xhci_address_slot()
2157 slot->uport = uport; in xhci_address_slot()
2158 slot->ctx = octx; in xhci_address_slot()
2159 slot->intr = get_field(slot_ctx[2], TRB_INTR); in xhci_address_slot()
2192 xhci->slots[slotid-1].addressed = 1; in xhci_address_slot()
2209 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_configure_slot()
2212 octx = xhci->slots[slotid-1].ctx; in xhci_configure_slot()
2219 if (xhci->slots[slotid-1].eps[i-1]) { in xhci_configure_slot()
2308 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_evaluate_slot()
2311 octx = xhci->slots[slotid-1].ctx; in xhci_evaluate_slot()
2335 xhci->slots[slotid-1].intr = get_field(islot_ctx[2], TRB_INTR); in xhci_evaluate_slot()
2336 set_field(&slot_ctx[2], xhci->slots[slotid-1].intr, TRB_INTR); in xhci_evaluate_slot()
2372 assert(slotid >= 1 && slotid <= xhci->numslots); in xhci_reset_slot()
2374 octx = xhci->slots[slotid-1].ctx; in xhci_reset_slot()
2379 if (xhci->slots[slotid-1].eps[i-1]) { in xhci_reset_slot()
2397 slotid = (trb->control >> TRB_CR_SLOTID_SHIFT) & TRB_CR_SLOTID_MASK; in xhci_get_slot()
2398 if (slotid < 1 || slotid > xhci->numslots) { in xhci_get_slot()
2400 event->ccode = CC_TRB_ERROR; in xhci_get_slot()
2402 } else if (!xhci->slots[slotid-1].enabled) { in xhci_get_slot()
2404 event->ccode = CC_SLOT_NOT_ENABLED_ERROR; in xhci_get_slot()
2415 for (slot = 0; slot < xhci->numslots; slot++) { in xhci_detach_slot()
2416 if (xhci->slots[slot].uport == uport) { in xhci_detach_slot()
2420 if (slot == xhci->numslots) { in xhci_detach_slot()
2425 if (xhci->slots[slot].eps[ep]) { in xhci_detach_slot()
2429 xhci->slots[slot].uport = NULL; in xhci_detach_slot()
2443 if (stb_dma(xhci->as, ctx, 0, MEMTXATTRS_UNSPECIFIED) != MEMTX_OK || in xhci_get_port_bandwidth()
2444 dma_memory_set(xhci->as, ctx + 1, 80, xhci->numports, in xhci_get_port_bandwidth()
2457 return (v << count) | (v >> (32 - count)); in rotl()
2464 val = rotl(lo - 0x49434878, 32 - ((hi>>8) & 0x1F)); in xhci_nec_challenge()
2466 val -= rotl(hi ^ 0x49434878, (lo >> 16) & 0x1F); in xhci_nec_challenge()
2484 xhci->crcr_low |= CRCR_CRR; in xhci_process_commands()
2486 while ((type = xhci_ring_fetch(xhci, &xhci->cmd_ring, &trb, &addr))) { in xhci_process_commands()
2490 for (i = 0; i < xhci->numslots; i++) { in xhci_process_commands()
2491 if (!xhci->slots[i].enabled) { in xhci_process_commands()
2495 if (i >= xhci->numslots) { in xhci_process_commands()
2569 if (xhci->nec_quirks) { in xhci_process_commands()
2577 if (xhci->nec_quirks) { in xhci_process_commands()
2606 if (!port->uport->dev || !port->uport->dev->attached) { in xhci_port_have_device()
2609 if (!((1 << port->uport->dev->speed) & port->speedmask)) { in xhci_port_have_device()
2618 port->portnr << 24 }; in xhci_port_notify()
2620 if ((port->portsc & bits) == bits) { in xhci_port_notify()
2623 trace_usb_xhci_port_notify(port->portnr, bits); in xhci_port_notify()
2624 port->portsc |= bits; in xhci_port_notify()
2625 if (!xhci_running(port->xhci)) { in xhci_port_notify()
2628 xhci_event(port->xhci, &ev, 0); in xhci_port_notify()
2636 port->portsc = PORTSC_PP; in xhci_port_update()
2638 port->portsc |= PORTSC_CCS; in xhci_port_update()
2639 switch (port->uport->dev->speed) { in xhci_port_update()
2641 port->portsc |= PORTSC_SPEED_LOW; in xhci_port_update()
2645 port->portsc |= PORTSC_SPEED_FULL; in xhci_port_update()
2649 port->portsc |= PORTSC_SPEED_HIGH; in xhci_port_update()
2653 port->portsc |= PORTSC_SPEED_SUPER; in xhci_port_update()
2654 port->portsc |= PORTSC_PED; in xhci_port_update()
2659 set_field(&port->portsc, pls, PORTSC_PLS); in xhci_port_update()
2660 trace_usb_xhci_port_link(port->portnr, pls); in xhci_port_update()
2666 trace_usb_xhci_port_reset(port->portnr, warm_reset); in xhci_port_reset()
2672 usb_device_reset(port->uport->dev); in xhci_port_reset()
2674 switch (port->uport->dev->speed) { in xhci_port_reset()
2677 port->portsc |= PORTSC_WRC; in xhci_port_reset()
2683 set_field(&port->portsc, PLS_U0, PORTSC_PLS); in xhci_port_reset()
2684 trace_usb_xhci_port_link(port->portnr, PLS_U0); in xhci_port_reset()
2685 port->portsc |= PORTSC_PED; in xhci_port_reset()
2689 port->portsc &= ~PORTSC_PR; in xhci_port_reset()
2699 if (!(xhci->usbsts & USBSTS_HCH)) { in xhci_reset()
2703 xhci->usbcmd = 0; in xhci_reset()
2704 xhci->usbsts = USBSTS_HCH; in xhci_reset()
2705 xhci->dnctrl = 0; in xhci_reset()
2706 xhci->crcr_low = 0; in xhci_reset()
2707 xhci->crcr_high = 0; in xhci_reset()
2708 xhci->dcbaap_low = 0; in xhci_reset()
2709 xhci->dcbaap_high = 0; in xhci_reset()
2710 xhci->config = 0; in xhci_reset()
2712 for (i = 0; i < xhci->numslots; i++) { in xhci_reset()
2716 for (i = 0; i < xhci->numports; i++) { in xhci_reset()
2717 xhci_port_update(xhci->ports + i, 0); in xhci_reset()
2720 for (i = 0; i < xhci->numintrs; i++) { in xhci_reset()
2721 xhci->intr[i].iman = 0; in xhci_reset()
2722 xhci->intr[i].imod = 0; in xhci_reset()
2723 xhci->intr[i].erstsz = 0; in xhci_reset()
2724 xhci->intr[i].erstba_low = 0; in xhci_reset()
2725 xhci->intr[i].erstba_high = 0; in xhci_reset()
2726 xhci->intr[i].erdp_low = 0; in xhci_reset()
2727 xhci->intr[i].erdp_high = 0; in xhci_reset()
2729 xhci->intr[i].er_ep_idx = 0; in xhci_reset()
2730 xhci->intr[i].er_pcs = 1; in xhci_reset()
2731 xhci->intr[i].ev_buffer_put = 0; in xhci_reset()
2732 xhci->intr[i].ev_buffer_get = 0; in xhci_reset()
2735 xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); in xhci_reset()
2749 ret = ((xhci->numports_2+xhci->numports_3)<<24) in xhci_cap_read()
2750 | (xhci->numintrs<<8) | xhci->numslots; in xhci_cap_read()
2760 ret = 0x00080000 | (xhci->max_pstreams_mask << 12); in xhci_cap_read()
2762 ret = 0x00080001 | (xhci->max_pstreams_mask << 12); in xhci_cap_read()
2780 ret = (xhci->numports_2 << 8) | (xhci->numports_3 + 1); in xhci_cap_read()
2792 ret = (xhci->numports_3 << 8) | 1; in xhci_cap_read()
2813 ret = port->portsc; in xhci_port_read()
2831 trace_usb_xhci_port_read(port->portnr, reg, ret); in xhci_port_read()
2841 trace_usb_xhci_port_write(port->portnr, reg, val); in xhci_port_write()
2845 /* write-1-to-start bits */ in xhci_port_write()
2855 portsc = port->portsc; in xhci_port_write()
2857 /* write-1-to-clear bits*/ in xhci_port_write()
2862 uint32_t old_pls = get_field(port->portsc, PORTSC_PLS); in xhci_port_write()
2868 trace_usb_xhci_port_link(port->portnr, new_pls); in xhci_port_write()
2875 trace_usb_xhci_port_link(port->portnr, new_pls); in xhci_port_write()
2890 port->portsc = portsc; in xhci_port_write()
2903 qemu_log_mask(LOG_GUEST_ERROR, "%s: Write to read-only PORTLI register", in xhci_port_write()
2922 ret = xhci->usbcmd; in xhci_oper_read()
2925 ret = xhci->usbsts; in xhci_oper_read()
2931 ret = xhci->dnctrl; in xhci_oper_read()
2934 ret = xhci->crcr_low & ~0xe; in xhci_oper_read()
2937 ret = xhci->crcr_high; in xhci_oper_read()
2940 ret = xhci->dcbaap_low; in xhci_oper_read()
2943 ret = xhci->dcbaap_high; in xhci_oper_read()
2946 ret = xhci->config; in xhci_oper_read()
2966 if ((val & USBCMD_RS) && !(xhci->usbcmd & USBCMD_RS)) { in xhci_oper_write()
2968 } else if (!(val & USBCMD_RS) && (xhci->usbcmd & USBCMD_RS)) { in xhci_oper_write()
2973 xhci->usbsts &= ~USBSTS_SRE; in xhci_oper_write()
2977 xhci->usbsts |= USBSTS_SRE; in xhci_oper_write()
2979 xhci->usbcmd = val & 0xc0f; in xhci_oper_write()
2988 /* these bits are write-1-to-clear */ in xhci_oper_write()
2989 xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE)); in xhci_oper_write()
2994 xhci->dnctrl = val & 0xffff; in xhci_oper_write()
2997 xhci->crcr_low = (val & 0xffffffcf) | (xhci->crcr_low & CRCR_CRR); in xhci_oper_write()
3000 xhci->crcr_high = val; in xhci_oper_write()
3001 if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { in xhci_oper_write()
3003 xhci->crcr_low &= ~CRCR_CRR; in xhci_oper_write()
3005 DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); in xhci_oper_write()
3007 dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); in xhci_oper_write()
3008 xhci_ring_init(xhci, &xhci->cmd_ring, base); in xhci_oper_write()
3010 xhci->crcr_low &= ~(CRCR_CA | CRCR_CS); in xhci_oper_write()
3013 xhci->dcbaap_low = val & 0xffffffc0; in xhci_oper_write()
3016 xhci->dcbaap_high = val; in xhci_oper_write()
3019 xhci->config = val & 0xff; in xhci_oper_write()
3042 int v = (reg - 0x20) / 0x20; in xhci_runtime_read()
3043 XHCIInterrupter *intr = &xhci->intr[v]; in xhci_runtime_read()
3046 ret = intr->iman; in xhci_runtime_read()
3049 ret = intr->imod; in xhci_runtime_read()
3052 ret = intr->erstsz; in xhci_runtime_read()
3055 ret = intr->erstba_low; in xhci_runtime_read()
3058 ret = intr->erstba_high; in xhci_runtime_read()
3061 ret = intr->erdp_low; in xhci_runtime_read()
3064 ret = intr->erdp_high; in xhci_runtime_read()
3086 v = (reg - 0x20) / 0x20; in xhci_runtime_write()
3087 intr = &xhci->intr[v]; in xhci_runtime_write()
3092 intr->iman &= ~IMAN_IP; in xhci_runtime_write()
3094 intr->iman &= ~IMAN_IE; in xhci_runtime_write()
3095 intr->iman |= val & IMAN_IE; in xhci_runtime_write()
3099 intr->imod = val; in xhci_runtime_write()
3102 intr->erstsz = val & 0xffff; in xhci_runtime_write()
3105 if (xhci->nec_quirks) { in xhci_runtime_write()
3107 intr->erstba_low = val & 0xfffffff0; in xhci_runtime_write()
3109 intr->erstba_low = val & 0xffffffc0; in xhci_runtime_write()
3113 intr->erstba_high = val; in xhci_runtime_write()
3118 intr->erdp_low &= ~ERDP_EHB; in xhci_runtime_write()
3120 intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB); in xhci_runtime_write()
3122 dma_addr_t erdp = xhci_addr64(intr->erdp_low, intr->erdp_high); in xhci_runtime_write()
3123 unsigned int dp_idx = (erdp - intr->er_start) / TRB_SIZE; in xhci_runtime_write()
3124 if (erdp >= intr->er_start && in xhci_runtime_write()
3125 erdp < (intr->er_start + TRB_SIZE * intr->er_size) && in xhci_runtime_write()
3126 dp_idx != intr->er_ep_idx) { in xhci_runtime_write()
3132 intr->erdp_high = val; in xhci_runtime_write()
3172 if (reg > xhci->numslots) { in xhci_doorbell_write()
3233 XHCIState *xhci = usbport->opaque; in xhci_attach()
3241 XHCIState *xhci = usbport->opaque; in xhci_detach()
3250 XHCIState *xhci = usbport->opaque; in xhci_wakeup()
3254 if (get_field(port->portsc, PORTSC_PLS) != PLS_U3) { in xhci_wakeup()
3257 set_field(&port->portsc, PLS_RESUME, PORTSC_PLS); in xhci_wakeup()
3265 if (packet->status == USB_RET_REMOVE_FROM_QUEUE) { in xhci_complete()
3270 xhci_kick_epctx(xfer->epctx, xfer->streamid); in xhci_complete()
3271 if (xfer->complete) { in xhci_complete()
3281 xhci_detach_slot(xhci, child->port); in xhci_child_detach()
3294 if (ep->nr == 0) { in xhci_find_epid()
3297 if (ep->pid == USB_TOKEN_IN) { in xhci_find_epid()
3298 return ep->nr * 2 + 1; in xhci_find_epid()
3300 return ep->nr * 2; in xhci_find_epid()
3312 uport = epctx->xhci->slots[epctx->slotid - 1].uport; in xhci_epid_to_usbep()
3313 if (!uport || !uport->dev) { in xhci_epid_to_usbep()
3316 token = (epctx->epid & 1) ? USB_TOKEN_IN : USB_TOKEN_OUT; in xhci_epid_to_usbep()
3317 return usb_ep_get(uport->dev, token, epctx->epid >> 1); in xhci_epid_to_usbep()
3327 slotid = ep->dev->addr; in xhci_wakeup_endpoint()
3328 if (slotid == 0 || slotid > xhci->numslots || in xhci_wakeup_endpoint()
3329 !xhci->slots[slotid - 1].enabled) { in xhci_wakeup_endpoint()
3330 DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr); in xhci_wakeup_endpoint()
3345 xhci->usbsts = USBSTS_HCH; in usb_xhci_init()
3347 if (xhci->numports_2 > XHCI_MAXPORTS_2) { in usb_xhci_init()
3348 xhci->numports_2 = XHCI_MAXPORTS_2; in usb_xhci_init()
3350 if (xhci->numports_3 > XHCI_MAXPORTS_3) { in usb_xhci_init()
3351 xhci->numports_3 = XHCI_MAXPORTS_3; in usb_xhci_init()
3353 usbports = MAX(xhci->numports_2, xhci->numports_3); in usb_xhci_init()
3354 xhci->numports = xhci->numports_2 + xhci->numports_3; in usb_xhci_init()
3356 usb_bus_new(&xhci->bus, sizeof(xhci->bus), &xhci_bus_ops, xhci->hostOpaque); in usb_xhci_init()
3360 if (i < xhci->numports_2) { in usb_xhci_init()
3361 port = &xhci->ports[i + xhci->numports_3]; in usb_xhci_init()
3362 port->portnr = i + 1 + xhci->numports_3; in usb_xhci_init()
3363 port->uport = &xhci->uports[i]; in usb_xhci_init()
3364 port->speedmask = in usb_xhci_init()
3369 snprintf(port->name, sizeof(port->name), "usb2 port #%d", i+1); in usb_xhci_init()
3370 speedmask |= port->speedmask; in usb_xhci_init()
3372 if (i < xhci->numports_3) { in usb_xhci_init()
3373 port = &xhci->ports[i]; in usb_xhci_init()
3374 port->portnr = i + 1; in usb_xhci_init()
3375 port->uport = &xhci->uports[i]; in usb_xhci_init()
3376 port->speedmask = USB_SPEED_MASK_SUPER; in usb_xhci_init()
3378 snprintf(port->name, sizeof(port->name), "usb3 port #%d", i+1); in usb_xhci_init()
3379 speedmask |= port->speedmask; in usb_xhci_init()
3381 usb_register_port(&xhci->bus, &xhci->uports[i], xhci, i, in usb_xhci_init()
3392 if (xhci->numintrs > XHCI_MAXINTRS) { in usb_xhci_realize()
3393 xhci->numintrs = XHCI_MAXINTRS; in usb_xhci_realize()
3395 while (xhci->numintrs & (xhci->numintrs - 1)) { /* ! power of 2 */ in usb_xhci_realize()
3396 xhci->numintrs++; in usb_xhci_realize()
3398 if (xhci->numintrs < 1) { in usb_xhci_realize()
3399 xhci->numintrs = 1; in usb_xhci_realize()
3401 if (xhci->numslots > XHCI_MAXSLOTS) { in usb_xhci_realize()
3402 xhci->numslots = XHCI_MAXSLOTS; in usb_xhci_realize()
3404 if (xhci->numslots < 1) { in usb_xhci_realize()
3405 xhci->numslots = 1; in usb_xhci_realize()
3408 xhci->max_pstreams_mask = 7; /* == 256 primary streams */ in usb_xhci_realize()
3410 xhci->max_pstreams_mask = 0; in usb_xhci_realize()
3414 xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci); in usb_xhci_realize()
3416 memory_region_init(&xhci->mem, OBJECT(dev), "xhci", XHCI_LEN_REGS); in usb_xhci_realize()
3417 memory_region_init_io(&xhci->mem_cap, OBJECT(dev), &xhci_cap_ops, xhci, in usb_xhci_realize()
3419 memory_region_init_io(&xhci->mem_oper, OBJECT(dev), &xhci_oper_ops, xhci, in usb_xhci_realize()
3421 memory_region_init_io(&xhci->mem_runtime, OBJECT(dev), &xhci_runtime_ops, in usb_xhci_realize()
3423 memory_region_init_io(&xhci->mem_doorbell, OBJECT(dev), &xhci_doorbell_ops, in usb_xhci_realize()
3426 memory_region_add_subregion(&xhci->mem, 0, &xhci->mem_cap); in usb_xhci_realize()
3427 memory_region_add_subregion(&xhci->mem, OFF_OPER, &xhci->mem_oper); in usb_xhci_realize()
3428 memory_region_add_subregion(&xhci->mem, OFF_RUNTIME, &xhci->mem_runtime); in usb_xhci_realize()
3429 memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell); in usb_xhci_realize()
3431 for (i = 0; i < xhci->numports; i++) { in usb_xhci_realize()
3432 XHCIPort *port = &xhci->ports[i]; in usb_xhci_realize()
3434 port->xhci = xhci; in usb_xhci_realize()
3435 memory_region_init_io(&port->mem, OBJECT(dev), &xhci_port_ops, port, in usb_xhci_realize()
3436 port->name, 0x10); in usb_xhci_realize()
3437 memory_region_add_subregion(&xhci->mem, offset, &port->mem); in usb_xhci_realize()
3448 for (i = 0; i < xhci->numslots; i++) { in usb_xhci_unrealize()
3452 if (xhci->mfwrap_timer) { in usb_xhci_unrealize()
3453 timer_free(xhci->mfwrap_timer); in usb_xhci_unrealize()
3454 xhci->mfwrap_timer = NULL; in usb_xhci_unrealize()
3457 memory_region_del_subregion(&xhci->mem, &xhci->mem_cap); in usb_xhci_unrealize()
3458 memory_region_del_subregion(&xhci->mem, &xhci->mem_oper); in usb_xhci_unrealize()
3459 memory_region_del_subregion(&xhci->mem, &xhci->mem_runtime); in usb_xhci_unrealize()
3460 memory_region_del_subregion(&xhci->mem, &xhci->mem_doorbell); in usb_xhci_unrealize()
3462 for (i = 0; i < xhci->numports; i++) { in usb_xhci_unrealize()
3463 XHCIPort *port = &xhci->ports[i]; in usb_xhci_unrealize()
3464 memory_region_del_subregion(&xhci->mem, &port->mem); in usb_xhci_unrealize()
3467 usb_bus_release(&xhci->bus); in usb_xhci_unrealize()
3481 dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); in usb_xhci_post_load()
3483 for (slotid = 1; slotid <= xhci->numslots; slotid++) { in usb_xhci_post_load()
3484 slot = &xhci->slots[slotid-1]; in usb_xhci_post_load()
3485 if (!slot->addressed) { in usb_xhci_post_load()
3488 ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &addr, MEMTXATTRS_UNSPECIFIED); in usb_xhci_post_load()
3489 slot->ctx = xhci_mask64(addr); in usb_xhci_post_load()
3491 xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx)); in usb_xhci_post_load()
3492 slot->uport = xhci_lookup_uport(xhci, slot_ctx); in usb_xhci_post_load()
3493 if (!slot->uport) { in usb_xhci_post_load()
3495 slot->enabled = 0; in usb_xhci_post_load()
3496 slot->addressed = 0; in usb_xhci_post_load()
3499 assert(slot->uport && slot->uport->dev); in usb_xhci_post_load()
3502 pctx = slot->ctx + 32 * epid; in usb_xhci_post_load()
3509 slot->eps[epid-1] = epctx; in usb_xhci_post_load()
3511 epctx->state = state; in usb_xhci_post_load()
3514 timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); in usb_xhci_post_load()
3522 .name = "xhci-ring",
3532 .name = "xhci-port",
3541 .name = "xhci-slot",
3551 .name = "xhci-event",
3571 .name = "xhci-intr",
3603 .name = "xhci-core",
3646 dc->realize = usb_xhci_realize; in xhci_class_init()
3647 dc->unrealize = usb_xhci_unrealize; in xhci_class_init()
3650 dc->user_creatable = false; in xhci_class_init()