Lines Matching +full:usb2 +full:- +full:2
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
13 * 2. Redistributions in binary form must reproduce the above copyright
31 -s <n>,xhci,{devices}
69 #define XHCI_MAX_DEVS 8 /* 4 USB3 + 4 USB2 devs */
79 #define XHCI_ERST_MAX 0 /* max 2^entries event ring seg tbl */
86 #define XHCI_STREAMS_MAX 1 /* 4-15 in XHCI spec */
88 /* caplength and hci-version registers */
111 #define XHCI_SET_HCCP1_CSZ(x) (((x) & 0x01) << 2)
127 #define XHCI_SET_HCCP2_FSC(x) (((x) & 0x01) << 2)
186 /* device context base address array: maps slot->device context */
223 uint64_t erstba; /* event ring seg-tbl base addr */
231 int er_enq_idx; /* event ring enqueue index - xHCI */
243 * This is referenced from usb_hci->hci_sc; 1 pci_xhci_dev_emu for each
267 uint32_t hcsparams2; /* structural parameters 2 */
272 uint32_t hccparams2; /* capability parameters 2 */
289 #define XHCI_PORTREG_PTR(x,n) &((x)->portregs[(n) - 1])
290 #define XHCI_DEVINST_PTR(x,n) ((x)->devices[(n) - 1])
291 #define XHCI_SLOTDEV_PTR(x,n) ((x)->slots[(n) - 1])
293 #define XHCI_HALTED(sc) ((sc)->opregs.usbsts & XHCI_STS_HCH)
295 #define XHCI_GADDR(sc,a) paddr_guest2host((sc)->xsc_pi->pi_vmctx, \
297 XHCI_PADDR_SZ - ((a) & (XHCI_PADDR_SZ-1)))
352 evtrb->qwTrb0 = port << 24; in pci_xhci_set_evtrb()
353 evtrb->dwTrb2 = XHCI_TRB_2_ERROR_SET(errcode); in pci_xhci_set_evtrb()
354 evtrb->dwTrb3 = XHCI_TRB_3_TYPE_SET(evtype); in pci_xhci_set_evtrb()
364 sc->rtsregs.er_enq_idx = 0; in pci_xhci_reset()
365 sc->rtsregs.er_events_cnt = 0; in pci_xhci_reset()
366 sc->rtsregs.event_pcs = 1; in pci_xhci_reset()
380 do_intr = (sc->opregs.usbcmd & XHCI_CMD_RS) == 0; in pci_xhci_usbcmd_write()
382 sc->opregs.usbcmd |= XHCI_CMD_RS; in pci_xhci_usbcmd_write()
383 sc->opregs.usbsts &= ~XHCI_STS_HCH; in pci_xhci_usbcmd_write()
384 sc->opregs.usbsts |= XHCI_STS_PCD; in pci_xhci_usbcmd_write()
397 port->portsc |= XHCI_PS_CSC | XHCI_PS_CCS; in pci_xhci_usbcmd_write()
398 port->portsc &= ~XHCI_PS_PLS_MASK; in pci_xhci_usbcmd_write()
401 * XHCI 4.19.3 USB2 RxDetect->Polling, in pci_xhci_usbcmd_write()
402 * USB3 Polling->U0 in pci_xhci_usbcmd_write()
404 if (dev->dev_ue->ue_usbver == 2) in pci_xhci_usbcmd_write()
405 port->portsc |= in pci_xhci_usbcmd_write()
408 port->portsc |= in pci_xhci_usbcmd_write()
420 sc->opregs.usbcmd &= ~XHCI_CMD_RS; in pci_xhci_usbcmd_write()
421 sc->opregs.usbsts |= XHCI_STS_HCH; in pci_xhci_usbcmd_write()
422 sc->opregs.usbsts &= ~XHCI_STS_PCD; in pci_xhci_usbcmd_write()
426 cmd |= sc->opregs.usbcmd & XHCI_CMD_RS; in pci_xhci_usbcmd_write()
451 if (sc->portregs == NULL) in pci_xhci_portregs_write()
454 port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ; in pci_xhci_portregs_write()
455 offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ; in pci_xhci_portregs_write()
482 if ((p->portsc & XHCI_PS_PP) == 0) { in pci_xhci_portregs_write()
489 oldpls = XHCI_PS_PLS_GET(p->portsc); in pci_xhci_portregs_write()
493 p->portsc &= XHCI_PS_PED | XHCI_PS_PP | XHCI_PS_PLS_MASK | in pci_xhci_portregs_write()
496 p->portsc &= XHCI_PS_PED | XHCI_PS_PLS_MASK | in pci_xhci_portregs_write()
501 p->portsc |= XHCI_PS_CCS; in pci_xhci_portregs_write()
503 p->portsc |= (value & in pci_xhci_portregs_write()
513 p->portsc &= ~(value & in pci_xhci_portregs_write()
535 p->portsc &= ~XHCI_PS_PLS_MASK; in pci_xhci_portregs_write()
536 p->portsc |= XHCI_PS_PLS_SET(newpls) | in pci_xhci_portregs_write()
557 p->portpmsc = value; in pci_xhci_portregs_write()
569 p->porthlpmc = value; in pci_xhci_portregs_write()
586 assert(sc->opregs.dcbaa_p != NULL); in pci_xhci_get_dev_ctx()
588 devctx_addr = sc->opregs.dcbaa_p->dcba[slot]; in pci_xhci_get_dev_ctx()
610 if (XHCI_TRB_3_TYPE_GET(curtrb->dwTrb3) == XHCI_TRB_TYPE_LINK) { in pci_xhci_trb_next()
612 *guestaddr = curtrb->qwTrb0 & ~0xFUL; in pci_xhci_trb_next()
614 next = XHCI_GADDR(sc, curtrb->qwTrb0 & ~0xFUL); in pci_xhci_trb_next()
629 sc->rtsregs.intrreg.erdp |= XHCI_ERDP_LO_BUSY; in pci_xhci_assert_interrupt()
630 sc->rtsregs.intrreg.iman |= XHCI_IMAN_INTR_PEND; in pci_xhci_assert_interrupt()
631 sc->opregs.usbsts |= XHCI_STS_EINT; in pci_xhci_assert_interrupt()
634 if ((sc->opregs.usbcmd & XHCI_CMD_INTE) && in pci_xhci_assert_interrupt()
635 (sc->rtsregs.intrreg.iman & XHCI_IMAN_INTR_ENA)) { in pci_xhci_assert_interrupt()
636 if (pci_msi_enabled(sc->xsc_pi)) in pci_xhci_assert_interrupt()
637 pci_generate_msi(sc->xsc_pi, 0); in pci_xhci_assert_interrupt()
639 pci_lintr_assert(sc->xsc_pi); in pci_xhci_assert_interrupt()
647 if (!pci_msi_enabled(sc->xsc_pi)) in pci_xhci_deassert_interrupt()
648 pci_lintr_assert(sc->xsc_pi); in pci_xhci_deassert_interrupt()
659 dev_ctx = dev->dev_ctx; in pci_xhci_init_ep()
660 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_init_ep()
661 devep = &dev->eps[epid]; in pci_xhci_init_ep()
662 pstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0); in pci_xhci_init_ep()
665 assert(devep->ep_sctx_trbs == NULL); in pci_xhci_init_ep()
667 devep->ep_sctx = XHCI_GADDR(dev->xsc, ep_ctx->qwEpCtx2 & in pci_xhci_init_ep()
669 devep->ep_sctx_trbs = calloc(pstreams, in pci_xhci_init_ep()
672 devep->ep_sctx_trbs[i].ringaddr = in pci_xhci_init_ep()
673 devep->ep_sctx[i].qwSctx0 & in pci_xhci_init_ep()
675 devep->ep_sctx_trbs[i].ccs = in pci_xhci_init_ep()
676 XHCI_SCTX_0_DCS_GET(devep->ep_sctx[i].qwSctx0); in pci_xhci_init_ep()
680 devep->ep_ringaddr = ep_ctx->qwEpCtx2 & in pci_xhci_init_ep()
682 devep->ep_ccs = XHCI_EPCTX_2_DCS_GET(ep_ctx->qwEpCtx2); in pci_xhci_init_ep()
683 devep->ep_tr = XHCI_GADDR(dev->xsc, devep->ep_ringaddr); in pci_xhci_init_ep()
684 DPRINTF(("init_ep tr DCS %x", devep->ep_ccs)); in pci_xhci_init_ep()
686 devep->ep_MaxPStreams = pstreams; in pci_xhci_init_ep()
688 if (devep->ep_xfer == NULL) { in pci_xhci_init_ep()
689 devep->ep_xfer = malloc(sizeof(struct usb_data_xfer)); in pci_xhci_init_ep()
690 USB_DATA_XFER_INIT(devep->ep_xfer); in pci_xhci_init_ep()
703 dev_ctx = dev->dev_ctx; in pci_xhci_disable_ep()
704 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_disable_ep()
705 ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_DISABLED; in pci_xhci_disable_ep()
707 devep = &dev->eps[epid]; in pci_xhci_disable_ep()
708 if (devep->ep_MaxPStreams > 0) in pci_xhci_disable_ep()
709 free(devep->ep_sctx_trbs); in pci_xhci_disable_ep()
711 if (devep->ep_xfer != NULL) { in pci_xhci_disable_ep()
712 free(devep->ep_xfer); in pci_xhci_disable_ep()
713 devep->ep_xfer = NULL; in pci_xhci_disable_ep()
731 dev->dev_slotstate = XHCI_ST_DISABLED; in pci_xhci_reset_slot()
749 rts = &sc->rtsregs; in pci_xhci_insert_event()
751 erdp = rts->intrreg.erdp & ~0xF; in pci_xhci_insert_event()
752 erdp_idx = (erdp - rts->erstba_p[rts->er_deq_seg].qwEvrsTablePtr) / in pci_xhci_insert_event()
755 DPRINTF(("pci_xhci: insert event 0[%lx] 2[%x] 3[%x]", in pci_xhci_insert_event()
756 evtrb->qwTrb0, evtrb->dwTrb2, evtrb->dwTrb3)); in pci_xhci_insert_event()
758 erdp_idx, rts->er_deq_seg, rts->er_enq_idx, in pci_xhci_insert_event()
759 rts->er_enq_seg, rts->event_pcs)); in pci_xhci_insert_event()
761 erdp, rts->erstba_p->qwEvrsTablePtr, in pci_xhci_insert_event()
762 rts->erstba_p->dwEvrsTableSize, do_intr)); in pci_xhci_insert_event()
764 evtrbptr = &rts->erst_p[rts->er_enq_idx]; in pci_xhci_insert_event()
766 /* TODO: multi-segment table */ in pci_xhci_insert_event()
767 if (rts->er_events_cnt >= rts->erstba_p->dwEvrsTableSize) { in pci_xhci_insert_event()
774 if (rts->er_events_cnt == rts->erstba_p->dwEvrsTableSize - 1) { in pci_xhci_insert_event()
777 if ((evtrbptr->dwTrb3 & 0x1) == (rts->event_pcs & 0x1)) { in pci_xhci_insert_event()
787 rts->event_pcs; in pci_xhci_insert_event()
788 rts->er_events_cnt++; in pci_xhci_insert_event()
789 memcpy(&rts->erst_p[rts->er_enq_idx], &errev, in pci_xhci_insert_event()
791 rts->er_enq_idx = (rts->er_enq_idx + 1) % in pci_xhci_insert_event()
792 rts->erstba_p->dwEvrsTableSize; in pci_xhci_insert_event()
799 rts->er_events_cnt++; in pci_xhci_insert_event()
802 evtrb->dwTrb3 &= ~XHCI_TRB_3_CYCLE_BIT; in pci_xhci_insert_event()
803 evtrb->dwTrb3 |= rts->event_pcs; in pci_xhci_insert_event()
805 memcpy(&rts->erst_p[rts->er_enq_idx], evtrb, sizeof(struct xhci_trb)); in pci_xhci_insert_event()
806 rts->er_enq_idx = (rts->er_enq_idx + 1) % in pci_xhci_insert_event()
807 rts->erstba_p->dwEvrsTableSize; in pci_xhci_insert_event()
809 if (rts->er_enq_idx == 0) in pci_xhci_insert_event()
810 rts->event_pcs ^= 1; in pci_xhci_insert_event()
827 if (sc->portregs != NULL) in pci_xhci_cmd_enable_slot()
830 if (dev && dev->dev_slotstate == XHCI_ST_DISABLED) { in pci_xhci_cmd_enable_slot()
832 dev->dev_slotstate = XHCI_ST_ENABLED; in pci_xhci_cmd_enable_slot()
834 dev->hci.hci_address = i; in pci_xhci_cmd_enable_slot()
853 if (sc->portregs == NULL) { in pci_xhci_cmd_disable_slot()
864 if (dev->dev_slotstate == XHCI_ST_DISABLED) { in pci_xhci_cmd_disable_slot()
867 dev->dev_slotstate = XHCI_ST_DISABLED; in pci_xhci_cmd_disable_slot()
886 if (sc->portregs == NULL) { in pci_xhci_cmd_reset_device()
898 if (!dev || dev->dev_slotstate == XHCI_ST_DISABLED) in pci_xhci_cmd_reset_device()
901 dev->dev_slotstate = XHCI_ST_DEFAULT; in pci_xhci_cmd_reset_device()
903 dev->hci.hci_address = 0; in pci_xhci_cmd_reset_device()
911 dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( in pci_xhci_cmd_reset_device()
912 dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_DEFAULT, in pci_xhci_cmd_reset_device()
916 dev_ctx->ctx_slot.dwSctx0 = FIELD_REPLACE( in pci_xhci_cmd_reset_device()
917 dev_ctx->ctx_slot.dwSctx0, 1, 0x1F, 27); in pci_xhci_cmd_reset_device()
919 /* reset all eps other than ep-0 */ in pci_xhci_cmd_reset_device()
920 for (i = 2; i <= 31; i++) { in pci_xhci_cmd_reset_device()
921 ep_ctx = &dev_ctx->ctx_ep[i]; in pci_xhci_cmd_reset_device()
922 ep_ctx->dwEpCtx0 = FIELD_REPLACE( ep_ctx->dwEpCtx0, in pci_xhci_cmd_reset_device()
944 input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); in pci_xhci_cmd_address_device()
945 islot_ctx = &input_ctx->ctx_slot; in pci_xhci_cmd_address_device()
946 ep0_ctx = &input_ctx->ctx_ep[1]; in pci_xhci_cmd_address_device()
949 input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1)); in pci_xhci_cmd_address_device()
951 islot_ctx->dwSctx0, islot_ctx->dwSctx1, in pci_xhci_cmd_address_device()
952 islot_ctx->dwSctx2, islot_ctx->dwSctx3)); in pci_xhci_cmd_address_device()
954 ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, in pci_xhci_cmd_address_device()
955 ep0_ctx->dwEpCtx4)); in pci_xhci_cmd_address_device()
957 /* when setting address: drop-ctx=0, add-ctx=slot+ep0 */ in pci_xhci_cmd_address_device()
958 if ((input_ctx->ctx_input.dwInCtx0 != 0) || in pci_xhci_cmd_address_device()
959 (input_ctx->ctx_input.dwInCtx1 & 0x03) != 0x03) { in pci_xhci_cmd_address_device()
978 dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_address_device()
979 dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); in pci_xhci_cmd_address_device()
984 dev->hci.hci_address = slot; in pci_xhci_cmd_address_device()
985 dev->dev_ctx = dev_ctx; in pci_xhci_cmd_address_device()
987 if (dev->dev_ue->ue_reset == NULL || in pci_xhci_cmd_address_device()
988 dev->dev_ue->ue_reset(dev->dev_sc) < 0) { in pci_xhci_cmd_address_device()
993 memcpy(&dev_ctx->ctx_slot, islot_ctx, sizeof(struct xhci_slot_ctx)); in pci_xhci_cmd_address_device()
995 dev_ctx->ctx_slot.dwSctx3 = in pci_xhci_cmd_address_device()
999 memcpy(&dev_ctx->ctx_ep[1], ep0_ctx, sizeof(struct xhci_endp_ctx)); in pci_xhci_cmd_address_device()
1000 ep0_ctx = &dev_ctx->ctx_ep[1]; in pci_xhci_cmd_address_device()
1001 ep0_ctx->dwEpCtx0 = (ep0_ctx->dwEpCtx0 & ~0x7) | in pci_xhci_cmd_address_device()
1006 dev->dev_slotstate = XHCI_ST_ADDRESSED; in pci_xhci_cmd_address_device()
1010 dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_address_device()
1011 dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); in pci_xhci_cmd_address_device()
1013 ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, in pci_xhci_cmd_address_device()
1014 ep0_ctx->dwEpCtx4)); in pci_xhci_cmd_address_device()
1040 if ((trb->dwTrb3 & XHCI_TRB_3_DCEP_BIT) != 0) { in pci_xhci_cmd_config_ep()
1041 DPRINTF(("pci_xhci config_ep - deconfigure ep slot %u", in pci_xhci_cmd_config_ep()
1043 if (dev->dev_ue->ue_stop != NULL) in pci_xhci_cmd_config_ep()
1044 dev->dev_ue->ue_stop(dev->dev_sc); in pci_xhci_cmd_config_ep()
1046 dev->dev_slotstate = XHCI_ST_ADDRESSED; in pci_xhci_cmd_config_ep()
1048 dev->hci.hci_address = 0; in pci_xhci_cmd_config_ep()
1056 dev_ctx->ctx_slot.dwSctx0 = FIELD_REPLACE( in pci_xhci_cmd_config_ep()
1057 dev_ctx->ctx_slot.dwSctx0, 1, 0x1F, 27); in pci_xhci_cmd_config_ep()
1060 dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( in pci_xhci_cmd_config_ep()
1061 dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_ADDRESSED, in pci_xhci_cmd_config_ep()
1065 for (i = 2; i < 32; i++) in pci_xhci_cmd_config_ep()
1073 if (dev->dev_slotstate < XHCI_ST_ADDRESSED) { in pci_xhci_cmd_config_ep()
1075 dev->dev_slotstate)); in pci_xhci_cmd_config_ep()
1082 * ep->state = DISABLED in pci_xhci_cmd_config_ep()
1084 * cp(ep-in, ep-out) in pci_xhci_cmd_config_ep()
1085 * ep->state = RUNNING in pci_xhci_cmd_config_ep()
1088 * cp(ep-in, ep-out) in pci_xhci_cmd_config_ep()
1089 * ep->state = RUNNING in pci_xhci_cmd_config_ep()
1090 * if input->DisabledCtx[2-31] < 30: (at least 1 ep not disabled) in pci_xhci_cmd_config_ep()
1091 * slot->state = configured in pci_xhci_cmd_config_ep()
1094 input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); in pci_xhci_cmd_config_ep()
1095 dev_ctx = dev->dev_ctx; in pci_xhci_cmd_config_ep()
1097 input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1, in pci_xhci_cmd_config_ep()
1098 input_ctx->ctx_input.dwInCtx7)); in pci_xhci_cmd_config_ep()
1100 for (i = 2; i <= 31; i++) { in pci_xhci_cmd_config_ep()
1101 ep_ctx = &dev_ctx->ctx_ep[i]; in pci_xhci_cmd_config_ep()
1103 if (input_ctx->ctx_input.dwInCtx0 & in pci_xhci_cmd_config_ep()
1105 DPRINTF((" config ep - dropping ep %d", i)); in pci_xhci_cmd_config_ep()
1109 if (input_ctx->ctx_input.dwInCtx1 & in pci_xhci_cmd_config_ep()
1111 iep_ctx = &input_ctx->ctx_ep[i]; in pci_xhci_cmd_config_ep()
1114 i, iep_ctx->dwEpCtx0, iep_ctx->dwEpCtx1, in pci_xhci_cmd_config_ep()
1115 iep_ctx->qwEpCtx2, iep_ctx->dwEpCtx4)); in pci_xhci_cmd_config_ep()
1122 ep_ctx->dwEpCtx0 = FIELD_REPLACE( in pci_xhci_cmd_config_ep()
1123 ep_ctx->dwEpCtx0, XHCI_ST_EPCTX_RUNNING, 0x7, 0); in pci_xhci_cmd_config_ep()
1128 dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( in pci_xhci_cmd_config_ep()
1129 dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_CONFIGURED, 0x1F, 27); in pci_xhci_cmd_config_ep()
1130 dev_ctx->ctx_slot.dwSctx0 = FIELD_COPY( in pci_xhci_cmd_config_ep()
1131 dev_ctx->ctx_slot.dwSctx0, input_ctx->ctx_slot.dwSctx0, 0x1F, 27); in pci_xhci_cmd_config_ep()
1132 dev->dev_slotstate = XHCI_ST_CONFIGURED; in pci_xhci_cmd_config_ep()
1134 DPRINTF(("EP configured; slot %u [0]=0x%08x [1]=0x%08x [2]=0x%08x " in pci_xhci_cmd_config_ep()
1136 slot, dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_config_ep()
1137 dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); in pci_xhci_cmd_config_ep()
1154 epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); in pci_xhci_cmd_reset_ep()
1165 type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); in pci_xhci_cmd_reset_ep()
1168 (trb->dwTrb3 & XHCI_TRB_3_SUSP_EP_BIT) != 0) { in pci_xhci_cmd_reset_ep()
1178 devep = &dev->eps[epid]; in pci_xhci_cmd_reset_ep()
1179 if (devep->ep_xfer != NULL) in pci_xhci_cmd_reset_ep()
1180 USB_DATA_XFER_RESET(devep->ep_xfer); in pci_xhci_cmd_reset_ep()
1182 dev_ctx = dev->dev_ctx; in pci_xhci_cmd_reset_ep()
1185 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_cmd_reset_ep()
1187 ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_STOPPED; in pci_xhci_cmd_reset_ep()
1189 if (devep->ep_MaxPStreams == 0) in pci_xhci_cmd_reset_ep()
1190 ep_ctx->qwEpCtx2 = devep->ep_ringaddr | devep->ep_ccs; in pci_xhci_cmd_reset_ep()
1193 epid, ep_ctx->dwEpCtx0, ep_ctx->dwEpCtx1, ep_ctx->qwEpCtx2, in pci_xhci_cmd_reset_ep()
1194 ep_ctx->dwEpCtx4)); in pci_xhci_cmd_reset_ep()
1197 (dev->dev_ue->ue_reset == NULL || in pci_xhci_cmd_reset_ep()
1198 dev->dev_ue->ue_reset(dev->dev_sc) < 0)) { in pci_xhci_cmd_reset_ep()
1214 if (devep->ep_MaxPStreams == 0) in pci_xhci_find_stream()
1217 if (devep->ep_MaxPStreams > XHCI_STREAMS_MAX) in pci_xhci_find_stream()
1220 if (XHCI_EPCTX_0_LSA_GET(ep->dwEpCtx0) == 0) { in pci_xhci_find_stream()
1226 if (streamid >= devep->ep_MaxPStreams) in pci_xhci_find_stream()
1229 sctx = (struct xhci_stream_ctx *)XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + in pci_xhci_find_stream()
1231 if (!XHCI_SCTX_0_SCT_GET(sctx->qwSctx0)) in pci_xhci_find_stream()
1256 DPRINTF(("pci_xhci set_tr: new-tr x%016lx, SCT %u DCS %u", in pci_xhci_cmd_set_tr()
1257 (trb->qwTrb0 & ~0xF), (uint32_t)((trb->qwTrb0 >> 1) & 0x7), in pci_xhci_cmd_set_tr()
1258 (uint32_t)(trb->qwTrb0 & 0x1))); in pci_xhci_cmd_set_tr()
1259 DPRINTF((" stream-id %u, slot %u, epid %u, C %u", in pci_xhci_cmd_set_tr()
1260 (trb->dwTrb2 >> 16) & 0xFFFF, in pci_xhci_cmd_set_tr()
1261 XHCI_TRB_3_SLOT_GET(trb->dwTrb3), in pci_xhci_cmd_set_tr()
1262 XHCI_TRB_3_EP_GET(trb->dwTrb3), trb->dwTrb3 & 0x1)); in pci_xhci_cmd_set_tr()
1264 epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); in pci_xhci_cmd_set_tr()
1271 dev_ctx = dev->dev_ctx; in pci_xhci_cmd_set_tr()
1274 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_cmd_set_tr()
1275 devep = &dev->eps[epid]; in pci_xhci_cmd_set_tr()
1277 switch (XHCI_EPCTX_0_EPSTATE_GET(ep_ctx->dwEpCtx0)) { in pci_xhci_cmd_set_tr()
1283 XHCI_EPCTX_0_EPSTATE_GET(ep_ctx->dwEpCtx0))); in pci_xhci_cmd_set_tr()
1288 streamid = XHCI_TRB_2_STREAM_GET(trb->dwTrb2); in pci_xhci_cmd_set_tr()
1289 if (devep->ep_MaxPStreams > 0) { in pci_xhci_cmd_set_tr()
1292 assert(devep->ep_sctx != NULL); in pci_xhci_cmd_set_tr()
1294 devep->ep_sctx[streamid].qwSctx0 = trb->qwTrb0; in pci_xhci_cmd_set_tr()
1295 devep->ep_sctx_trbs[streamid].ringaddr = in pci_xhci_cmd_set_tr()
1296 trb->qwTrb0 & ~0xF; in pci_xhci_cmd_set_tr()
1297 devep->ep_sctx_trbs[streamid].ccs = in pci_xhci_cmd_set_tr()
1298 XHCI_EPCTX_2_DCS_GET(trb->qwTrb0); in pci_xhci_cmd_set_tr()
1305 ep_ctx->qwEpCtx2 = trb->qwTrb0 & ~0xFUL; in pci_xhci_cmd_set_tr()
1306 devep->ep_ringaddr = ep_ctx->qwEpCtx2 & ~0xFUL; in pci_xhci_cmd_set_tr()
1307 devep->ep_ccs = trb->qwTrb0 & 0x1; in pci_xhci_cmd_set_tr()
1308 devep->ep_tr = XHCI_GADDR(sc, devep->ep_ringaddr); in pci_xhci_cmd_set_tr()
1311 pci_xhci_dump_trb(devep->ep_tr); in pci_xhci_cmd_set_tr()
1313 ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_STOPPED; in pci_xhci_cmd_set_tr()
1329 input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); in pci_xhci_cmd_eval_ctx()
1330 islot_ctx = &input_ctx->ctx_slot; in pci_xhci_cmd_eval_ctx()
1331 ep0_ctx = &input_ctx->ctx_ep[1]; in pci_xhci_cmd_eval_ctx()
1334 input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1)); in pci_xhci_cmd_eval_ctx()
1336 islot_ctx->dwSctx0, islot_ctx->dwSctx1, in pci_xhci_cmd_eval_ctx()
1337 islot_ctx->dwSctx2, islot_ctx->dwSctx3)); in pci_xhci_cmd_eval_ctx()
1339 ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, in pci_xhci_cmd_eval_ctx()
1340 ep0_ctx->dwEpCtx4)); in pci_xhci_cmd_eval_ctx()
1342 /* this command expects drop-ctx=0 & add-ctx=slot+ep0 */ in pci_xhci_cmd_eval_ctx()
1343 if ((input_ctx->ctx_input.dwInCtx0 != 0) || in pci_xhci_cmd_eval_ctx()
1344 (input_ctx->ctx_input.dwInCtx1 & 0x03) == 0) { in pci_xhci_cmd_eval_ctx()
1363 dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_eval_ctx()
1364 dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); in pci_xhci_cmd_eval_ctx()
1366 if (input_ctx->ctx_input.dwInCtx1 & 0x01) { /* slot ctx */ in pci_xhci_cmd_eval_ctx()
1368 dev_ctx->ctx_slot.dwSctx1 = FIELD_COPY( in pci_xhci_cmd_eval_ctx()
1369 dev_ctx->ctx_slot.dwSctx1, input_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_eval_ctx()
1373 dev_ctx->ctx_slot.dwSctx2 = FIELD_COPY( in pci_xhci_cmd_eval_ctx()
1374 dev_ctx->ctx_slot.dwSctx2, input_ctx->ctx_slot.dwSctx2, in pci_xhci_cmd_eval_ctx()
1377 if (input_ctx->ctx_input.dwInCtx1 & 0x02) { /* control ctx */ in pci_xhci_cmd_eval_ctx()
1379 dev_ctx->ctx_ep[1].dwEpCtx1 = FIELD_COPY( in pci_xhci_cmd_eval_ctx()
1380 dev_ctx->ctx_ep[1].dwEpCtx1, ep0_ctx->dwEpCtx1, in pci_xhci_cmd_eval_ctx()
1383 ep0_ctx = &dev_ctx->ctx_ep[1]; in pci_xhci_cmd_eval_ctx()
1388 dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, in pci_xhci_cmd_eval_ctx()
1389 dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); in pci_xhci_cmd_eval_ctx()
1391 ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, in pci_xhci_cmd_eval_ctx()
1392 ep0_ctx->dwEpCtx4)); in pci_xhci_cmd_eval_ctx()
1404 uint32_t ccs; /* cycle state (XHCI 4.9.2) */ in pci_xhci_complete_commands()
1411 sc->opregs.crcr |= XHCI_CRCR_LO_CRR; in pci_xhci_complete_commands()
1413 trb = sc->opregs.cr_p; in pci_xhci_complete_commands()
1414 ccs = sc->opregs.crcr & XHCI_CRCR_LO_RCS; in pci_xhci_complete_commands()
1415 crcr = sc->opregs.crcr & ~0xF; in pci_xhci_complete_commands()
1418 sc->opregs.cr_p = trb; in pci_xhci_complete_commands()
1420 type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1422 if ((trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT) != in pci_xhci_complete_commands()
1428 type, trb->qwTrb0, trb->dwTrb2, trb->dwTrb3, in pci_xhci_complete_commands()
1429 trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT, ccs)); in pci_xhci_complete_commands()
1439 if (trb->dwTrb3 & XHCI_TRB_3_TC_BIT) in pci_xhci_complete_commands()
1448 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1453 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1458 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1463 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1469 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1475 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1480 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1485 slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); in pci_xhci_complete_commands()
1528 sc->opregs.crcr = crcr | (sc->opregs.crcr & XHCI_CRCR_LO_CA) | ccs; in pci_xhci_complete_commands()
1529 sc->opregs.crcr &= ~XHCI_CRCR_LO_CRR; in pci_xhci_complete_commands()
1564 type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); in pci_xhci_dump_trb()
1565 DPRINTF(("pci_xhci: trb[@%p] type x%02x %s 0:x%016lx 2:x%08x 3:x%08x", in pci_xhci_dump_trb()
1568 trb->qwTrb0, trb->dwTrb2, trb->dwTrb3)); in pci_xhci_dump_trb()
1586 devep = &dev->eps[epid]; in pci_xhci_xfer_complete()
1592 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_xfer_complete()
1599 for (i = xfer->head; xfer->ndata > 0; ) { in pci_xhci_xfer_complete()
1600 evtrb.qwTrb0 = (uint64_t)xfer->data[i].hci_data; in pci_xhci_xfer_complete()
1602 trbflags = trb->dwTrb3; in pci_xhci_xfer_complete()
1606 i, xfer->data[i].processed, xfer->data[i].blen, in pci_xhci_xfer_complete()
1609 trb->dwTrb3 & XHCI_TRB_3_IOC_BIT ? 1 : 0)); in pci_xhci_xfer_complete()
1611 if (!xfer->data[i].processed) { in pci_xhci_xfer_complete()
1612 xfer->head = i; in pci_xhci_xfer_complete()
1616 xfer->ndata--; in pci_xhci_xfer_complete()
1617 edtla += xfer->data[i].bdone; in pci_xhci_xfer_complete()
1619 trb->dwTrb3 = (trb->dwTrb3 & ~0x1) | (xfer->data[i].ccs); in pci_xhci_xfer_complete()
1622 xfer->data[i].streamid, xfer->data[i].trbnext, in pci_xhci_xfer_complete()
1623 xfer->data[i].ccs); in pci_xhci_xfer_complete()
1626 if (!(trb->dwTrb3 & XHCI_TRB_3_IOC_BIT) && in pci_xhci_xfer_complete()
1628 (trb->dwTrb3 & XHCI_TRB_3_ISP_BIT))) { in pci_xhci_xfer_complete()
1635 XHCI_TRB_2_REM_SET(xfer->data[i].blen); in pci_xhci_xfer_complete()
1642 evtrb.qwTrb0 = trb->qwTrb0; in pci_xhci_xfer_complete()
1668 if (devep->ep_MaxPStreams != 0) { in pci_xhci_update_ep_ring()
1669 devep->ep_sctx[streamid].qwSctx0 = (ringaddr & ~0xFUL) | in pci_xhci_update_ep_ring()
1672 devep->ep_sctx_trbs[streamid].ringaddr = ringaddr & ~0xFUL; in pci_xhci_update_ep_ring()
1673 devep->ep_sctx_trbs[streamid].ccs = ccs & 0x1; in pci_xhci_update_ep_ring()
1674 ep_ctx->qwEpCtx2 = (ep_ctx->qwEpCtx2 & ~0x1) | (ccs & 0x1); in pci_xhci_update_ep_ring()
1676 DPRINTF(("xhci update ep-ring stream %d, addr %lx", in pci_xhci_update_ep_ring()
1677 streamid, devep->ep_sctx[streamid].qwSctx0)); in pci_xhci_update_ep_ring()
1679 devep->ep_ringaddr = ringaddr & ~0xFUL; in pci_xhci_update_ep_ring()
1680 devep->ep_ccs = ccs & 0x1; in pci_xhci_update_ep_ring()
1681 devep->ep_tr = XHCI_GADDR(sc, ringaddr & ~0xFUL); in pci_xhci_update_ep_ring()
1682 ep_ctx->qwEpCtx2 = (ringaddr & ~0xFUL) | (ccs & 0x1); in pci_xhci_update_ep_ring()
1684 DPRINTF(("xhci update ep-ring, addr %lx", in pci_xhci_update_ep_ring()
1685 (devep->ep_ringaddr | devep->ep_ccs))); in pci_xhci_update_ep_ring()
1713 ep_ctx->dwEpCtx0 = FIELD_REPLACE( in pci_xhci_try_usb_xfer()
1714 ep_ctx->dwEpCtx0, XHCI_ST_EPCTX_RUNNING, 0x7, 0); in pci_xhci_try_usb_xfer()
1719 xfer = devep->ep_xfer; in pci_xhci_try_usb_xfer()
1732 if (dev->dev_ue->ue_data != NULL) { in pci_xhci_try_usb_xfer()
1733 err = dev->dev_ue->ue_data(dev->dev_sc, xfer, in pci_xhci_try_usb_xfer()
1734 epid & 0x1 ? USB_XFER_IN : USB_XFER_OUT, epid/2); in pci_xhci_try_usb_xfer()
1736 if (USB_DATA_GET_ERRCODE(&xfer->data[xfer->head]) == in pci_xhci_try_usb_xfer()
1774 ep_ctx->dwEpCtx0 = FIELD_REPLACE(ep_ctx->dwEpCtx0, in pci_xhci_handle_transfer()
1777 xfer = devep->ep_xfer; in pci_xhci_handle_transfer()
1791 trbflags = trb->dwTrb3; in pci_xhci_handle_transfer()
1796 DPRINTF(("Cycle-bit changed trbflags %x, ccs %x", in pci_xhci_handle_transfer()
1805 if (trb->dwTrb3 & XHCI_TRB_3_TC_BIT) in pci_xhci_handle_transfer()
1810 xfer_block->processed = 1; in pci_xhci_handle_transfer()
1815 XHCI_TRB_2_BYTES_GET(trb->dwTrb2) != 8) { in pci_xhci_handle_transfer()
1822 val = trb->qwTrb0; in pci_xhci_handle_transfer()
1823 if (!xfer->ureq) in pci_xhci_handle_transfer()
1824 xfer->ureq = malloc( in pci_xhci_handle_transfer()
1826 memcpy(xfer->ureq, &val, in pci_xhci_handle_transfer()
1831 xfer_block->processed = 1; in pci_xhci_handle_transfer()
1847 &trb->qwTrb0 : XHCI_GADDR(sc, trb->qwTrb0)), in pci_xhci_handle_transfer()
1848 trb->dwTrb2 & 0x1FFFF, (void *)addr, ccs); in pci_xhci_handle_transfer()
1859 xfer_block->processed = 1; in pci_xhci_handle_transfer()
1866 xfer_block->processed = 1; in pci_xhci_handle_transfer()
1883 xfer_block->trbnext = addr; in pci_xhci_handle_transfer()
1884 xfer_block->streamid = streamid; in pci_xhci_handle_transfer()
1901 DPRINTF(("pci_xhci[%d]: xfer->ndata %u", __LINE__, xfer->ndata)); in pci_xhci_handle_transfer()
1903 if (xfer->ndata <= 0) in pci_xhci_handle_transfer()
1909 if (dev->dev_ue->ue_request != NULL) in pci_xhci_handle_transfer()
1910 usberr = dev->dev_ue->ue_request(dev->dev_sc, xfer); in pci_xhci_handle_transfer()
1980 devep = &dev->eps[epid]; in pci_xhci_device_doorbell()
1985 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_device_doorbell()
1990 epid, ep_ctx->dwEpCtx0, ep_ctx->dwEpCtx1, ep_ctx->qwEpCtx2, in pci_xhci_device_doorbell()
1991 ep_ctx->dwEpCtx4)); in pci_xhci_device_doorbell()
1993 if (ep_ctx->qwEpCtx2 == 0) in pci_xhci_device_doorbell()
1997 if (devep->ep_xfer->ndata > 0) { in pci_xhci_device_doorbell()
1999 USB_DATA_XFER_LOCK(devep->ep_xfer); in pci_xhci_device_doorbell()
2003 USB_DATA_XFER_UNLOCK(devep->ep_xfer); in pci_xhci_device_doorbell()
2009 if (devep->ep_MaxPStreams != 0) { in pci_xhci_device_doorbell()
2025 sctx_tr = &devep->ep_sctx_trbs[streamid]; in pci_xhci_device_doorbell()
2026 ringaddr = sctx_tr->ringaddr; in pci_xhci_device_doorbell()
2027 ccs = sctx_tr->ccs; in pci_xhci_device_doorbell()
2028 trb = XHCI_GADDR(sc, sctx_tr->ringaddr & ~0xFUL); in pci_xhci_device_doorbell()
2030 streamid, ep_ctx->qwEpCtx2 & XHCI_TRB_3_CYCLE_BIT, in pci_xhci_device_doorbell()
2031 trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT)); in pci_xhci_device_doorbell()
2037 ringaddr = devep->ep_ringaddr; in pci_xhci_device_doorbell()
2038 ccs = devep->ep_ccs; in pci_xhci_device_doorbell()
2039 trb = devep->ep_tr; in pci_xhci_device_doorbell()
2041 ep_ctx->qwEpCtx2 & XHCI_TRB_3_CYCLE_BIT, in pci_xhci_device_doorbell()
2042 trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT)); in pci_xhci_device_doorbell()
2045 if (XHCI_TRB_3_TYPE_GET(trb->dwTrb3) == 0) { in pci_xhci_device_doorbell()
2047 ep_ctx->qwEpCtx2, devep->ep_ringaddr, epid)); in pci_xhci_device_doorbell()
2060 offset = (offset - sc->dboff) / sizeof(uint32_t); in pci_xhci_dbregs_write()
2072 else if (sc->portregs != NULL) in pci_xhci_dbregs_write()
2083 offset -= sc->rtsoff; in pci_xhci_rtsregs_write()
2093 offset -= 0x20; /* start of intrreg */ in pci_xhci_rtsregs_write()
2095 rts = &sc->rtsregs; in pci_xhci_rtsregs_write()
2100 rts->intrreg.iman &= ~XHCI_IMAN_INTR_PEND; in pci_xhci_rtsregs_write()
2101 rts->intrreg.iman = (value & XHCI_IMAN_INTR_ENA) | in pci_xhci_rtsregs_write()
2102 (rts->intrreg.iman & XHCI_IMAN_INTR_PEND); in pci_xhci_rtsregs_write()
2110 rts->intrreg.imod = value; in pci_xhci_rtsregs_write()
2114 rts->intrreg.erstsz = value & 0xFFFF; in pci_xhci_rtsregs_write()
2119 rts->intrreg.erstba = MASK_64_HI(sc->rtsregs.intrreg.erstba) | in pci_xhci_rtsregs_write()
2125 rts->intrreg.erstba = (value << 32) | in pci_xhci_rtsregs_write()
2126 MASK_64_LO(sc->rtsregs.intrreg.erstba); in pci_xhci_rtsregs_write()
2128 rts->erstba_p = XHCI_GADDR(sc, in pci_xhci_rtsregs_write()
2129 sc->rtsregs.intrreg.erstba & ~0x3FUL); in pci_xhci_rtsregs_write()
2131 rts->erst_p = XHCI_GADDR(sc, in pci_xhci_rtsregs_write()
2132 sc->rtsregs.erstba_p->qwEvrsTablePtr & ~0x3FUL); in pci_xhci_rtsregs_write()
2134 rts->er_enq_idx = 0; in pci_xhci_rtsregs_write()
2135 rts->er_events_cnt = 0; in pci_xhci_rtsregs_write()
2138 rts->erstba_p, in pci_xhci_rtsregs_write()
2139 rts->erstba_p->qwEvrsTablePtr, in pci_xhci_rtsregs_write()
2140 rts->erstba_p->dwEvrsTableSize)); in pci_xhci_rtsregs_write()
2145 rts->intrreg.erdp = in pci_xhci_rtsregs_write()
2146 MASK_64_HI(sc->rtsregs.intrreg.erdp) | in pci_xhci_rtsregs_write()
2147 (rts->intrreg.erdp & XHCI_ERDP_LO_BUSY) | in pci_xhci_rtsregs_write()
2150 rts->intrreg.erdp &= ~XHCI_ERDP_LO_BUSY; in pci_xhci_rtsregs_write()
2151 rts->intrreg.iman &= ~XHCI_IMAN_INTR_PEND; in pci_xhci_rtsregs_write()
2154 rts->er_deq_seg = XHCI_ERDP_LO_SINDEX(value); in pci_xhci_rtsregs_write()
2160 rts->intrreg.erdp = (value << 32) | in pci_xhci_rtsregs_write()
2161 MASK_64_LO(sc->rtsregs.intrreg.erdp); in pci_xhci_rtsregs_write()
2163 if (rts->er_events_cnt > 0) { in pci_xhci_rtsregs_write()
2167 erdp = rts->intrreg.erdp & ~0xF; in pci_xhci_rtsregs_write()
2168 erdp_i = (erdp - rts->erstba_p->qwEvrsTablePtr) / in pci_xhci_rtsregs_write()
2171 if (erdp_i <= rts->er_enq_idx) in pci_xhci_rtsregs_write()
2172 rts->er_events_cnt = rts->er_enq_idx - erdp_i; in pci_xhci_rtsregs_write()
2174 rts->er_events_cnt = in pci_xhci_rtsregs_write()
2175 rts->erstba_p->dwEvrsTableSize - in pci_xhci_rtsregs_write()
2176 (erdp_i - rts->er_enq_idx); in pci_xhci_rtsregs_write()
2179 erdp, rts->er_events_cnt)); in pci_xhci_rtsregs_write()
2198 if (sc->portregs == NULL) in pci_xhci_portregs_read()
2201 port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ; in pci_xhci_portregs_read()
2202 offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ; in pci_xhci_portregs_read()
2215 reg = portregs->portsc; in pci_xhci_portregs_read()
2218 reg = portregs->portpmsc; in pci_xhci_portregs_read()
2221 reg = portregs->portli; in pci_xhci_portregs_read()
2224 reg = portregs->porthlpmc; in pci_xhci_portregs_read()
2233 DPRINTF(("pci_xhci: portregs read offset 0x%lx port %u -> 0x%x", in pci_xhci_portregs_read()
2243 offset -= XHCI_CAPLEN; in pci_xhci_hostop_write()
2251 sc->opregs.usbcmd = pci_xhci_usbcmd_write(sc, value & 0x3F0F); in pci_xhci_hostop_write()
2256 sc->opregs.usbsts &= ~(value & in pci_xhci_hostop_write()
2266 sc->opregs.dnctrl = value & 0xFFFF; in pci_xhci_hostop_write()
2270 if (sc->opregs.crcr & XHCI_CRCR_LO_CRR) { in pci_xhci_hostop_write()
2271 sc->opregs.crcr &= ~(XHCI_CRCR_LO_CS|XHCI_CRCR_LO_CA); in pci_xhci_hostop_write()
2272 sc->opregs.crcr |= value & in pci_xhci_hostop_write()
2275 sc->opregs.crcr = MASK_64_HI(sc->opregs.crcr) | in pci_xhci_hostop_write()
2281 if (!(sc->opregs.crcr & XHCI_CRCR_LO_CRR)) { in pci_xhci_hostop_write()
2282 sc->opregs.crcr = MASK_64_LO(sc->opregs.crcr) | in pci_xhci_hostop_write()
2285 sc->opregs.cr_p = XHCI_GADDR(sc, in pci_xhci_hostop_write()
2286 sc->opregs.crcr & ~0xF); in pci_xhci_hostop_write()
2289 if (sc->opregs.crcr & XHCI_CRCR_LO_CS) { in pci_xhci_hostop_write()
2293 if (sc->opregs.crcr & XHCI_CRCR_LO_CA) { in pci_xhci_hostop_write()
2300 sc->opregs.dcbaap = MASK_64_HI(sc->opregs.dcbaap) | in pci_xhci_hostop_write()
2305 sc->opregs.dcbaap = MASK_64_LO(sc->opregs.dcbaap) | in pci_xhci_hostop_write()
2307 sc->opregs.dcbaa_p = XHCI_GADDR(sc, sc->opregs.dcbaap & ~0x3FUL); in pci_xhci_hostop_write()
2310 sc->opregs.dcbaap, (uint64_t)sc->opregs.dcbaa_p)); in pci_xhci_hostop_write()
2314 sc->opregs.config = value & 0x03FF; in pci_xhci_hostop_write()
2332 sc = pi->pi_arg; in pci_xhci_write()
2337 pthread_mutex_lock(&sc->mtx); in pci_xhci_write()
2339 WPRINTF(("pci_xhci: write RO-CAPs offset %ld", offset)); in pci_xhci_write()
2340 else if (offset < sc->dboff) in pci_xhci_write()
2342 else if (offset < sc->rtsoff) in pci_xhci_write()
2344 else if (offset < sc->regsend) in pci_xhci_write()
2349 pthread_mutex_unlock(&sc->mtx); in pci_xhci_write()
2359 value = sc->caplength; in pci_xhci_hostcap_read()
2363 value = sc->hcsparams1; in pci_xhci_hostcap_read()
2367 value = sc->hcsparams2; in pci_xhci_hostcap_read()
2371 value = sc->hcsparams3; in pci_xhci_hostcap_read()
2375 value = sc->hccparams1; in pci_xhci_hostcap_read()
2379 value = sc->dboff; in pci_xhci_hostcap_read()
2383 value = sc->rtsoff; in pci_xhci_hostcap_read()
2387 value = sc->hccparams2; in pci_xhci_hostcap_read()
2395 DPRINTF(("pci_xhci: hostcap read offset 0x%lx -> 0x%lx", in pci_xhci_hostcap_read()
2406 offset = (offset - XHCI_CAPLEN); in pci_xhci_hostop_read()
2410 value = sc->opregs.usbcmd; in pci_xhci_hostop_read()
2414 value = sc->opregs.usbsts; in pci_xhci_hostop_read()
2418 value = sc->opregs.pgsz; in pci_xhci_hostop_read()
2422 value = sc->opregs.dnctrl; in pci_xhci_hostop_read()
2426 value = sc->opregs.crcr & XHCI_CRCR_LO_CRR; in pci_xhci_hostop_read()
2434 value = sc->opregs.dcbaap & 0xFFFFFFFF; in pci_xhci_hostop_read()
2438 value = (sc->opregs.dcbaap >> 32) & 0xFFFFFFFF; in pci_xhci_hostop_read()
2442 value = sc->opregs.config; in pci_xhci_hostop_read()
2455 DPRINTF(("pci_xhci: hostop read offset 0x%lx -> 0x%lx", in pci_xhci_hostop_read()
2474 offset -= sc->rtsoff; in pci_xhci_rtsregs_read()
2478 value = sc->rtsregs.mfindex; in pci_xhci_rtsregs_read()
2483 offset -= 0x20; in pci_xhci_rtsregs_read()
2486 assert(offset < sizeof(sc->rtsregs.intrreg)); in pci_xhci_rtsregs_read()
2488 p = &sc->rtsregs.intrreg.iman; in pci_xhci_rtsregs_read()
2493 DPRINTF(("pci_xhci: rtsregs read offset 0x%lx -> 0x%x", in pci_xhci_rtsregs_read()
2504 offset -= sc->regsend; in pci_xhci_xecp_read()
2509 /* rev major | rev minor | next-cap | cap-id */ in pci_xhci_xecp_read()
2517 /* psic | proto-defined | compat # | compat offset */ in pci_xhci_xecp_read()
2518 value = ((XHCI_MAX_DEVS/2) << 8) | sc->usb2_port_start; in pci_xhci_xecp_read()
2523 /* rev major | rev minor | next-cap | cap-id */ in pci_xhci_xecp_read()
2531 /* psic | proto-defined | compat # | compat offset */ in pci_xhci_xecp_read()
2532 value = ((XHCI_MAX_DEVS/2) << 8) | sc->usb3_port_start; in pci_xhci_xecp_read()
2541 DPRINTF(("pci_xhci: xecp read offset 0x%lx -> 0x%x", in pci_xhci_xecp_read()
2554 sc = pi->pi_arg; in pci_xhci_read()
2558 pthread_mutex_lock(&sc->mtx); in pci_xhci_read()
2561 else if (offset < sc->dboff) in pci_xhci_read()
2563 else if (offset < sc->rtsoff) in pci_xhci_read()
2565 else if (offset < sc->regsend) in pci_xhci_read()
2567 else if (offset < (sc->regsend + 4*32)) in pci_xhci_read()
2574 pthread_mutex_unlock(&sc->mtx); in pci_xhci_read()
2580 case 2: in pci_xhci_read()
2606 port->portsc &= ~(XHCI_PS_PLS_MASK | XHCI_PS_PR | XHCI_PS_PRC); in pci_xhci_reset_port()
2607 port->portsc |= XHCI_PS_PED | in pci_xhci_reset_port()
2608 XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); in pci_xhci_reset_port()
2610 if (warm && dev->dev_ue->ue_usbver == 3) { in pci_xhci_reset_port()
2611 port->portsc |= XHCI_PS_WRC; in pci_xhci_reset_port()
2614 if ((port->portsc & XHCI_PS_PRC) == 0) { in pci_xhci_reset_port()
2615 port->portsc |= XHCI_PS_PRC; in pci_xhci_reset_port()
2637 port->portsc = XHCI_PS_CCS | /* connected */ in pci_xhci_init_port()
2640 if (dev->dev_ue->ue_usbver == 2) { in pci_xhci_init_port()
2641 port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) | in pci_xhci_init_port()
2642 XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); in pci_xhci_init_port()
2644 port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_U0) | in pci_xhci_init_port()
2646 XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); in pci_xhci_init_port()
2649 DPRINTF(("Init port %d 0x%x", portn, port->portsc)); in pci_xhci_init_port()
2651 port->portsc = XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP; in pci_xhci_init_port()
2652 DPRINTF(("Init empty port %d 0x%x", portn, port->portsc)); in pci_xhci_init_port()
2672 /* HW endpoint contexts are 0-15; convert to epid based on dir */ in pci_xhci_dev_intr()
2673 epid = (epid * 2) + (dir_in ? 1 : 0); in pci_xhci_dev_intr()
2677 dev = hci->hci_sc; in pci_xhci_dev_intr()
2678 sc = dev->xsc; in pci_xhci_dev_intr()
2681 if (sc->rtsregs.erstba_p == NULL || in pci_xhci_dev_intr()
2682 (sc->opregs.usbcmd & XHCI_CMD_RS) == 0 || in pci_xhci_dev_intr()
2683 dev->dev_ctx == NULL) in pci_xhci_dev_intr()
2686 p = XHCI_PORTREG_PTR(sc, hci->hci_port); in pci_xhci_dev_intr()
2689 if (XHCI_PS_PLS_GET(p->portsc) == 3) { in pci_xhci_dev_intr()
2690 p->portsc &= ~XHCI_PS_PLS_MASK; in pci_xhci_dev_intr()
2691 p->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_RESUME); in pci_xhci_dev_intr()
2692 if ((p->portsc & XHCI_PS_PLC) != 0) in pci_xhci_dev_intr()
2695 p->portsc |= XHCI_PS_PLC; in pci_xhci_dev_intr()
2697 pci_xhci_set_evtrb(&evtrb, hci->hci_port, in pci_xhci_dev_intr()
2704 dev_ctx = dev->dev_ctx; in pci_xhci_dev_intr()
2705 ep_ctx = &dev_ctx->ctx_ep[epid]; in pci_xhci_dev_intr()
2706 if ((ep_ctx->dwEpCtx0 & 0x7) == XHCI_ST_EPCTX_DISABLED) { in pci_xhci_dev_intr()
2714 pci_xhci_device_doorbell(sc, hci->hci_port, epid, 0); in pci_xhci_dev_intr()
2724 DPRINTF(("xhci device event port %d", hci->hci_port)); in pci_xhci_dev_event()
2791 usb3_port = sc->usb3_port_start; in pci_xhci_parse_devices()
2792 usb2_port = sc->usb2_port_start; in pci_xhci_parse_devices()
2794 sc->devices = calloc(XHCI_MAX_DEVS, sizeof(struct pci_xhci_dev_emu *)); in pci_xhci_parse_devices()
2795 sc->slots = calloc(XHCI_MAX_SLOTS, sizeof(struct pci_xhci_dev_emu *)); in pci_xhci_parse_devices()
2805 if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS/2) || in pci_xhci_parse_devices()
2806 usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS/2)) { in pci_xhci_parse_devices()
2807 WPRINTF(("pci_xhci max number of USB 2 or 3 " in pci_xhci_parse_devices()
2808 "devices reached, max %d", XHCI_MAX_DEVS/2)); in pci_xhci_parse_devices()
2849 dev->xsc = sc; in pci_xhci_parse_devices()
2850 dev->hci.hci_sc = dev; in pci_xhci_parse_devices()
2851 dev->hci.hci_intr = pci_xhci_dev_intr; in pci_xhci_parse_devices()
2852 dev->hci.hci_event = pci_xhci_dev_event; in pci_xhci_parse_devices()
2854 if (ue->ue_usbver == 2) { in pci_xhci_parse_devices()
2855 if (usb2_port == sc->usb2_port_start + in pci_xhci_parse_devices()
2856 XHCI_MAX_DEVS / 2) { in pci_xhci_parse_devices()
2857 WPRINTF(("pci_xhci max number of USB 2 devices " in pci_xhci_parse_devices()
2858 "reached, max %d", XHCI_MAX_DEVS / 2)); in pci_xhci_parse_devices()
2861 dev->hci.hci_port = usb2_port; in pci_xhci_parse_devices()
2864 if (usb3_port == sc->usb3_port_start + in pci_xhci_parse_devices()
2865 XHCI_MAX_DEVS / 2) { in pci_xhci_parse_devices()
2867 "reached, max %d", XHCI_MAX_DEVS / 2)); in pci_xhci_parse_devices()
2870 dev->hci.hci_port = usb3_port; in pci_xhci_parse_devices()
2873 XHCI_DEVINST_PTR(sc, dev->hci.hci_port) = dev; in pci_xhci_parse_devices()
2875 dev->hci.hci_address = 0; in pci_xhci_parse_devices()
2876 devsc = ue->ue_init(&dev->hci, nvl); in pci_xhci_parse_devices()
2881 dev->dev_ue = ue; in pci_xhci_parse_devices()
2882 dev->dev_sc = devsc; in pci_xhci_parse_devices()
2889 sc->portregs = calloc(XHCI_MAX_DEVS, sizeof(struct pci_xhci_portregs)); in pci_xhci_parse_devices()
2905 free(sc->devices); in pci_xhci_parse_devices()
2906 free(sc->slots); in pci_xhci_parse_devices()
2908 return (-1); in pci_xhci_parse_devices()
2924 return (-1); in pci_xhci_init()
2929 pi->pi_arg = sc; in pci_xhci_init()
2930 sc->xsc_pi = pi; in pci_xhci_init()
2932 sc->usb2_port_start = (XHCI_MAX_DEVS/2) + 1; in pci_xhci_init()
2933 sc->usb3_port_start = 1; in pci_xhci_init()
2942 sc->caplength = XHCI_SET_CAPLEN(XHCI_CAPLEN) | in pci_xhci_init()
2944 sc->hcsparams1 = XHCI_SET_HCSP1_MAXPORTS(XHCI_MAX_DEVS) | in pci_xhci_init()
2947 sc->hcsparams2 = XHCI_SET_HCSP2_ERSTMAX(XHCI_ERST_MAX) | in pci_xhci_init()
2949 sc->hcsparams3 = 0; /* no latency */ in pci_xhci_init()
2950 sc->hccparams1 = XHCI_SET_HCCP1_AC64(1) | /* 64-bit addrs */ in pci_xhci_init()
2951 XHCI_SET_HCCP1_NSS(1) | /* no 2nd-streams */ in pci_xhci_init()
2954 sc->hccparams2 = XHCI_SET_HCCP2_LEC(1) | in pci_xhci_init()
2956 sc->dboff = XHCI_SET_DOORBELL(XHCI_CAPLEN + XHCI_PORTREGS_START + in pci_xhci_init()
2959 /* dboff must be 32-bit aligned */ in pci_xhci_init()
2960 if (sc->dboff & 0x3) in pci_xhci_init()
2961 sc->dboff = (sc->dboff + 0x3) & ~0x3; in pci_xhci_init()
2963 /* rtsoff must be 32-bytes aligned */ in pci_xhci_init()
2964 sc->rtsoff = XHCI_SET_RTSOFFSET(sc->dboff + (XHCI_MAX_SLOTS+1) * 32); in pci_xhci_init()
2965 if (sc->rtsoff & 0x1F) in pci_xhci_init()
2966 sc->rtsoff = (sc->rtsoff + 0x1F) & ~0x1F; in pci_xhci_init()
2968 DPRINTF(("pci_xhci dboff: 0x%x, rtsoff: 0x%x", sc->dboff, in pci_xhci_init()
2969 sc->rtsoff)); in pci_xhci_init()
2971 sc->opregs.usbsts = XHCI_STS_HCH; in pci_xhci_init()
2972 sc->opregs.pgsz = XHCI_PAGESIZE_4K; in pci_xhci_init()
2976 sc->regsend = sc->rtsoff + 0x20 + 32; /* only 1 intrpter */ in pci_xhci_init()
2980 * value of xecp field is 32-bit offset. in pci_xhci_init()
2982 sc->hccparams1 |= XHCI_SET_HCCP1_XECP(sc->regsend/4); in pci_xhci_init()
2994 pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, sc->regsend + 4*32); in pci_xhci_init()
2995 DPRINTF(("pci_xhci pci_emu_alloc: %d", sc->regsend + 4*32)); in pci_xhci_init()
3000 pthread_mutex_init(&sc->mtx, NULL); in pci_xhci_init()