Changeset 107924 in vbox
- Timestamp:
- Jan 23, 2025 4:42:56 PM (2 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DevXHCI.cpp
r106061 r107924 315 315 316 316 /** Convert a zero-based index to a 1-based ID. */ 317 #define IDX_TO_ID(a) ( a + 1)317 #define IDX_TO_ID(a) (uint8_t)(a + 1) 318 318 /** Convert a 1-based ID to a zero-based index. */ 319 #define ID_TO_IDX(a) ( a - 1)319 #define ID_TO_IDX(a) (uint8_t)(a - 1) 320 320 321 321 /** PCI device related constants. */ … … 434 434 /** @name xHCI Extended capability types. 435 435 * @{ */ 436 #define XHCI_XCP_USB_LEGACY 1 437 #define XHCI_XCP_PROTOCOL 2 438 #define XHCI_XCP_EXT_PM 3 439 #define XHCI_XCP_IOVIRT 4 440 #define XHCI_XCP_MSI 5 441 #define XHCI_XCP_LOCAL_MEM 6 442 #define XHCI_XCP_USB_DEBUG 10 443 #define XHCI_XCP_EXT_MSI 17 436 #define XHCI_XCP_USB_LEGACY 1u /**< USB legacy support. */ 437 #define XHCI_XCP_PROTOCOL 2u /**< Protocols supported by ports. */ 438 #define XHCI_XCP_EXT_PM 3u /**< Extended power management (non-PCI). */ 439 #define XHCI_XCP_IOVIRT 4u /**< Hardware xHCI virtualization support. */ 440 #define XHCI_XCP_MSI 5u /**< Message interrupts (non-PCI). */ 441 #define XHCI_XCP_LOCAL_MEM 6u /**< Local memory (for debug support). */ 442 #define XHCI_XCP_USB_DEBUG 10u /**< USB debug capability. */ 443 #define XHCI_XCP_EXT_MSI 17u /**< MSI-X (non-PCI). */ 444 444 /** @} */ 445 445 … … 614 614 /** @name Event Ring Deqeue Pointer Register (ERDP) bits 615 615 * @{ */ 616 #define XHCI_ERDP_DESI_MASK 0x00000007/**< RW - Dequeue ERST Segment Index */617 #define XHCI_ERDP_EHB RT_BIT (3)/**< RW1C - Event Handler Busy */616 #define XHCI_ERDP_DESI_MASK UINT64_C(7) /**< RW - Dequeue ERST Segment Index */ 617 #define XHCI_ERDP_EHB RT_BIT_64(3) /**< RW1C - Event Handler Busy */ 618 618 #define XHCI_ERDP_ADDR_MASK UINT64_C(0xFFFFFFFFFFFFFFF0) /**< RW - ERDP address mask */ 619 619 /** @} */ … … 1891 1891 1892 1892 /** Query the number of configured USB2 ports. */ 1893 #define XHCI_NDP_USB2(a_pThisCC) (( unsigned)(a_pThisCC)->RootHub2.cPortsImpl)1893 #define XHCI_NDP_USB2(a_pThisCC) ((a_pThisCC)->RootHub2.cPortsImpl) 1894 1894 1895 1895 /** Query the number of configured USB3 ports. */ 1896 #define XHCI_NDP_USB3(a_pThisCC) (( unsigned)(a_pThisCC)->RootHub3.cPortsImpl)1896 #define XHCI_NDP_USB3(a_pThisCC) ((a_pThisCC)->RootHub3.cPortsImpl) 1897 1897 1898 1898 /** Query the total number of configured ports. */ … … 1910 1910 1911 1911 /** Build a Protocol extended capability. */ 1912 static uint32_t xhciR3BuildProtocolCaps(uint8_t *pbCap, uint32_t cbMax, int cPorts, intnPortOfs, int ver)1912 static uint32_t xhciR3BuildProtocolCaps(uint8_t *pbCap, uint32_t cbMax, unsigned cPorts, unsigned nPortOfs, int ver) 1913 1913 { 1914 1914 uint32_t *pu32Cap = (uint32_t *)pbCap; … … 2815 2815 { 2816 2816 XHCI_CTX_XFER_COMPLETE *pCtx = (XHCI_CTX_XFER_COMPLETE *)pvContext; 2817 int rc;2818 2817 unsigned uXferLen; 2819 2818 unsigned uResidue; … … 2874 2873 if (pXferTRB->norm.ioc || (pXferTRB->norm.isp && uResidue)) 2875 2874 { 2876 rc =xhciR3PostXferEvent(pDevIns, pThis, pXferTRB->norm.int_tgt, uResidue, cc,2877 2875 xhciR3PostXferEvent(pDevIns, pThis, pXferTRB->norm.int_tgt, uResidue, cc, 2876 pCtx->uSlotID, pCtx->uEpDCI, GCPhysXfrTRB, pXferTRB->norm.bei, false); 2878 2877 } 2879 2878 break; … … 2881 2880 if (pXferTRB->evtd.ioc) 2882 2881 { 2883 rc =xhciR3PostXferEvent(pDevIns, pThis, pXferTRB->evtd.int_tgt, pCtx->uEDTLA, pCtx->uLastCC,2884 2882 xhciR3PostXferEvent(pDevIns, pThis, pXferTRB->evtd.int_tgt, pCtx->uEDTLA, pCtx->uLastCC, 2883 pCtx->uSlotID, pCtx->uEpDCI, pXferTRB->evtd.evt_data, pXferTRB->evtd.bei, true); 2885 2884 } 2886 2885 /* Clear the EDTLA. */ … … 2931 2930 bool fInFlight; 2932 2931 bool fContinue = true; 2933 int rc;2934 2932 unsigned cTrbs = 0; 2935 2933 … … 2974 2972 pEpCtx->trep = pEpCtx->trdp; 2975 2973 if (xfer.link.ioc) 2976 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.link.int_tgt, 0, XHCI_TCC_SUCCESS, uSlotID, uEpDCI,2977 2974 xhciR3PostXferEvent(pDevIns, pThis, xfer.link.int_tgt, 0, XHCI_TCC_SUCCESS, uSlotID, uEpDCI, 2975 GCPhysXfrTRB, false, false); 2978 2976 break; 2979 2977 case XHCI_TRB_NOOP_XFER: … … 2986 2984 pEpCtx->trep += sizeof(XHCI_XFER_TRB); 2987 2985 if (xfer.nop.ioc) 2988 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.nop.int_tgt, 0, XHCI_TCC_SUCCESS, uSlotID, uEpDCI,2989 2986 xhciR3PostXferEvent(pDevIns, pThis, xfer.nop.int_tgt, 0, XHCI_TCC_SUCCESS, uSlotID, uEpDCI, 2987 GCPhysXfrTRB, false, false); 2990 2988 break; 2991 2989 default: … … 3011 3009 /* Get out of the loop. */ 3012 3010 fContinue = false; 3013 rc = VERR_NOT_SUPPORTED; /* No good error code really... */3014 3011 } 3015 3012 } while (fContinue); … … 3043 3040 XHCI_XFER_TRB xfer; 3044 3041 RTGCPHYS GCPhysXfrTRB; 3045 int rc;3046 3042 unsigned uResidue = 0; 3047 3043 uint8_t uSlotID = pUrb->pHci->uSlotID; … … 3120 3116 ep_ctx.ep_state = XHCI_EPST_HALTED; 3121 3117 cc = XHCI_TCC_STALL; 3122 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc,3123 3118 xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc, 3119 uSlotID, uEpDCI, GCPhysXfrTRB, false, false); 3124 3120 break; 3125 3121 case VUSBSTATUS_DNR: … … 3129 3125 ep_ctx.ep_state = XHCI_EPST_HALTED; 3130 3126 cc = XHCI_TCC_USB_XACT_ERR; 3131 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc,3132 3127 xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc, 3128 uSlotID, uEpDCI, GCPhysXfrTRB, false, false); 3133 3129 break; 3134 3130 case VUSBSTATUS_CRC: /// @todo Separate status for canceling?! 3135 3131 ep_ctx.ep_state = XHCI_EPST_HALTED; 3136 3132 cc = XHCI_TCC_USB_XACT_ERR; 3137 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc,3138 3133 xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc, 3134 uSlotID, uEpDCI, GCPhysXfrTRB, false, false); 3139 3135 3140 3136 /* NB: The TRDP is *not* advanced and TREP is reset. */ … … 3148 3144 ep_ctx.ep_state = XHCI_EPST_HALTED; 3149 3145 cc = XHCI_TCC_DATA_BUF_ERR; 3150 rc =xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc,3151 3146 xhciR3PostXferEvent(pDevIns, pThis, xfer.gen.int_tgt, uResidue, cc, 3147 uSlotID, uEpDCI, GCPhysXfrTRB, false, false); 3152 3148 break; 3153 3149 default: … … 3493 3489 uint64_t uTREP; 3494 3490 PVUSBURB pUrb; 3495 u nsignedcIsoPackets;3491 uint8_t cIsoPackets; 3496 3492 uint32_t cbPktMax; 3497 3493 … … 3806 3802 bool dcs; 3807 3803 bool fContinue = true; 3808 int rc ;3804 int rc = VINF_SUCCESS; 3809 3805 unsigned cTrbs = 0; 3810 3806 … … 4014 4010 xhciR3WriteBackEp(pDevIns, pThis, uSlotID, uDBTarget, &ep_ctx); 4015 4011 } 4016 return VINF_SUCCESS;4012 return rc; 4017 4013 } 4018 4014 … … 5048 5044 /* Reset the given endpoint. */ 5049 5045 Log(("Reset Endpoint: slot ID %u, EP ID %u, TSP=%u\n", pCmd->rse.slot_id, pCmd->rse.ep_id, pCmd->rse.tsp)); 5050 cc = XHCI_TCC_SUCCESS;5051 5046 slot = ID_TO_IDX(pCmd->rse.slot_id); 5052 5047 if ((slot >= RT_ELEMENTS(pThis->aSlotState)) || (pThis->aSlotState[slot] == XHCI_DEVSLOT_EMPTY)) … … 5061 5056 /* Stop the given endpoint. */ 5062 5057 Log(("Stop Endpoint: slot ID %u, EP ID %u, SP=%u\n", pCmd->stp.slot_id, pCmd->stp.ep_id, pCmd->stp.sp)); 5063 cc = XHCI_TCC_SUCCESS;5064 5058 slot = ID_TO_IDX(pCmd->stp.slot_id); 5065 5059 if ((slot >= RT_ELEMENTS(pThis->aSlotState)) || (pThis->aSlotState[slot] == XHCI_DEVSLOT_EMPTY)) … … 5074 5068 /* Set TR Dequeue Pointer. */ 5075 5069 Log(("Set TRDP: slot ID %u, EP ID %u, TRDP=%RX64\n", pCmd->stdp.slot_id, pCmd->stdp.ep_id, pCmd->stdp.tr_dqp)); 5076 cc = XHCI_TCC_SUCCESS;5077 5070 slot = ID_TO_IDX(pCmd->stdp.slot_id); 5078 5071 if ((slot >= RT_ELEMENTS(pThis->aSlotState)) || (pThis->aSlotState[slot] == XHCI_DEVSLOT_EMPTY)) … … 5087 5080 /* Reset a device. */ 5088 5081 Log(("Reset Device: slot ID %u\n", pCmd->rsd.slot_id)); 5089 cc = XHCI_TCC_SUCCESS;5090 5082 slot = ID_TO_IDX(pCmd->rsd.slot_id); 5091 5083 if ((slot >= RT_ELEMENTS(pThis->aSlotState)) || (pThis->aSlotState[slot] == XHCI_DEVSLOT_EMPTY)) … … 5100 5092 /* Get port bandwidth. */ 5101 5093 Log(("Get Port Bandwidth: Dev Speed %u, Hub Slot ID %u, Context=%RX64\n", pCmd->gpbw.spd, pCmd->gpbw.slot_id, pCmd->gpbw.pbctx_ptr)); 5102 cc = XHCI_TCC_SUCCESS;5103 5094 if (pCmd->gpbw.slot_id) 5104 5095 cc = XHCI_TCC_PARM_ERR; /* Potential undefined behavior, see 4.6.15. */ … … 5559 5550 * @returns true if device was connected and the flag was cleared. 5560 5551 */ 5561 static bool xhciR3RhPortSetIfConnected(PXHCI pThis, intiPort, uint32_t fValue)5552 static bool xhciR3RhPortSetIfConnected(PXHCI pThis, unsigned iPort, uint32_t fValue) 5562 5553 { 5563 5554 /* … … 5948 5939 Log(("Unknown USBCMD bits %#x are set!\n", val & ~XHCI_CMD_MASK)); 5949 5940 5950 uint32_t old_cmd = pThis->cmd; 5941 5942 /* First deal with resets. These must be done in R3 and will initialize 5943 * the USBCMD register. 5944 */ 5945 if (val & (XHCI_CMD_HCRST | XHCI_CMD_LCRST)) 5946 { 5951 5947 #ifdef IN_RING3 5952 pThis->cmd = val; 5953 #endif 5954 5955 if (val & XHCI_CMD_HCRST) 5956 { 5957 #ifdef IN_RING3 5958 LogRel(("xHCI: Hardware reset\n")); 5959 xhciR3DoReset(pThis, pThisCC, XHCI_USB_RESET, true /* reset devices */); 5948 /* NB: xhciR3DoReset() overwrites pThis->cmd */ 5949 if (val & XHCI_CMD_HCRST) 5950 { 5951 LogRel(("xHCI: Hardware reset\n")); 5952 xhciR3DoReset(pThis, pThisCC, XHCI_USB_RESET, true /* reset devices */); 5953 } 5954 else if (val & XHCI_CMD_LCRST) 5955 { 5956 LogRel(("xHCI: Software reset\n")); 5957 xhciR3DoReset(pThis, pThisCC, XHCI_USB_SUSPEND, false /* N/A */); 5958 } 5959 else 5960 Assert(0); 5961 5962 return VINF_SUCCESS; 5960 5963 #else 5961 5964 return VINF_IOM_R3_MMIO_WRITE; 5962 5965 #endif 5963 5966 } 5964 else if (val & XHCI_CMD_LCRST) 5965 { 5966 #ifdef IN_RING3 5967 LogRel(("xHCI: Software reset\n")); 5968 xhciR3DoReset(pThis, pThisCC, XHCI_USB_SUSPEND, false /* N/A */); 5969 #else 5970 return VINF_IOM_R3_MMIO_WRITE; 5971 #endif 5972 } 5973 else if (pThis->status & XHCI_STATUS_HCE) 5974 { 5975 /* If HCE is set, don't restart the controller. Only a reset 5976 * will clear the HCE bit. 5967 5968 /* Not resetting, handle the remaining bits. */ 5969 if (pThis->status & XHCI_STATUS_HCE) 5970 { 5971 /* If the HCE (HC Error) status bit is set, don't do anything. 5972 * Only a reset will clear the HCE bit. 5977 5973 */ 5978 5974 Log(("xHCI: HCE bit set, ignoring USBCMD register changes!\n")); 5979 pThis->cmd = old_cmd;5980 5975 return VINF_SUCCESS; 5981 5976 } 5982 5977 else 5983 5978 { 5984 /* See what changed and take action on that. First the R/S bit. */ 5985 uint32_t old_state = old_cmd & XHCI_CMD_RS; 5986 uint32_t new_state = val & XHCI_CMD_RS; 5979 /* See what changed and take action on that. First the R/S bit. 5980 * Note that R/S changes must also be done in R3, so we get them 5981 * out of the way first. 5982 * NB: xhciR3BusStop() modifies USBCMD. 5983 */ 5984 uint32_t old_state = pThis->cmd & XHCI_CMD_RS; 5985 uint32_t new_state = val & XHCI_CMD_RS; 5987 5986 5988 5987 if (old_state != new_state) … … 6006 6005 6007 6006 /* Check EWE (Enable MFINDEX Wraparound Event) changes. */ 6008 old_state = old_cmd & XHCI_CMD_EWE;6009 new_state = val & XHCI_CMD_EWE;6007 old_state = pThis->cmd & XHCI_CMD_EWE; 6008 new_state = val & XHCI_CMD_EWE; 6010 6009 6011 6010 if (old_state != new_state) … … 6025 6024 6026 6025 /* INTE transitions need to twiddle interrupts. */ 6027 old_state = old_cmd & XHCI_CMD_INTE;6028 new_state = val & XHCI_CMD_INTE;6026 old_state = pThis->cmd & XHCI_CMD_INTE; 6027 new_state = val & XHCI_CMD_INTE; 6029 6028 if (old_state != new_state) 6030 6029 { … … 6061 6060 } 6062 6061 } 6063 #ifndef IN_RING3 6062 6063 /* Finally update the USBCMD register. */ 6064 6064 pThis->cmd = val; 6065 #endif 6065 6066 6066 return VINF_SUCCESS; 6067 6067 } … … 7889 7889 * Worker for xhciR3Construct that registers a LUN (USB root hub). 7890 7890 */ 7891 static int xhciR3RegisterHub(PPDMDEVINS pDevIns, PXHCIROOTHUBR3 pRh, int iLun, const char *pszDesc)7891 static int xhciR3RegisterHub(PPDMDEVINS pDevIns, PXHCIROOTHUBR3 pRh, uint32_t iLun, const char *pszDesc) 7892 7892 { 7893 7893 int rc = PDMDevHlpDriverAttach(pDevIns, iLun, &pRh->IBase, &pRh->pIBase, pszDesc); 7894 AssertMsgRCReturn(rc, ("Configuration error: Failed to attach root hub driver to LUN #% d! (%Rrc)\n", iLun, rc), rc);7894 AssertMsgRCReturn(rc, ("Configuration error: Failed to attach root hub driver to LUN #%u! (%Rrc)\n", iLun, rc), rc); 7895 7895 7896 7896 pRh->pIRhConn = PDMIBASE_QUERY_INTERFACE(pRh->pIBase, VUSBIROOTHUBCONNECTOR); … … 7917 7917 PXHCICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PXHCICC); 7918 7918 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 7919 uint 32_tcUsb2Ports;7920 uint 32_tcUsb3Ports;7919 uint8_t cUsb2Ports; 7920 uint8_t cUsb3Ports; 7921 7921 int rc; 7922 7922 LogFlow(("xhciR3Construct:\n")); … … 7934 7934 7935 7935 /* Number of USB2 ports option. */ 7936 rc = pHlp->pfnCFGMQueryU 32Def(pCfg, "USB2Ports", &cUsb2Ports, XHCI_NDP_20_DEFAULT);7936 rc = pHlp->pfnCFGMQueryU8Def(pCfg, "USB2Ports", &cUsb2Ports, XHCI_NDP_20_DEFAULT); 7937 7937 if (RT_FAILURE(rc)) 7938 7938 return PDMDEV_SET_ERROR(pDevIns, rc, … … 7945 7945 7946 7946 /* Number of USB3 ports option. */ 7947 rc = pHlp->pfnCFGMQueryU 32Def(pCfg, "USB3Ports", &cUsb3Ports, XHCI_NDP_30_DEFAULT);7947 rc = pHlp->pfnCFGMQueryU8Def(pCfg, "USB3Ports", &cUsb3Ports, XHCI_NDP_30_DEFAULT); 7948 7948 if (RT_FAILURE(rc)) 7949 7949 return PDMDEV_SET_ERROR(pDevIns, rc, … … 8039 8039 8040 8040 /* Set up the USB2 root hub interface. */ 8041 pThis->cUsb2Ports = (uint8_t)cUsb2Ports;8041 pThis->cUsb2Ports = cUsb2Ports; 8042 8042 pThisCC->RootHub2.pXhciR3 = pThisCC; 8043 8043 pThisCC->RootHub2.cPortsImpl = cUsb2Ports; … … 8053 8053 8054 8054 /* Now the USB3 root hub interface. */ 8055 pThis->cUsb3Ports = (uint8_t)cUsb3Ports;8055 pThis->cUsb3Ports = cUsb3Ports; 8056 8056 pThisCC->RootHub3.pXhciR3 = pThisCC; 8057 8057 pThisCC->RootHub3.cPortsImpl = cUsb3Ports;
Note:
See TracChangeset
for help on using the changeset viewer.