Changeset 59348 in vbox for trunk/src/VBox/Devices/Audio/DevIchHda.cpp
- Timestamp:
- Jan 14, 2016 2:48:08 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r59343 r59348 658 658 /** LUN to which this driver has been assigned. */ 659 659 uint8_t uLUN; 660 /** Audio connector interface to the underlying 661 * host backend. */ 660 /** Pointer to attached driver base interface. */ 661 R3PTRTYPE(PPDMIBASE) pDrvBase; 662 /** Audio connector interface to the underlying host backend. */ 662 663 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pConnector; 663 664 /** Stream for line input. */ … … 684 685 /** Padding for alignment. */ 685 686 uint32_t u32Padding; 686 /** Pointer to the attached audio driver. */687 R3PTRTYPE(PPDMIBASE) pDrvBase;688 687 /** The base interface for LUN\#0. */ 689 688 PDMIBASE IBase; … … 4323 4322 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 4324 4323 4325 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,4326 ("HDA device does not support hotplugging\n"),4327 VERR_INVALID_PARAMETER);4328 4329 4324 /* 4330 4325 * Attach driver. … … 4332 4327 char *pszDesc = NULL; 4333 4328 if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN#%u", uLUN) <= 0) 4334 AssertMsgReturn(pszDesc, 4335 ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN), 4336 VERR_NO_MEMORY); 4337 4329 AssertReleaseMsgReturn(pszDesc, 4330 ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN), 4331 VERR_NO_MEMORY); 4332 4333 PPDMIBASE pDrvBase; 4338 4334 int rc = PDMDevHlpDriverAttach(pDevIns, uLUN, 4339 &pThis->IBase, &p This->pDrvBase, pszDesc);4335 &pThis->IBase, &pDrvBase, pszDesc); 4340 4336 if (RT_SUCCESS(rc)) 4341 4337 { … … 4343 4339 if (pDrv) 4344 4340 { 4345 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 4341 pDrv->pDrvBase = pDrvBase; 4342 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR); 4346 4343 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc)); 4347 4344 pDrv->pHDAState = pThis; … … 4363 4360 rc = VERR_NO_MEMORY; 4364 4361 } 4365 else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER 4366 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME) 4362 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4367 4363 { 4368 4364 LogFunc(("No attached driver for LUN #%u\n", uLUN)); … … 4372 4368 uLUN, pszDesc, rc)); 4373 4369 4374 RTStrFree(pszDesc); 4370 if (RT_FAILURE(rc)) 4371 { 4372 /* Only free this string on failure; 4373 * must remain valid for the live of the driver instance. */ 4374 RTStrFree(pszDesc); 4375 } 4375 4376 4376 4377 LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc)); … … 4378 4379 } 4379 4380 4380 static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 4381 { 4382 NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags); 4383 4384 LogFlowFuncEnter(); 4381 static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 4382 { 4383 LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags)); 4384 } 4385 4386 static int hdaReattach(PHDASTATE pThis, PCFGMNODE pCfg, PHDADRIVER pDrv, const char *pszDriver) 4387 { 4388 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 4389 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 4390 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 4391 AssertPtrReturn(pszDriver, VERR_INVALID_POINTER); 4392 4393 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3); 4394 PCFGMNODE pRoot = CFGMR3GetRoot(pVM); 4395 PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/hda/0/"); 4396 4397 /* Remove LUN branch. */ 4398 CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN)); 4399 4400 int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */); 4401 if (RT_FAILURE(rc)) 4402 return rc; 4403 4404 #define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } 4405 4406 do 4407 { 4408 PCFGMNODE pLunL0; 4409 rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN); RC_CHECK(); 4410 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK(); 4411 rc = CFGMR3InsertNode(pLunL0, "Config/", NULL); RC_CHECK(); 4412 4413 PCFGMNODE pLunL1, pLunL2; 4414 rc = CFGMR3InsertNode (pLunL0, "AttachedDriver/", &pLunL1); RC_CHECK(); 4415 rc = CFGMR3InsertNode (pLunL1, "Config/", &pLunL2); RC_CHECK(); 4416 rc = CFGMR3InsertString(pLunL1, "Driver", pszDriver); RC_CHECK(); 4417 4418 rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver); RC_CHECK(); 4419 4420 } while (0); 4421 4422 if (RT_SUCCESS(rc)) 4423 rc = hdaAttach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */); 4424 4425 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc)); 4426 4427 #undef RC_CHECK 4428 4429 return rc; 4385 4430 } 4386 4431 … … 4388 4433 * @interface_method_impl{PDMDEVREG,pfnConstruct} 4389 4434 */ 4390 static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg Handle)4435 static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 4391 4436 { 4392 4437 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); … … 4397 4442 * Validations. 4398 4443 */ 4399 if (!CFGMR3AreValuesValid(pCfg Handle, "R0Enabled\0"4400 4401 4444 if (!CFGMR3AreValuesValid(pCfg, "R0Enabled\0" 4445 "RCEnabled\0" 4446 "TimerHz\0")) 4402 4447 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 4403 4448 N_ ("Invalid configuration for the Intel HDA device")); 4404 4449 4405 int rc = CFGMR3QueryBoolDef(pCfg Handle, "RCEnabled", &pThis->fRCEnabled, false);4450 int rc = CFGMR3QueryBoolDef(pCfg, "RCEnabled", &pThis->fRCEnabled, false); 4406 4451 if (RT_FAILURE(rc)) 4407 4452 return PDMDEV_SET_ERROR(pDevIns, rc, 4408 4453 N_("HDA configuration error: failed to read RCEnabled as boolean")); 4409 rc = CFGMR3QueryBoolDef(pCfg Handle, "R0Enabled", &pThis->fR0Enabled, false);4454 rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &pThis->fR0Enabled, false); 4410 4455 if (RT_FAILURE(rc)) 4411 4456 return PDMDEV_SET_ERROR(pDevIns, rc, … … 4413 4458 #ifndef VBOX_WITH_AUDIO_CALLBACKS 4414 4459 uint16_t uTimerHz; 4415 rc = CFGMR3QueryU16Def(pCfg Handle, "TimerHz", &uTimerHz, 200 /* Hz */);4460 rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */); 4416 4461 if (RT_FAILURE(rc)) 4417 4462 return PDMDEV_SET_ERROR(pDevIns, rc, … … 4540 4585 { 4541 4586 LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN)); 4542 rc = hdaAttach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);4587 rc = hdaAttach(pDevIns, uLUN, 0 /* fFlags */); 4543 4588 if (RT_FAILURE(rc)) 4544 4589 { … … 4607 4652 4608 4653 /* Construct the codec. */ 4609 rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg Handle);4654 rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg); 4610 4655 if (RT_FAILURE(rc)) 4611 4656 AssertRCReturn(rc, rc); … … 4629 4674 rc = hdaStreamCreate(&pThis->StrmStOut); 4630 4675 AssertRC(rc); 4676 4677 PHDADRIVER pDrv; 4678 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 4679 { 4680 /* 4681 * Only primary drivers are critical for the VM to run. Everything else 4682 * might not worth showing an own error message box in the GUI. 4683 */ 4684 if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY)) 4685 continue; 4686 4687 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 4688 AssertPtr(pCon); 4689 4690 uint8_t cFailed = 0; 4691 if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn)) 4692 cFailed++; 4693 #ifdef VBOX_WITH_HDA_MIC_IN 4694 if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn)) 4695 cFailed++; 4696 #endif 4697 if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut)) 4698 cFailed++; 4699 4700 #ifdef VBOX_WITH_HDA_MIC_IN 4701 if (cFailed == 3) 4702 #else 4703 if (cFailed == 2) 4704 #endif 4705 { 4706 LogRel(("HDA: Falling back to NULL backend (no sound audible)\n")); 4707 4708 hdaReset(pDevIns); 4709 hdaReattach(pThis, pCfg, pDrv, "NullAudio"); 4710 4711 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4712 N_("No audio devices could be opened. Selecting the NULL audio backend " 4713 "with the consequence that no sound is audible")); 4714 } 4715 else if (cFailed) 4716 { 4717 if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->LineIn.pStrmIn)) 4718 LogRel(("HDA: WARNING: Unable to open PCM line input for LUN #%RU32!\n", pDrv->uLUN)); 4719 #ifdef VBOX_WITH_HDA_MIC_IN 4720 if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->MicIn.pStrmIn)) 4721 LogRel(("HDA: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", pDrv->uLUN)); 4722 #endif 4723 if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut)) 4724 LogRel(("HDA: WARNING: Unable to open PCM output for LUN #%RU32!\n", pDrv->uLUN)); 4725 4726 char szMissingStreams[255]; 4727 size_t len = 0; 4728 if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn)) 4729 len = RTStrPrintf(szMissingStreams, 4730 sizeof(szMissingStreams), "PCM Input"); 4731 #ifdef VBOX_WITH_HDA_MIC_IN 4732 if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn)) 4733 len += RTStrPrintf(szMissingStreams + len, 4734 sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone"); 4735 #endif 4736 if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut)) 4737 len += RTStrPrintf(szMissingStreams + len, 4738 sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output"); 4739 4740 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4741 N_("Some HDA audio streams (%s) could not be opened. Guest applications generating audio " 4742 "output or depending on audio input may hang. Make sure your host audio device " 4743 "is working properly. Check the logfile for error messages of the audio " 4744 "subsystem"), szMissingStreams); 4745 } 4746 } 4631 4747 } 4632 4748 … … 4819 4935 NULL, 4820 4936 /* pfnAttach */ 4821 NULL,4937 hdaAttach, 4822 4938 /* pfnDetach */ 4823 NULL,4939 hdaDetach, 4824 4940 /* pfnQueryInterface. */ 4825 4941 NULL,
Note:
See TracChangeset
for help on using the changeset viewer.