- Timestamp:
- Dec 17, 2013 3:47:27 PM (11 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DevOHCI.cpp
r49814 r49958 361 361 362 362 uint32_t Alignment3; /**< Align size on a 8 byte boundary. */ 363 364 /** Critical section synchronising interrupt handling. */ 365 PDMCRITSECT CsIrq; 363 366 364 367 /** The framer thread. */ … … 797 800 * Update PCI IRQ levels 798 801 */ 799 static void ohciUpdateInterrupt (POHCI ohci, const char *msg)802 static void ohciUpdateInterruptLocked(POHCI ohci, const char *msg) 800 803 { 801 804 int level = 0; 802 803 #ifdef IN_RING3804 PDMCritSectEnter(ohci->pDevInsR3->pCritSectRoR3, VERR_IGNORED);805 #endif806 805 807 806 if ( (ohci->intr & OHCI_INTR_MASTER_INTERRUPT_ENABLED) … … 818 817 (val >> 6) & 1, (val >> 30) & 1, msg)); NOREF(val); NOREF(msg); 819 818 } 820 821 #ifdef IN_RING3822 PDMCritSectLeave(ohci->pDevInsR3->pCritSectRoR3);823 #endif824 819 } 825 820 … … 827 822 * Set an interrupt, use the wrapper ohciSetInterrupt. 828 823 */ 829 DECLINLINE(void) ohciSetInterruptInt(POHCI ohci, uint32_t intr, const char *msg) 830 { 831 if ( (ohci->intr_status & intr) == intr ) 832 return; 833 ohci->intr_status |= intr; 834 ohciUpdateInterrupt(ohci, msg); 824 DECLINLINE(int) ohciSetInterruptInt(POHCI ohci, int rcBusy, uint32_t intr, const char *msg) 825 { 826 int rc = VINF_SUCCESS; 827 828 rc = PDMCritSectEnter(&ohci->CsIrq, rcBusy); 829 if (rc != VINF_SUCCESS) 830 return rc; 831 832 if ( (ohci->intr_status & intr) != intr ) 833 { 834 ohci->intr_status |= intr; 835 ohciUpdateInterruptLocked(ohci, msg); 836 } 837 838 PDMCritSectLeave(&ohci->CsIrq); 839 return rc; 835 840 } 836 841 … … 838 843 * Set an interrupt wrapper macro for logging purposes. 839 844 */ 840 #define ohciSetInterrupt(ohci, intr) ohciSetInterruptInt(ohci, intr, #intr)841 845 #define ohciSetInterrupt(ohci, a_rcBusy, intr) ohciSetInterruptInt(ohci, a_rcBusy, intr, #intr) 846 #define ohciR3SetInterrupt(ohci, intr) ohciSetInterruptInt(ohci, VERR_IGNORED, intr, #intr) 842 847 843 848 #ifdef IN_RING3 … … 960 965 961 966 ohci_remote_wakeup(pThis); 962 ohci SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);967 ohciR3SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); 963 968 964 969 PDMCritSectLeave(pThis->pDevInsR3->pCritSectRoR3); … … 997 1002 998 1003 ohci_remote_wakeup(pThis); 999 ohci SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);1004 ohciR3SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); 1000 1005 1001 1006 PDMCritSectLeave(pThis->pDevInsR3->pCritSectRoR3); … … 3555 3560 ohciPhysWrite(pThis, pThis->hcca + OHCI_HCCA_OFS, (uint8_t *)&hcca, sizeof(hcca)); 3556 3561 if (fWriteDoneHeadInterrupt) 3557 ohci SetInterrupt(pThis, OHCI_INTR_WRITE_DONE_HEAD);3562 ohciR3SetInterrupt(pThis, OHCI_INTR_WRITE_DONE_HEAD); 3558 3563 } 3559 3564 … … 3701 3706 3702 3707 /* "After writing to HCCA, HC will set SF in HcInterruptStatus" - guest isn't executing, so ignore the order! */ 3703 ohci SetInterrupt(pThis, OHCI_INTR_START_OF_FRAME);3708 ohciR3SetInterrupt(pThis, OHCI_INTR_START_OF_FRAME); 3704 3709 3705 3710 if (pThis->fno) 3706 3711 { 3707 ohci SetInterrupt(pThis, OHCI_INTR_FRAMENUMBER_OVERFLOW);3712 ohciR3SetInterrupt(pThis, OHCI_INTR_FRAMENUMBER_OVERFLOW); 3708 3713 pThis->fno = 0; 3709 3714 } … … 3921 3926 3922 3927 if (fHardware && (pThis->ctl & OHCI_CTL_RWE)) 3923 ohci SetInterrupt(pThis, OHCI_INTR_RESUME_DETECT);3928 ohciR3SetInterrupt(pThis, OHCI_INTR_RESUME_DETECT); 3924 3929 3925 3930 ohciBusStart(pThis); … … 4127 4132 uint32_t res = pThis->intr_status & ~val; 4128 4133 uint32_t chg = pThis->intr_status ^ res; NOREF(chg); 4134 int rc = VINF_SUCCESS; 4135 4136 rc = PDMCritSectEnter(&pThis->CsIrq, VINF_IOM_R3_MMIO_WRITE); 4137 if (rc != VINF_SUCCESS) 4138 return rc; 4139 4129 4140 Log2(("HcInterruptStatus_w(%#010x) => %sSO=%d %sWDH=%d %sSF=%d %sRD=%d %sUE=%d %sFNO=%d %sRHSC=%d %sOC=%d\n", 4130 4141 val, … … 4145 4156 */ 4146 4157 pThis->intr_status &= ~val; 4147 ohciUpdateInterrupt(pThis, "HcInterruptStatus_w"); 4158 ohciUpdateInterruptLocked(pThis, "HcInterruptStatus_w"); 4159 PDMCritSectLeave(&pThis->CsIrq); 4148 4160 return VINF_SUCCESS; 4149 4161 } … … 4169 4181 uint32_t res = pThis->intr | val; 4170 4182 uint32_t chg = pThis->intr ^ res; NOREF(chg); 4183 int rc = VINF_SUCCESS; 4184 4185 rc = PDMCritSectEnter(&pThis->CsIrq, VINF_IOM_R3_MMIO_WRITE); 4186 if (rc != VINF_SUCCESS) 4187 return rc; 4188 4171 4189 Log2(("HcInterruptEnable_w(%#010x) => %sSO=%d %sWDH=%d %sSF=%d %sRD=%d %sUE=%d %sFNO=%d %sRHSC=%d %sOC=%d %sMIE=%d\n", 4172 4190 val, … … 4184 4202 4185 4203 pThis->intr |= val; 4186 ohciUpdateInterrupt(pThis, "HcInterruptEnable_w"); 4204 ohciUpdateInterruptLocked(pThis, "HcInterruptEnable_w"); 4205 PDMCritSectLeave(&pThis->CsIrq); 4187 4206 return VINF_SUCCESS; 4188 4207 } … … 4213 4232 uint32_t res = pThis->intr & ~val; 4214 4233 uint32_t chg = pThis->intr ^ res; NOREF(chg); 4234 int rc = VINF_SUCCESS; 4235 4236 rc = PDMCritSectEnter(&pThis->CsIrq, VINF_IOM_R3_MMIO_WRITE); 4237 if (rc != VINF_SUCCESS) 4238 return rc; 4239 4215 4240 Log2(("HcInterruptDisable_w(%#010x) => %sSO=%d %sWDH=%d %sSF=%d %sRD=%d %sUE=%d %sFNO=%d %sRHSC=%d %sOC=%d %sMIE=%d\n", 4216 4241 val, … … 4228 4253 4229 4254 pThis->intr &= ~val; 4230 ohciUpdateInterrupt(pThis, "HcInterruptDisable_w"); 4255 ohciUpdateInterruptLocked(pThis, "HcInterruptDisable_w"); 4256 PDMCritSectLeave(&pThis->CsIrq); 4231 4257 return VINF_SUCCESS; 4232 4258 } … … 4768 4794 4769 4795 /* Raise roothub status change interrupt. */ 4770 ohci SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);4796 ohciR3SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); 4771 4797 } 4772 4798 … … 4792 4818 { 4793 4819 pRh->aPorts[iPort].fReg |= OHCI_PORT_R_CONNECT_STATUS_CHANGE; 4794 ohci SetInterrupt(pRh->pOhci, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);4820 ohciR3SetInterrupt(pRh->pOhci, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); 4795 4821 return false; 4796 4822 } … … 4887 4913 pThis->RootHub.aPorts[i].fReg &= ~OHCI_PORT_R_SUSPEND_STATUS; 4888 4914 pThis->RootHub.aPorts[i].fReg |= OHCI_PORT_R_SUSPEND_STATUS_CHANGE; 4889 ohci SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE);4915 ohciR3SetInterrupt(pThis, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); 4890 4916 } 4891 4917 … … 5518 5544 RTSemEventDestroy(pThis->hSemEventFrame); 5519 5545 RTCritSectDelete(&pThis->CritSect); 5546 PDMR3CritSectDelete(&pThis->CsIrq); 5520 5547 5521 5548 /* … … 5664 5691 pThis->fBusStarted = false; 5665 5692 5693 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CsIrq, RT_SRC_POS, "OHCI#%uIrq", iInstance); 5694 if (RT_FAILURE(rc)) 5695 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 5696 N_("EHCI: Failed to create critical section")); 5697 5666 5698 rc = RTSemEventCreate(&pThis->hSemEventFrame); 5667 5699 AssertRCReturn(rc, rc); 5668 5700 5669 /* 5670 * Initialize the critical section without the lock validator. 5671 * This is necessary because USB devices attached to this controller 5672 * will be detached in the save state callback with the 5673 * per device PDM critical section held. If there are still URBs pending 5674 * for this device they will get reaped and cause a lock validator error 5675 * because they will take this critical section. 5676 * 5677 * The framer thread on the other hand will first take this critical section 5678 * during a run and might take the PDM critical section when issuing an interrupt. 5679 * Normally this is a real deadlock issue but we make sure 5680 * that the framer thread is not running when the save state handler is called. 5681 */ 5682 rc = RTCritSectInitEx(&pThis->CritSect, RTCRITSECT_FLAGS_NO_LOCK_VAL, 5683 NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_USER, "OhciCritSect"); 5701 rc = RTCritSectInit(&pThis->CritSect); 5684 5702 if (RT_FAILURE(rc)) 5685 5703 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r49814 r49958 1003 1003 GEN_CHECK_OFF(OHCI, hSemEventFrame); 1004 1004 GEN_CHECK_OFF(OHCI, fBusStarted); 1005 GEN_CHECK_OFF(OHCI, CsIrq); 1005 1006 GEN_CHECK_OFF(OHCI, nsWait); 1006 1007 GEN_CHECK_OFF(OHCI, CritSect); … … 1085 1086 GEN_CHECK_OFF(EHCI, hSemEventFrame); 1086 1087 GEN_CHECK_OFF(EHCI, fBusStarted); 1088 GEN_CHECK_OFF(EHCI, CsIrq); 1087 1089 GEN_CHECK_OFF(EHCI, nsWait); 1088 1090 GEN_CHECK_OFF(EHCI, CritSect);
Note:
See TracChangeset
for help on using the changeset viewer.