Changeset 81536 in vbox
- Timestamp:
- Oct 25, 2019 11:42:49 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DevOHCI.cpp
r81535 r81536 337 337 uint64_t cTicksPerUsbTick; 338 338 339 /** Detected canceled isochronous URBs. */ 340 STAMCOUNTER StatCanceledIsocUrbs; 341 /** Detected canceled general URBs. */ 342 STAMCOUNTER StatCanceledGenUrbs; 343 /** Dropped URBs (endpoint halted, or URB canceled). */ 344 STAMCOUNTER StatDroppedUrbs; 345 /** Profiling ohciR3FrameBoundaryTimer. */ 346 STAMPROFILE StatTimer; 347 348 /** This member and all the following are not part of saved state. */ 349 uint64_t SavedStateEnd; 350 351 /** VM timer frequency used for frame timer calculations. */ 352 uint64_t u64TimerHz; 353 /** Idle detection flag; must be cleared at start of frame */ 354 bool fIdle; 355 /** A flag indicating that the bulk list may have in-flight URBs. */ 356 bool fBulkNeedsCleaning; 357 358 bool afAlignment3[2]; 359 uint32_t Alignment4; /**< Align size on a 8 byte boundary. */ 360 361 /** Critical section synchronising interrupt handling. */ 362 PDMCRITSECT CsIrq; 363 364 /** The MMIO region handle. */ 365 IOMMMIOHANDLE hMmio; 366 } OHCI; 367 368 369 /** 370 * OHCI device data, ring-3. 371 */ 372 typedef struct OHCIR3 373 { 374 /** The root hub, ring-3 portion. */ 375 OHCIROOTHUBR3 RootHub; 376 /** Pointer to the device instance - R3 ptr. */ 377 PPDMDEVINSR3 pDevInsR3; 378 339 379 /** Number of in-flight TDs. */ 340 380 unsigned cInFlight; … … 344 384 { 345 385 /** Address of the transport descriptor. */ 346 uint32_t GCPhysTD;386 uint32_t GCPhysTD; 347 387 /** Flag indicating an inactive (not-linked) URB. */ 348 bool fInactive;388 bool fInactive; 349 389 /** Pointer to the URB. */ 350 390 R3PTRTYPE(PVUSBURB) pUrb; … … 361 401 { 362 402 /** Address of the transport descriptor. */ 363 uint32_t GCPhysTD;403 uint32_t GCPhysTD; 364 404 } aInDoneQueue[64]; 365 405 /** When the tail of the done queue was added. … … 371 411 #endif 372 412 373 /** Detected canceled isochronous URBs. */374 STAMCOUNTER StatCanceledIsocUrbs;375 /** Detected canceled general URBs. */376 STAMCOUNTER StatCanceledGenUrbs;377 /** Dropped URBs (endpoint halted, or URB canceled). */378 STAMCOUNTER StatDroppedUrbs;379 /** Profiling ohciR3FrameBoundaryTimer. */380 STAMPROFILE StatTimer;381 382 /** This member and all the following are not part of saved state. */383 uint64_t SavedStateEnd;384 385 /** VM timer frequency used for frame timer calculations. */386 uint64_t u64TimerHz;387 /** Idle detection flag; must be cleared at start of frame */388 bool fIdle;389 /** A flag indicating that the bulk list may have in-flight URBs. */390 bool fBulkNeedsCleaning;391 392 bool afAlignment3[2];393 uint32_t Alignment4; /**< Align size on a 8 byte boundary. */394 395 /** Critical section synchronising interrupt handling. */396 PDMCRITSECT CsIrq;397 398 /** The MMIO region handle. */399 IOMMMIOHANDLE hMmio;400 } OHCI;401 402 403 /**404 * OHCI device data, ring-3.405 */406 typedef struct OHCIR3407 {408 /** The root hub, ring-3 portion. */409 OHCIROOTHUBR3 RootHub;410 /** Pointer to the device instance - R3 ptr. */411 PPDMDEVINSR3 pDevInsR3;412 413 /** Pointer to state load data. */414 R3PTRTYPE(POHCILOAD) pLoad;415 416 413 #ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE 417 414 /** Last read physical page for caching ED reads in the framer thread. */ 418 OHCIPAGECACHE 415 OHCIPAGECACHE CacheED; 419 416 /** Last read physical page for caching TD reads in the framer thread. */ 420 OHCIPAGECACHE 417 OHCIPAGECACHE CacheTD; 421 418 #endif 422 419 423 420 /** Critical section to synchronize the framer and URB completion handler. */ 424 RTCRITSECT CritSect; 421 RTCRITSECT CritSect; 422 423 /** Pointer to state load data. */ 424 R3PTRTYPE(POHCILOAD) pLoad; 425 425 } OHCIR3; 426 426 /** Pointer to ring-3 OHCI state. */ … … 906 906 static DECLCALLBACK(bool) ohciR3RhXferError(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb); 907 907 908 static int ohciR3InFlightFind(POHCI pThis, uint32_t GCPhysTD);908 static int ohciR3InFlightFind(POHCICC pThisCC, uint32_t GCPhysTD); 909 909 # if defined(VBOX_STRICT) || defined(LOG_ENABLED) 910 static int ohciR3InDoneQueueFind(POHCI pThis, uint32_t GCPhysTD);910 static int ohciR3InDoneQueueFind(POHCICC pThisCC, uint32_t GCPhysTD); 911 911 # endif 912 912 static DECLCALLBACK(void) ohciR3LoadReattachDevices(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser); … … 1262 1262 */ 1263 1263 pThisCC->RootHub.pIRhConn->pfnCancelAllUrbs(pThisCC->RootHub.pIRhConn); 1264 Assert(pThis ->cInFlight == 0);1264 Assert(pThisCC->cInFlight == 0); 1265 1265 1266 1266 /* … … 1756 1756 * Core TD queue dumper. LOG_ENABLED builds only. 1757 1757 */ 1758 DECLINLINE(void) ohciR3DumpTdQueueCore(PPDMDEVINS pDevIns, POHCI pThis, uint32_t GCPhysHead, uint32_t GCPhysTail, bool fFull)1758 DECLINLINE(void) ohciR3DumpTdQueueCore(PPDMDEVINS pDevIns, POHCICC pThisCC, uint32_t GCPhysHead, uint32_t GCPhysTail, bool fFull) 1759 1759 { 1760 1760 uint32_t GCPhys = GCPhysHead; … … 1764 1764 OHCITD Td; 1765 1765 Log4(("%#010x%s%s", GCPhys, 1766 GCPhys && ohciR3InFlightFind(pThis , GCPhys) >= 0 ? "~" : "",1767 GCPhys && ohciR3InDoneQueueFind(pThis , GCPhys) >= 0 ? "^" : ""));1766 GCPhys && ohciR3InFlightFind(pThisCC, GCPhys) >= 0 ? "~" : "", 1767 GCPhys && ohciR3InDoneQueueFind(pThisCC, GCPhys) >= 0 ? "^" : "")); 1768 1768 if (GCPhys == 0 || GCPhys == GCPhysTail) 1769 1769 break; … … 1793 1793 * Dumps a TD queue. LOG_ENABLED builds only. 1794 1794 */ 1795 DECLINLINE(void) ohciR3DumpTdQueue(PPDMDEVINS pDevIns, POHCI pThis, uint32_t GCPhysHead, const char *pszMsg)1795 DECLINLINE(void) ohciR3DumpTdQueue(PPDMDEVINS pDevIns, POHCICC pThisCC, uint32_t GCPhysHead, const char *pszMsg) 1796 1796 { 1797 1797 if (pszMsg) 1798 1798 Log4(("%s: ", pszMsg)); 1799 ohciR3DumpTdQueueCore(pDevIns, pThis , GCPhysHead, 0, true);1799 ohciR3DumpTdQueueCore(pDevIns, pThisCC, GCPhysHead, 0, true); 1800 1800 Log4(("\n")); 1801 1801 } … … 1804 1804 * Core ITD queue dumper. LOG_ENABLED builds only. 1805 1805 */ 1806 DECLINLINE(void) ohciR3DumpITdQueueCore(PPDMDEVINS pDevIns, POHCI pThis, uint32_t GCPhysHead, uint32_t GCPhysTail, bool fFull)1806 DECLINLINE(void) ohciR3DumpITdQueueCore(PPDMDEVINS pDevIns, POHCICC pThisCC, uint32_t GCPhysHead, uint32_t GCPhysTail, bool fFull) 1807 1807 { 1808 1808 RT_NOREF(fFull); … … 1813 1813 OHCIITD ITd; 1814 1814 Log4(("%#010x%s%s", GCPhys, 1815 GCPhys && ohciR3InFlightFind(pThis , GCPhys) >= 0 ? "~" : "",1816 GCPhys && ohciR3InDoneQueueFind(pThis , GCPhys) >= 0 ? "^" : ""));1815 GCPhys && ohciR3InFlightFind(pThisCC, GCPhys) >= 0 ? "~" : "", 1816 GCPhys && ohciR3InDoneQueueFind(pThisCC, GCPhys) >= 0 ? "^" : "")); 1817 1817 if (GCPhys == 0 || GCPhys == GCPhysTail) 1818 1818 break; … … 1842 1842 * Dumps a ED list. LOG_ENABLED builds only. 1843 1843 */ 1844 DECLINLINE(void) ohciR3DumpEdList(PPDMDEVINS pDevIns, POHCI pThis, uint32_t GCPhysHead, const char *pszMsg, bool fTDs)1844 DECLINLINE(void) ohciR3DumpEdList(PPDMDEVINS pDevIns, POHCICC pThisCC, uint32_t GCPhysHead, const char *pszMsg, bool fTDs) 1845 1845 { 1846 1846 RT_NOREF(fTDs); … … 1876 1876 { 1877 1877 if (Ed.hwinfo & ED_HWINFO_ISO) 1878 ohciR3DumpITdQueueCore(pDevIns, pThis , Ed.HeadP & ED_PTR_MASK, Ed.TailP & ED_PTR_MASK, false);1878 ohciR3DumpITdQueueCore(pDevIns, pThisCC, Ed.HeadP & ED_PTR_MASK, Ed.TailP & ED_PTR_MASK, false); 1879 1879 else 1880 ohciR3DumpTdQueueCore(pDevIns, pThis , Ed.HeadP & ED_PTR_MASK, Ed.TailP & ED_PTR_MASK, false);1880 ohciR3DumpTdQueueCore(pDevIns, pThisCC, Ed.HeadP & ED_PTR_MASK, Ed.TailP & ED_PTR_MASK, false); 1881 1881 Log4(("}")); 1882 1882 } … … 1892 1892 1893 1893 1894 DECLINLINE(int) ohciR3InFlightFindFree(POHCI pThis, const int iStart)1894 DECLINLINE(int) ohciR3InFlightFindFree(POHCICC pThisCC, const int iStart) 1895 1895 { 1896 1896 unsigned i = iStart; 1897 while (i < RT_ELEMENTS(pThis ->aInFlight))1898 { 1899 if (pThis ->aInFlight[i].GCPhysTD == 0)1897 while (i < RT_ELEMENTS(pThisCC->aInFlight)) 1898 { 1899 if (pThisCC->aInFlight[i].GCPhysTD == 0) 1900 1900 return i; 1901 1901 i++; … … 1904 1904 while (i-- > 0) 1905 1905 { 1906 if (pThis ->aInFlight[i].GCPhysTD == 0)1906 if (pThisCC->aInFlight[i].GCPhysTD == 0) 1907 1907 return i; 1908 1908 } … … 1914 1914 * Record an in-flight TD. 1915 1915 * 1916 * @param pThis OHCI instance data. 1916 * @param pThis OHCI instance data, shared edition. 1917 * @param pThisCC OHCI instance data, ring-3 edition. 1917 1918 * @param GCPhysTD Physical address of the TD. 1918 1919 * @param pUrb The URB. 1919 1920 */ 1920 static void ohciR3InFlightAdd(POHCI pThis, uint32_t GCPhysTD, PVUSBURB pUrb)1921 { 1922 int i = ohciR3InFlightFindFree(pThis , (GCPhysTD >> 4) % RT_ELEMENTS(pThis->aInFlight));1921 static void ohciR3InFlightAdd(POHCI pThis, POHCICC pThisCC, uint32_t GCPhysTD, PVUSBURB pUrb) 1922 { 1923 int i = ohciR3InFlightFindFree(pThisCC, (GCPhysTD >> 4) % RT_ELEMENTS(pThisCC->aInFlight)); 1923 1924 if (i >= 0) 1924 1925 { … … 1926 1927 pUrb->pHci->u32FrameNo = pThis->HcFmNumber; 1927 1928 # endif 1928 pThis ->aInFlight[i].GCPhysTD = GCPhysTD;1929 pThis ->aInFlight[i].pUrb = pUrb;1930 pThis ->cInFlight++;1929 pThisCC->aInFlight[i].GCPhysTD = GCPhysTD; 1930 pThisCC->aInFlight[i].pUrb = pUrb; 1931 pThisCC->cInFlight++; 1931 1932 return; 1932 1933 } 1933 AssertMsgFailed(("Out of space cInFlight=%d!\n", pThis->cInFlight)); 1934 AssertMsgFailed(("Out of space cInFlight=%d!\n", pThisCC->cInFlight)); 1935 RT_NOREF(pThis); 1934 1936 } 1935 1937 … … 1938 1940 * Record in-flight TDs for an URB. 1939 1941 * 1940 * @param pThis OHCI instance data. 1942 * @param pThis OHCI instance data, shared edition. 1943 * @param pThisCC OHCI instance data, ring-3 edition. 1941 1944 * @param pUrb The URB. 1942 1945 */ 1943 static void ohciR3InFlightAddUrb(POHCI pThis, P VUSBURB pUrb)1946 static void ohciR3InFlightAddUrb(POHCI pThis, POHCICC pThisCC, PVUSBURB pUrb) 1944 1947 { 1945 1948 for (unsigned iTd = 0; iTd < pUrb->pHci->cTds; iTd++) 1946 ohciR3InFlightAdd(pThis, p Urb->paTds[iTd].TdAddr, pUrb);1949 ohciR3InFlightAdd(pThis, pThisCC, pUrb->paTds[iTd].TdAddr, pUrb); 1947 1950 } 1948 1951 … … 1953 1956 * @returns Index of the record. 1954 1957 * @returns -1 if not found. 1955 * @param pThis OHCI instance data.1958 * @param pThisCC OHCI instance data, ring-3 edition. 1956 1959 * @param GCPhysTD Physical address of the TD. 1957 1960 * @remark This has to be fast. 1958 1961 */ 1959 static int ohciR3InFlightFind(POHCI pThis, uint32_t GCPhysTD)1960 { 1961 unsigned cLeft = pThis ->cInFlight;1962 unsigned i = (GCPhysTD >> 4) % RT_ELEMENTS(pThis ->aInFlight);1962 static int ohciR3InFlightFind(POHCICC pThisCC, uint32_t GCPhysTD) 1963 { 1964 unsigned cLeft = pThisCC->cInFlight; 1965 unsigned i = (GCPhysTD >> 4) % RT_ELEMENTS(pThisCC->aInFlight); 1963 1966 const int iLast = i; 1964 while (i < RT_ELEMENTS(pThis ->aInFlight))1965 { 1966 if (pThis ->aInFlight[i].GCPhysTD == GCPhysTD)1967 while (i < RT_ELEMENTS(pThisCC->aInFlight)) 1968 { 1969 if (pThisCC->aInFlight[i].GCPhysTD == GCPhysTD) 1967 1970 return i; 1968 if (pThis ->aInFlight[i].GCPhysTD)1971 if (pThisCC->aInFlight[i].GCPhysTD) 1969 1972 if (cLeft-- <= 1) 1970 1973 return -1; … … 1974 1977 while (i-- > 0) 1975 1978 { 1976 if (pThis ->aInFlight[i].GCPhysTD == GCPhysTD)1979 if (pThisCC->aInFlight[i].GCPhysTD == GCPhysTD) 1977 1980 return i; 1978 if (pThis ->aInFlight[i].GCPhysTD)1981 if (pThisCC->aInFlight[i].GCPhysTD) 1979 1982 if (cLeft-- <= 1) 1980 1983 return -1; … … 1988 1991 * 1989 1992 * @returns true if in flight, false if not. 1990 * @param pThis OHCI instance data.1993 * @param pThisCC OHCI instance data, ring-3 edition. 1991 1994 * @param GCPhysTD Physical address of the TD. 1992 1995 */ 1993 static bool ohciR3IsTdInFlight(POHCI pThis, uint32_t GCPhysTD)1994 { 1995 return ohciR3InFlightFind(pThis , GCPhysTD) >= 0;1996 static bool ohciR3IsTdInFlight(POHCICC pThisCC, uint32_t GCPhysTD) 1997 { 1998 return ohciR3InFlightFind(pThisCC, GCPhysTD) >= 0; 1996 1999 } 1997 2000 … … 2001 2004 * @returns pointer to URB if TD is in flight. 2002 2005 * @returns NULL if not in flight. 2003 * @param pThis OHCI instance data.2006 * @param pThisCC OHCI instance data, ring-3 edition. 2004 2007 * @param GCPhysTD Physical address of the TD. 2005 2008 */ 2006 static PVUSBURB ohciR3TdInFlightUrb(POHCI pThis, uint32_t GCPhysTD)2009 static PVUSBURB ohciR3TdInFlightUrb(POHCICC pThisCC, uint32_t GCPhysTD) 2007 2010 { 2008 2011 int i; 2009 2012 2010 i = ohciR3InFlightFind(pThis , GCPhysTD);2013 i = ohciR3InFlightFind(pThisCC, GCPhysTD); 2011 2014 if ( i >= 0 ) 2012 return pThis ->aInFlight[i].pUrb;2015 return pThisCC->aInFlight[i].pUrb; 2013 2016 return NULL; 2014 2017 } … … 2019 2022 * @returns 0 if found. For logged builds this is the number of frames the TD has been in-flight. 2020 2023 * @returns -1 if not found. 2021 * @param pThis OHCI instance data. 2024 * @param pThis OHCI instance data, shared edition (for logging). 2025 * @param pThisCC OHCI instance data, ring-3 edition. 2022 2026 * @param GCPhysTD Physical address of the TD. 2023 2027 */ 2024 static int ohciR3InFlightRemove(POHCI pThis, uint32_t GCPhysTD)2025 { 2026 int i = ohciR3InFlightFind(pThis , GCPhysTD);2028 static int ohciR3InFlightRemove(POHCI pThis, POHCICC pThisCC, uint32_t GCPhysTD) 2029 { 2030 int i = ohciR3InFlightFind(pThisCC, GCPhysTD); 2027 2031 if (i >= 0) 2028 2032 { 2029 2033 # ifdef LOG_ENABLED 2030 const int cFramesInFlight = pThis->HcFmNumber - pThis ->aInFlight[i].pUrb->pHci->u32FrameNo;2034 const int cFramesInFlight = pThis->HcFmNumber - pThisCC->aInFlight[i].pUrb->pHci->u32FrameNo; 2031 2035 # else 2032 const int cFramesInFlight = 0; 2036 const int cFramesInFlight = 0; RT_NOREF(pThis); 2033 2037 # endif 2034 2038 Log2(("ohciR3InFlightRemove: reaping TD=%#010x %d frames (%#010x-%#010x)\n", 2035 GCPhysTD, cFramesInFlight, pThis ->aInFlight[i].pUrb->pHci->u32FrameNo, pThis->HcFmNumber));2036 pThis ->aInFlight[i].GCPhysTD = 0;2037 pThis ->aInFlight[i].pUrb = NULL;2038 pThis ->cInFlight--;2039 GCPhysTD, cFramesInFlight, pThisCC->aInFlight[i].pUrb->pHci->u32FrameNo, pThis->HcFmNumber)); 2040 pThisCC->aInFlight[i].GCPhysTD = 0; 2041 pThisCC->aInFlight[i].pUrb = NULL; 2042 pThisCC->cInFlight--; 2039 2043 return cFramesInFlight; 2040 2044 } … … 2049 2053 * @returns 0 if found. For logged builds this is the number of frames the TD has been in-flight. 2050 2054 * @returns -1 if not found. 2051 * @param pThis OHCI instance data. 2055 * @param pThis OHCI instance data, shared edition (for logging). 2056 * @param pThisCC OHCI instance data, ring-3 edition. 2052 2057 * @param pUrb The URB. 2053 2058 */ 2054 static int ohciR3InFlightRemoveUrb(POHCI pThis, P VUSBURB pUrb)2055 { 2056 int cFramesInFlight = ohciR3InFlightRemove(pThis, p Urb->paTds[0].TdAddr);2059 static int ohciR3InFlightRemoveUrb(POHCI pThis, POHCICC pThisCC, PVUSBURB pUrb) 2060 { 2061 int cFramesInFlight = ohciR3InFlightRemove(pThis, pThisCC, pUrb->paTds[0].TdAddr); 2057 2062 if (pUrb->pHci->cTds > 1) 2058 2063 { 2059 2064 for (unsigned iTd = 1; iTd < pUrb->pHci->cTds; iTd++) 2060 if (ohciR3InFlightRemove(pThis, p Urb->paTds[iTd].TdAddr) < 0)2065 if (ohciR3InFlightRemove(pThis, pThisCC, pUrb->paTds[iTd].TdAddr) < 0) 2061 2066 cFramesInFlight = -1; 2062 2067 } … … 2069 2074 /** 2070 2075 * Empties the in-done-queue. 2071 * @param pThis OHCI instance data.2072 */ 2073 static void ohciR3InDoneQueueZap(POHCI pThis)2074 { 2075 pThis ->cInDoneQueue = 0;2076 * @param pThisCC OHCI instance data, ring-3 edition. 2077 */ 2078 static void ohciR3InDoneQueueZap(POHCICC pThisCC) 2079 { 2080 pThisCC->cInDoneQueue = 0; 2076 2081 } 2077 2082 … … 2080 2085 * @returns >= 0 on success. 2081 2086 * @returns -1 if not found. 2082 * @param pThis OHCI instance data.2087 * @param pThisCC OHCI instance data, ring-3 edition. 2083 2088 * @param GCPhysTD Physical address of the TD. 2084 2089 */ 2085 static int ohciR3InDoneQueueFind(POHCI pThis, uint32_t GCPhysTD)2086 { 2087 unsigned i = pThis ->cInDoneQueue;2090 static int ohciR3InDoneQueueFind(POHCICC pThisCC, uint32_t GCPhysTD) 2091 { 2092 unsigned i = pThisCC->cInDoneQueue; 2088 2093 while (i-- > 0) 2089 if (pThis ->aInDoneQueue[i].GCPhysTD == GCPhysTD)2094 if (pThisCC->aInDoneQueue[i].GCPhysTD == GCPhysTD) 2090 2095 return i; 2091 2096 return -1; … … 2094 2099 /** 2095 2100 * Checks that the specified TD is not in the done queue. 2096 * @param pThis OHCI instance data.2101 * @param pThisCC OHCI instance data, ring-3 edition. 2097 2102 * @param GCPhysTD Physical address of the TD. 2098 2103 */ 2099 static bool ohciR3InDoneQueueCheck(POHCI pThis, uint32_t GCPhysTD)2100 { 2101 int i = ohciR3InDoneQueueFind(pThis , GCPhysTD);2104 static bool ohciR3InDoneQueueCheck(POHCICC pThisCC, uint32_t GCPhysTD) 2105 { 2106 int i = ohciR3InDoneQueueFind(pThisCC, GCPhysTD); 2102 2107 # if 0 2103 2108 /* This condition has been observed with the USB tablet emulation or with … … 2120 2125 /** 2121 2126 * Adds a TD to the in-done-queue tracking, checking that it's not there already. 2122 * @param pThis OHCI instance data.2127 * @param pThisCC OHCI instance data, ring-3 edition. 2123 2128 * @param GCPhysTD Physical address of the TD. 2124 2129 */ 2125 static void ohciR3InDoneQueueAdd(POHCI pThis, uint32_t GCPhysTD)2126 { 2127 Assert(pThis ->cInDoneQueue + 1 <= RT_ELEMENTS(pThis->aInDoneQueue));2128 if (ohciR3InDoneQueueCheck(pThis , GCPhysTD))2129 pThis ->aInDoneQueue[pThis->cInDoneQueue++].GCPhysTD = GCPhysTD;2130 static void ohciR3InDoneQueueAdd(POHCICC pThisCC, uint32_t GCPhysTD) 2131 { 2132 Assert(pThisCC->cInDoneQueue + 1 <= RT_ELEMENTS(pThisCC->aInDoneQueue)); 2133 if (ohciR3InDoneQueueCheck(pThisCC, GCPhysTD)) 2134 pThisCC->aInDoneQueue[pThisCC->cInDoneQueue++].GCPhysTD = GCPhysTD; 2130 2135 } 2131 2136 # endif /* VBOX_STRICT */ … … 2566 2571 * In general, all URBs should have status OK. 2567 2572 */ 2568 static void ohciR3RhXferCompleteIsochronousURB(PPDMDEVINS pDevIns, POHCI pThis, PVUSBURB pUrb /*, POHCIED pEd , int cFmAge*/) 2573 static void ohciR3RhXferCompleteIsochronousURB(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, PVUSBURB pUrb 2574 /*, POHCIED pEd , int cFmAge*/) 2569 2575 { 2570 2576 /* … … 2686 2692 # ifdef LOG_ENABLED 2687 2693 if (!pThis->done) 2688 pThis ->u32FmDoneQueueTail = pThis->HcFmNumber;2694 pThisCC->u32FmDoneQueueTail = pThis->HcFmNumber; 2689 2695 # ifdef VBOX_STRICT 2690 ohciR3InDoneQueueAdd(pThis , ITdAddr);2696 ohciR3InDoneQueueAdd(pThisCC, ITdAddr); 2691 2697 # endif 2692 2698 # endif … … 2712 2718 ohciR3WriteITd(pDevIns, pThis, ITdAddr, pITd, "retired"); 2713 2719 } 2720 RT_NOREF(pThisCC); 2714 2721 } 2715 2722 … … 2719 2726 * a URB made up of general TDs. 2720 2727 */ 2721 static void ohciR3RhXferCompleteGeneralURB(PPDMDEVINS pDevIns, POHCI pThis, PVUSBURB pUrb, POHCIED pEd, int cFmAge) 2728 static void ohciR3RhXferCompleteGeneralURB(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, PVUSBURB pUrb, 2729 POHCIED pEd, int cFmAge) 2722 2730 { 2723 2731 RT_NOREF(cFmAge); … … 2836 2844 # ifdef LOG_ENABLED 2837 2845 if (!pThis->done) 2838 pThis ->u32FmDoneQueueTail = pThis->HcFmNumber;2846 pThisCC->u32FmDoneQueueTail = pThis->HcFmNumber; 2839 2847 # ifdef VBOX_STRICT 2840 ohciR3InDoneQueueAdd(pThis , TdAddr);2848 ohciR3InDoneQueueAdd(pThisCC, TdAddr); 2841 2849 # endif 2842 2850 # endif … … 2858 2866 break; 2859 2867 } 2868 RT_NOREF(pThisCC); 2860 2869 } 2861 2870 … … 2880 2889 ohciR3Lock(pThisCC); 2881 2890 2882 int cFmAge = ohciR3InFlightRemoveUrb(pThis, p Urb);2891 int cFmAge = ohciR3InFlightRemoveUrb(pThis, pThisCC, pUrb); 2883 2892 2884 2893 /* Do nothing requiring memory access if the HC encountered an unrecoverable error. */ … … 2936 2945 */ 2937 2946 if (pUrb->enmType == VUSBXFERTYPE_ISOC) 2938 ohciR3RhXferCompleteIsochronousURB(pDevIns, pThis, p Urb /*, &Ed , cFmAge*/);2947 ohciR3RhXferCompleteIsochronousURB(pDevIns, pThis, pThisCC, pUrb /*, &Ed , cFmAge*/); 2939 2948 else 2940 ohciR3RhXferCompleteGeneralURB(pDevIns, pThis, p Urb, &Ed, cFmAge);2949 ohciR3RhXferCompleteGeneralURB(pDevIns, pThis, pThisCC, pUrb, &Ed, cFmAge); 2941 2950 2942 2951 /* finally write back the endpoint descriptor. */ … … 3104 3113 * Submit the URB. 3105 3114 */ 3106 ohciR3InFlightAdd(pThis, TdAddr, pUrb);3115 ohciR3InFlightAdd(pThis, pThisCC, TdAddr, pUrb); 3107 3116 Log(("%s: ohciR3ServiceTd: submitting TdAddr=%#010x EdAddr=%#010x cbData=%#x\n", 3108 3117 pUrb->pszDesc, TdAddr, EdAddr, pUrb->cbData)); … … 3117 3126 Log(("ohciR3ServiceTd: failed submitting TdAddr=%#010x EdAddr=%#010x pUrb=%p!!\n", 3118 3127 TdAddr, EdAddr, pUrb)); 3119 ohciR3InFlightRemove(pThis, TdAddr);3128 ohciR3InFlightRemove(pThis, pThisCC, TdAddr); 3120 3129 VUSBIRhFreeUrb(pThisCC->RootHub.pIRhConn, pUrb); 3121 3130 return false; … … 3133 3142 */ 3134 3143 uint32_t TdAddr = pEd->HeadP & ED_PTR_MASK; 3135 if (ohciR3IsTdInFlight(pThis , TdAddr))3144 if (ohciR3IsTdInFlight(pThisCC, TdAddr)) 3136 3145 return false; 3137 3146 # if defined(VBOX_STRICT) || defined(LOG_ENABLED) 3138 ohciR3InDoneQueueCheck(pThis , TdAddr);3147 ohciR3InDoneQueueCheck(pThisCC, TdAddr); 3139 3148 # endif 3140 3149 return ohciR3ServiceTd(pDevIns, pThis, pThisCC, enmType, pEd, EdAddr, TdAddr, &TdAddr, pszListName); … … 3277 3286 * Submit the URB. 3278 3287 */ 3279 ohciR3InFlightAddUrb(pThis, p Urb);3288 ohciR3InFlightAddUrb(pThis, pThisCC, pUrb); 3280 3289 Log(("%s: ohciR3ServiceTdMultiple: submitting cbData=%#x EdAddr=%#010x cTds=%d TdAddr0=%#010x\n", 3281 3290 pUrb->pszDesc, pUrb->cbData, EdAddr, cTds, TdAddr)); … … 3289 3298 Log(("ohciR3ServiceTdMultiple: failed submitting pUrb=%p cbData=%#x EdAddr=%#010x cTds=%d TdAddr0=%#010x - rc=%Rrc\n", 3290 3299 pUrb, cbTotal, EdAddr, cTds, TdAddr, rc)); 3291 ohciR3InFlightRemoveUrb(pThis, p Urb);3300 ohciR3InFlightRemoveUrb(pThis, pThisCC, pUrb); 3292 3301 VUSBIRhFreeUrb(pThisCC->RootHub.pIRhConn, pUrb); 3293 3302 return false; … … 3298 3307 * Service the head TD of an endpoint. 3299 3308 */ 3300 static bool ohciR3ServiceHeadTdMultiple(PPDMDEVINS pDevIns, POHCI pThis, VUSBXFERTYPE enmType, PCOHCIED pEd, uint32_t EdAddr,3301 const char *pszListName)3309 static bool ohciR3ServiceHeadTdMultiple(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, VUSBXFERTYPE enmType, 3310 PCOHCIED pEd, uint32_t EdAddr, const char *pszListName) 3302 3311 { 3303 3312 /* … … 3305 3314 */ 3306 3315 uint32_t TdAddr = pEd->HeadP & ED_PTR_MASK; 3307 if (ohciR3IsTdInFlight(pThis , TdAddr))3316 if (ohciR3IsTdInFlight(pThisCC, TdAddr)) 3308 3317 return false; 3309 3318 # if defined(VBOX_STRICT) || defined(LOG_ENABLED) 3310 ohciR3InDoneQueueCheck(pThis , TdAddr);3319 ohciR3InDoneQueueCheck(pThisCC, TdAddr); 3311 3320 # endif 3312 3321 return ohciR3ServiceTdMultiple(pDevIns, pThis, enmType, pEd, EdAddr, TdAddr, &TdAddr, pszListName); … … 3318 3327 * that belongs to the past. 3319 3328 */ 3320 static bool ohciR3ServiceIsochronousTdUnlink(PPDMDEVINS pDevIns, POHCI pThis, POHCI ITD pITd, uint32_t ITdAddr,3329 static bool ohciR3ServiceIsochronousTdUnlink(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, POHCIITD pITd, uint32_t ITdAddr, 3321 3330 uint32_t ITdAddrPrev, PVUSBURB pUrb, POHCIED pEd, uint32_t EdAddr) 3322 3331 { … … 3331 3340 { 3332 3341 /* Get validate the previous TD */ 3333 int iInFlightPrev = ohciR3InFlightFind(pThis , ITdAddrPrev);3342 int iInFlightPrev = ohciR3InFlightFind(pThisCC, ITdAddrPrev); 3334 3343 AssertMsgReturn(iInFlightPrev >= 0, ("ITdAddr=%#RX32\n", ITdAddrPrev), false); 3335 PVUSBURB pUrbPrev = pThis ->aInFlight[iInFlightPrev].pUrb;3344 PVUSBURB pUrbPrev = pThisCC->aInFlight[iInFlightPrev].pUrb; 3336 3345 if (ohciR3HasUrbBeenCanceled(pDevIns, pThis, pUrbPrev, pEd)) /* ensures the copy is correct. */ 3337 3346 return false; … … 3523 3532 * Submit the URB. 3524 3533 */ 3525 ohciR3InFlightAdd(pThis, ITdAddr, pUrb);3534 ohciR3InFlightAdd(pThis, pThisCC, ITdAddr, pUrb); 3526 3535 Log(("%s: ohciR3ServiceIsochronousTd: submitting cbData=%#x cIsocPkts=%d EdAddr=%#010x TdAddr=%#010x SF=%#x (%#x)\n", 3527 3536 pUrb->pszDesc, pUrb->cbData, pUrb->cIsocPkts, EdAddr, ITdAddr, pITd->HwInfo & ITD_HWINFO_SF, pThis->HcFmNumber)); … … 3535 3544 Log(("ohciR3ServiceIsochronousTd: failed submitting pUrb=%p cbData=%#x EdAddr=%#010x cTds=%d ITdAddr0=%#010x - rc=%Rrc\n", 3536 3545 pUrb, cbTotal, EdAddr, 1, ITdAddr, rc)); 3537 ohciR3InFlightRemove(pThis, ITdAddr);3546 ohciR3InFlightRemove(pThis, pThisCC, ITdAddr); 3538 3547 VUSBIRhFreeUrb(pThisCC->RootHub.pIRhConn, pUrb); 3539 3548 return false; … … 3602 3611 && (uint16_t)u32NextFrame != (uint16_t)(ITd.HwInfo & ITD_HWINFO_SF)) 3603 3612 break; 3604 if (ohciR3InFlightFind(pThis , ITdAddr) < 0)3613 if (ohciR3InFlightFind(pThisCC, ITdAddr) < 0) 3605 3614 if (!ohciR3ServiceIsochronousTd(pDevIns, pThis, pThisCC, &ITd, ITdAddr, R < 0 ? 0 : R, pEd, EdAddr)) 3606 3615 break; … … 3624 3633 * time will show. 3625 3634 */ 3626 int iInFlight = ohciR3InFlightFind(pThis , ITdAddr);3635 int iInFlight = ohciR3InFlightFind(pThisCC, ITdAddr); 3627 3636 if (iInFlight >= 0) 3628 3637 ITdAddrPrev = ITdAddr; 3629 else if (!ohciR3ServiceIsochronousTdUnlink(pDevIns, pThis, &ITd, ITdAddr, ITdAddrPrev, NULL, pEd, EdAddr))3638 else if (!ohciR3ServiceIsochronousTdUnlink(pDevIns, pThis, pThisCC, &ITd, ITdAddr, ITdAddrPrev, NULL, pEd, EdAddr)) 3630 3639 { 3631 3640 Log(("ohciR3ServiceIsochronousEndpoint: Failed unlinking old ITD.\n")); … … 3696 3705 # ifdef LOG_ENABLED 3697 3706 if (g_fLogBulkEPs) 3698 ohciR3DumpEdList(pDevIns, pThis , pThis->bulk_head, "Bulk before", true);3707 ohciR3DumpEdList(pDevIns, pThisCC, pThis->bulk_head, "Bulk before", true); 3699 3708 if (pThis->bulk_cur) 3700 3709 Log(("ohciR3ServiceBulkList: bulk_cur=%#010x before listprocessing!!! HCD have positioned us!!!\n", pThis->bulk_cur)); … … 3735 3744 * on a bulk endpoint. 3736 3745 */ 3737 ohciR3ServiceHeadTdMultiple(pDevIns, pThis, VUSBXFERTYPE_BULK, &Ed, EdAddr, "Bulk");3746 ohciR3ServiceHeadTdMultiple(pDevIns, pThis, pThisCC, VUSBXFERTYPE_BULK, &Ed, EdAddr, "Bulk"); 3738 3747 # else 3739 3748 /* … … 3772 3781 */ 3773 3782 uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; 3774 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThis , TdAddr);3783 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr); 3775 3784 if (pUrb) 3776 3785 pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb); … … 3785 3794 # ifdef LOG_ENABLED 3786 3795 if (g_fLogBulkEPs) 3787 ohciR3DumpEdList(pDevIns, pThis , pThis->bulk_head, "Bulk after ", true);3796 ohciR3DumpEdList(pDevIns, pThisCC, pThis->bulk_head, "Bulk after ", true); 3788 3797 # endif 3789 3798 } … … 3801 3810 # ifdef LOG_ENABLED 3802 3811 if (g_fLogBulkEPs) 3803 ohciR3DumpEdList(pDevIns, pThis , pThis->bulk_head, "Bulk before", true);3812 ohciR3DumpEdList(pDevIns, pThisCC, pThis->bulk_head, "Bulk before", true); 3804 3813 if (pThis->bulk_cur) 3805 3814 Log(("ohciR3UndoBulkList: bulk_cur=%#010x before list processing!!! HCD has positioned us!!!\n", pThis->bulk_cur)); … … 3819 3828 { 3820 3829 uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; 3821 if (ohciR3IsTdInFlight(pThis , TdAddr))3830 if (ohciR3IsTdInFlight(pThisCC, TdAddr)) 3822 3831 { 3823 3832 LogFlow(("ohciR3UndoBulkList: Ed=%#010RX32 Ed.TailP=%#010RX32 UNDO\n", EdAddr, Ed.TailP)); 3824 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThis , TdAddr);3833 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr); 3825 3834 if (pUrb) 3826 3835 pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb); … … 3843 3852 # ifdef LOG_ENABLED 3844 3853 if (g_fLogControlEPs) 3845 ohciR3DumpEdList(pDevIns, pThis , pThis->ctrl_head, "Ctrl before", true);3854 ohciR3DumpEdList(pDevIns, pThisCC, pThis->ctrl_head, "Ctrl before", true); 3846 3855 if (pThis->ctrl_cur) 3847 3856 Log(("ohciR3ServiceCtrlList: ctrl_cur=%010x before list processing!!! HCD have positioned us!!!\n", pThis->ctrl_cur)); … … 3879 3888 { 3880 3889 if ( !ohciR3ServiceHeadTd(pDevIns, pThis, pThisCC, VUSBXFERTYPE_CTRL, &Ed, EdAddr, "Control") 3881 || ohciR3IsTdInFlight(pThis , Ed.HeadP & ED_PTR_MASK))3890 || ohciR3IsTdInFlight(pThisCC, Ed.HeadP & ED_PTR_MASK)) 3882 3891 { 3883 3892 pThis->status |= OHCI_STATUS_CLF; … … 3899 3908 # ifdef LOG_ENABLED 3900 3909 if (g_fLogControlEPs) 3901 ohciR3DumpEdList(pDevIns, pThis , pThis->ctrl_head, "Ctrl after ", true);3910 ohciR3DumpEdList(pDevIns, pThisCC, pThis->ctrl_head, "Ctrl after ", true); 3902 3911 # endif 3903 3912 } … … 3926 3935 char sz[48]; 3927 3936 RTStrPrintf(sz, sizeof(sz), "Int%02x before", iList); 3928 ohciR3DumpEdList(pDevIns, pThis , EdAddrHead, sz, true);3937 ohciR3DumpEdList(pDevIns, pThisCC, EdAddrHead, sz, true); 3929 3938 } 3930 3939 # endif … … 3954 3963 * Presently we will only process the head URB on an interrupt endpoint. 3955 3964 */ 3956 ohciR3ServiceHeadTdMultiple(pDevIns, pThis, VUSBXFERTYPE_INTR, &Ed, EdAddr, "Periodic");3965 ohciR3ServiceHeadTdMultiple(pDevIns, pThis, pThisCC, VUSBXFERTYPE_INTR, &Ed, EdAddr, "Periodic"); 3957 3966 } 3958 3967 else if (pThis->ctl & OHCI_CTL_IE) … … 3975 3984 */ 3976 3985 uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; 3977 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThis , TdAddr);3986 PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr); 3978 3987 if (pUrb) 3979 3988 pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb); … … 3989 3998 char sz[48]; 3990 3999 RTStrPrintf(sz, sizeof(sz), "Int%02x after ", iList); 3991 ohciR3DumpEdList(pDevIns, pThis , EdAddrHead, sz, true);4000 ohciR3DumpEdList(pDevIns, pThisCC, EdAddrHead, sz, true); 3992 4001 } 3993 4002 # endif … … 4000 4009 * @param pThis The OHCI instance data. 4001 4010 */ 4002 static void ohciR3UpdateHCCA(PPDMDEVINS pDevIns, POHCI pThis )4011 static void ohciR3UpdateHCCA(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC) 4003 4012 { 4004 4013 OCHIHCCA hcca; … … 4023 4032 4024 4033 Log(("ohci: Writeback Done (%#010x) on frame %#x (age %#x)\n", hcca.done, 4025 pThis->HcFmNumber, pThis->HcFmNumber - pThis ->u32FmDoneQueueTail));4034 pThis->HcFmNumber, pThis->HcFmNumber - pThisCC->u32FmDoneQueueTail)); 4026 4035 # ifdef LOG_ENABLED 4027 ohciR3DumpTdQueue(pDevIns, pThis , hcca.done & ED_PTR_MASK, "DoneQueue");4036 ohciR3DumpTdQueue(pDevIns, pThisCC, hcca.done & ED_PTR_MASK, "DoneQueue"); 4028 4037 # endif 4029 4038 Assert(RT_OFFSETOF(OCHIHCCA, done) == 4); 4030 4039 # if defined(VBOX_STRICT) || defined(LOG_ENABLED) 4031 ohciR3InDoneQueueZap(pThis );4040 ohciR3InDoneQueueZap(pThisCC); 4032 4041 # endif 4033 4042 fWriteDoneHeadInterrupt = true; … … 4038 4047 if (fWriteDoneHeadInterrupt) 4039 4048 ohciR3SetInterrupt(pDevIns, pThis, OHCI_INTR_WRITE_DONE_HEAD); 4049 RT_NOREF(pThisCC); 4040 4050 } 4041 4051 … … 4047 4057 * they might "steal" data destined for another URB. 4048 4058 */ 4049 static void ohciR3CancelOrphanedURBs(PPDMDEVINS pDevIns, POHCI pThis )4059 static void ohciR3CancelOrphanedURBs(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC) 4050 4060 { 4051 4061 bool fValidHCCA = !( pThis->hcca >= OHCI_HCCA_MASK … … 4059 4069 * there's nothing to do. 4060 4070 */ 4061 if (!fValidHCCA || !pThis ->cInFlight)4071 if (!fValidHCCA || !pThisCC->cInFlight) 4062 4072 return; 4063 4073 4064 4074 /* Initially mark all in-flight URBs as inactive. */ 4065 for (i = 0, cLeft = pThis ->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++)4066 { 4067 if (pThis ->aInFlight[i].pUrb)4075 for (i = 0, cLeft = pThisCC->cInFlight; cLeft && i < RT_ELEMENTS(pThisCC->aInFlight); i++) 4076 { 4077 if (pThisCC->aInFlight[i].pUrb) 4068 4078 { 4069 pThis ->aInFlight[i].fInactive = true;4079 pThisCC->aInFlight[i].fInactive = true; 4070 4080 cLeft--; 4071 4081 } … … 4077 4087 uint32_t au32HCCA[OHCI_HCCA_NUM_INTR]; 4078 4088 ohciR3GetDWords(pDevIns, pThis->hcca, au32HCCA, OHCI_HCCA_NUM_INTR); 4079 POHCICC pThisCC = PDMINS_2_DATA_CC(pDevIns, POHCICC);4080 4089 # endif 4081 4090 … … 4119 4128 { 4120 4129 ohciR3ReadTd(pDevIns, TdAddr, &Td); 4121 j = ohciR3InFlightFind(pThis , TdAddr);4130 j = ohciR3InFlightFind(pThisCC, TdAddr); 4122 4131 if (j > -1) 4123 pThis ->aInFlight[j].fInactive = false;4132 pThisCC->aInFlight[j].fInactive = false; 4124 4133 TdAddr = Td.NextTD & ED_PTR_MASK; 4125 4134 /* See #8125. … … 4144 4153 * to be canceled. 4145 4154 */ 4146 for (i = 0, cLeft = pThis ->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++)4147 { 4148 if (pThis ->aInFlight[i].pUrb)4155 for (i = 0, cLeft = pThisCC->cInFlight; cLeft && i < RT_ELEMENTS(pThisCC->aInFlight); i++) 4156 { 4157 if (pThisCC->aInFlight[i].pUrb) 4149 4158 { 4150 4159 cLeft--; 4151 pUrb = pThis ->aInFlight[i].pUrb;4152 if ( pThis->aInFlight[i].fInactive4160 pUrb = pThisCC->aInFlight[i].pUrb; 4161 if ( pThisCC->aInFlight[i].fInactive 4153 4162 && pUrb->enmState == VUSBURBSTATE_IN_FLIGHT 4154 4163 && pUrb->enmType != VUSBXFERTYPE_CTRL) … … 4187 4196 */ 4188 4197 if (fValidHCCA) 4189 ohciR3UpdateHCCA(pDevIns, pThis );4198 ohciR3UpdateHCCA(pDevIns, pThis, pThisCC); 4190 4199 # endif 4191 4200 … … 4300 4309 4301 4310 /* Clean up any URBs that have been removed. */ 4302 ohciR3CancelOrphanedURBs(pDevIns, pThis );4311 ohciR3CancelOrphanedURBs(pDevIns, pThis, pThisCC); 4303 4312 4304 4313 /* Start the next frame. */
Note:
See TracChangeset
for help on using the changeset viewer.