Changeset 71762 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Apr 9, 2018 10:43:14 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r71748 r71762 220 220 * Internal Functions * 221 221 *********************************************************************************************************************************/ 222 static int sb16CreateDrvStream(PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg, PSB16DRIVER pDrv);223 static void sb16DestroyDrvStream(PSB16STATE pThis, PSB16DRIVER pDrv);224 222 static int sb16OpenOut(PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg); 225 223 static void sb16CloseOut(PSB16STATE pThis); … … 230 228 231 229 232 233 /**234 * Attach command, internal version.235 *236 * This is called to let the device attach to a driver for a specified LUN237 * during runtime. This is not called during VM construction, the device238 * constructor has to attach to all the available drivers.239 *240 * @returns VBox status code.241 * @param pThis SB16 state.242 * @param uLUN The logical unit which is being detached.243 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.244 * @param ppDrv Attached driver instance on success. Optional.245 */246 static int sb16AttachInternal(PSB16STATE pThis, unsigned uLUN, uint32_t fFlags, PSB16DRIVER *ppDrv)247 {248 RT_NOREF(fFlags);249 250 /*251 * Attach driver.252 */253 char *pszDesc;254 if (RTStrAPrintf(&pszDesc, "Audio driver port (SB16) for LUN #%u", uLUN) <= 0)255 AssertLogRelFailedReturn(VERR_NO_MEMORY);256 257 PPDMIBASE pDrvBase;258 int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN,259 &pThis->IBase, &pDrvBase, pszDesc);260 if (RT_SUCCESS(rc))261 {262 PSB16DRIVER pDrv = (PSB16DRIVER)RTMemAllocZ(sizeof(SB16DRIVER));263 if (pDrv)264 {265 pDrv->pDrvBase = pDrvBase;266 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);267 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));268 pDrv->pSB16State = pThis;269 pDrv->uLUN = uLUN;270 271 /*272 * For now we always set the driver at LUN 0 as our primary273 * host backend. This might change in the future.274 */275 if (pDrv->uLUN == 0)276 pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;277 278 LogFunc(("LUN#%RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));279 280 /* Attach to driver list if not attached yet. */281 if (!pDrv->fAttached)282 {283 RTListAppend(&pThis->lstDrv, &pDrv->Node);284 pDrv->fAttached = true;285 }286 287 if (ppDrv)288 *ppDrv = pDrv;289 }290 else291 rc = VERR_NO_MEMORY;292 }293 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)294 LogFunc(("No attached driver for LUN #%u\n", uLUN));295 296 if (RT_FAILURE(rc))297 {298 /* Only free this string on failure;299 * must remain valid for the live of the driver instance. */300 RTStrFree(pszDesc);301 }302 303 LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));304 return rc;305 }306 307 /**308 * Detach command, internal version.309 *310 * This is called to let the device detach from a driver for a specified LUN311 * during runtime.312 *313 * @returns VBox status code.314 * @param pThis SB16 state.315 * @param pDrv Driver to detach device from.316 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.317 */318 static int sb16DetachInternal(PSB16STATE pThis, PSB16DRIVER pDrv, uint32_t fFlags)319 {320 RT_NOREF(fFlags);321 322 sb16DestroyDrvStream(pThis, pDrv);323 324 RTListNodeRemove(&pDrv->Node);325 326 LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));327 return VINF_SUCCESS;328 }329 330 /**331 * @interface_method_impl{PDMDEVREG,pfnAttach}332 */333 static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)334 {335 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);336 337 LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));338 339 PSB16DRIVER pDrv;340 int rc2 = sb16AttachInternal(pThis, uLUN, fFlags, &pDrv);341 if (RT_SUCCESS(rc2))342 rc2 = sb16CreateDrvStream(pThis, &pThis->Out.Cfg, pDrv);343 344 return VINF_SUCCESS;345 }346 347 /**348 * @interface_method_impl{PDMDEVREG,pfnDetach}349 */350 static DECLCALLBACK(void) sb16Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)351 {352 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);353 354 LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));355 356 PSB16DRIVER pDrv, pDrvNext;357 RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, SB16DRIVER, Node)358 {359 if (pDrv->uLUN == uLUN)360 {361 int rc2 = sb16DetachInternal(pThis, pDrv, fFlags);362 if (RT_SUCCESS(rc2))363 {364 RTMemFree(pDrv);365 pDrv = NULL;366 }367 368 break;369 }370 }371 }372 373 /**374 * Re-attaches (replaces) a driver with a new driver.375 *376 * @returns VBox status code.377 * @param pThis Device instance.378 * @param pDrv Driver instance used for attaching to.379 * If NULL is specified, a new driver will be created and appended380 * to the driver list.381 * @param uLUN The logical unit which is being re-detached.382 * @param pszDriver New driver name to attach.383 */384 static int sb16Reattach(PSB16STATE pThis, PSB16DRIVER pDrv, uint8_t uLUN, const char *pszDriver)385 {386 AssertPtrReturn(pThis, VERR_INVALID_POINTER);387 AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);388 389 int rc;390 391 if (pDrv)392 {393 rc = sb16DetachInternal(pThis, pDrv, 0 /* fFlags */);394 if (RT_SUCCESS(rc))395 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);396 397 if (RT_FAILURE(rc))398 return rc;399 400 pDrv = NULL;401 }402 403 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);404 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);405 PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/sb16/0/");406 407 /* Remove LUN branch. */408 CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN));409 410 if (pDrv)411 {412 /* Re-use the driver instance so detach it before. */413 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);414 if (RT_FAILURE(rc))415 return rc;416 }417 418 #define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }419 420 do421 {422 PCFGMNODE pLunL0;423 rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", uLUN); RC_CHECK();424 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK();425 rc = CFGMR3InsertNode(pLunL0, "Config/", NULL); RC_CHECK();426 427 PCFGMNODE pLunL1, pLunL2;428 rc = CFGMR3InsertNode (pLunL0, "AttachedDriver/", &pLunL1); RC_CHECK();429 rc = CFGMR3InsertNode (pLunL1, "Config/", &pLunL2); RC_CHECK();430 rc = CFGMR3InsertString(pLunL1, "Driver", pszDriver); RC_CHECK();431 432 rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver); RC_CHECK();433 434 } while (0);435 436 if (RT_SUCCESS(rc))437 rc = sb16AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);438 439 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc));440 441 #undef RC_CHECK442 443 return rc;444 }445 230 446 231 static int magic_of_irq(int irq) … … 2416 2201 } 2417 2202 2203 2204 /** 2205 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 2206 */ 2207 static DECLCALLBACK(void *) sb16QueryInterface(struct PDMIBASE *pInterface, const char *pszIID) 2208 { 2209 PSB16STATE pThis = RT_FROM_MEMBER(pInterface, SB16STATE, IBase); 2210 Assert(&pThis->IBase == pInterface); 2211 2212 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase); 2213 return NULL; 2214 } 2215 2216 2217 /** 2218 * Attach command, internal version. 2219 * 2220 * This is called to let the device attach to a driver for a specified LUN 2221 * during runtime. This is not called during VM construction, the device 2222 * constructor has to attach to all the available drivers. 2223 * 2224 * @returns VBox status code. 2225 * @param pThis SB16 state. 2226 * @param uLUN The logical unit which is being detached. 2227 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 2228 * @param ppDrv Attached driver instance on success. Optional. 2229 */ 2230 static int sb16AttachInternal(PSB16STATE pThis, unsigned uLUN, uint32_t fFlags, PSB16DRIVER *ppDrv) 2231 { 2232 RT_NOREF(fFlags); 2233 2234 /* 2235 * Attach driver. 2236 */ 2237 char *pszDesc; 2238 if (RTStrAPrintf(&pszDesc, "Audio driver port (SB16) for LUN #%u", uLUN) <= 0) 2239 AssertLogRelFailedReturn(VERR_NO_MEMORY); 2240 2241 PPDMIBASE pDrvBase; 2242 int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN, 2243 &pThis->IBase, &pDrvBase, pszDesc); 2244 if (RT_SUCCESS(rc)) 2245 { 2246 PSB16DRIVER pDrv = (PSB16DRIVER)RTMemAllocZ(sizeof(SB16DRIVER)); 2247 if (pDrv) 2248 { 2249 pDrv->pDrvBase = pDrvBase; 2250 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR); 2251 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc)); 2252 pDrv->pSB16State = pThis; 2253 pDrv->uLUN = uLUN; 2254 2255 /* 2256 * For now we always set the driver at LUN 0 as our primary 2257 * host backend. This might change in the future. 2258 */ 2259 if (pDrv->uLUN == 0) 2260 pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY; 2261 2262 LogFunc(("LUN#%RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags)); 2263 2264 /* Attach to driver list if not attached yet. */ 2265 if (!pDrv->fAttached) 2266 { 2267 RTListAppend(&pThis->lstDrv, &pDrv->Node); 2268 pDrv->fAttached = true; 2269 } 2270 2271 if (ppDrv) 2272 *ppDrv = pDrv; 2273 } 2274 else 2275 rc = VERR_NO_MEMORY; 2276 } 2277 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2278 LogFunc(("No attached driver for LUN #%u\n", uLUN)); 2279 2280 if (RT_FAILURE(rc)) 2281 { 2282 /* Only free this string on failure; 2283 * must remain valid for the live of the driver instance. */ 2284 RTStrFree(pszDesc); 2285 } 2286 2287 LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc)); 2288 return rc; 2289 } 2290 2291 /** 2292 * Detach command, internal version. 2293 * 2294 * This is called to let the device detach from a driver for a specified LUN 2295 * during runtime. 2296 * 2297 * @returns VBox status code. 2298 * @param pThis SB16 state. 2299 * @param pDrv Driver to detach device from. 2300 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 2301 */ 2302 static int sb16DetachInternal(PSB16STATE pThis, PSB16DRIVER pDrv, uint32_t fFlags) 2303 { 2304 RT_NOREF(fFlags); 2305 2306 sb16DestroyDrvStream(pThis, pDrv); 2307 2308 RTListNodeRemove(&pDrv->Node); 2309 2310 LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags)); 2311 return VINF_SUCCESS; 2312 } 2313 2314 /** 2315 * @interface_method_impl{PDMDEVREG,pfnAttach} 2316 */ 2317 static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 2318 { 2319 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE); 2320 2321 LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags)); 2322 2323 PSB16DRIVER pDrv; 2324 int rc2 = sb16AttachInternal(pThis, uLUN, fFlags, &pDrv); 2325 if (RT_SUCCESS(rc2)) 2326 rc2 = sb16CreateDrvStream(pThis, &pThis->Out.Cfg, pDrv); 2327 2328 return VINF_SUCCESS; 2329 } 2330 2331 /** 2332 * @interface_method_impl{PDMDEVREG,pfnDetach} 2333 */ 2334 static DECLCALLBACK(void) sb16Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 2335 { 2336 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE); 2337 2338 LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags)); 2339 2340 PSB16DRIVER pDrv, pDrvNext; 2341 RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, SB16DRIVER, Node) 2342 { 2343 if (pDrv->uLUN == uLUN) 2344 { 2345 int rc2 = sb16DetachInternal(pThis, pDrv, fFlags); 2346 if (RT_SUCCESS(rc2)) 2347 { 2348 RTMemFree(pDrv); 2349 pDrv = NULL; 2350 } 2351 2352 break; 2353 } 2354 } 2355 } 2356 2357 /** 2358 * Re-attaches (replaces) a driver with a new driver. 2359 * 2360 * @returns VBox status code. 2361 * @param pThis Device instance. 2362 * @param pDrv Driver instance used for attaching to. 2363 * If NULL is specified, a new driver will be created and appended 2364 * to the driver list. 2365 * @param uLUN The logical unit which is being re-detached. 2366 * @param pszDriver New driver name to attach. 2367 */ 2368 static int sb16Reattach(PSB16STATE pThis, PSB16DRIVER pDrv, uint8_t uLUN, const char *pszDriver) 2369 { 2370 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2371 AssertPtrReturn(pszDriver, VERR_INVALID_POINTER); 2372 2373 int rc; 2374 2375 if (pDrv) 2376 { 2377 rc = sb16DetachInternal(pThis, pDrv, 0 /* fFlags */); 2378 if (RT_SUCCESS(rc)) 2379 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */); 2380 2381 if (RT_FAILURE(rc)) 2382 return rc; 2383 2384 pDrv = NULL; 2385 } 2386 2387 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3); 2388 PCFGMNODE pRoot = CFGMR3GetRoot(pVM); 2389 PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/sb16/0/"); 2390 2391 /* Remove LUN branch. */ 2392 CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN)); 2393 2394 if (pDrv) 2395 { 2396 /* Re-use the driver instance so detach it before. */ 2397 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */); 2398 if (RT_FAILURE(rc)) 2399 return rc; 2400 } 2401 2402 #define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } 2403 2404 do 2405 { 2406 PCFGMNODE pLunL0; 2407 rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", uLUN); RC_CHECK(); 2408 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK(); 2409 rc = CFGMR3InsertNode(pLunL0, "Config/", NULL); RC_CHECK(); 2410 2411 PCFGMNODE pLunL1, pLunL2; 2412 rc = CFGMR3InsertNode (pLunL0, "AttachedDriver/", &pLunL1); RC_CHECK(); 2413 rc = CFGMR3InsertNode (pLunL1, "Config/", &pLunL2); RC_CHECK(); 2414 rc = CFGMR3InsertString(pLunL1, "Driver", pszDriver); RC_CHECK(); 2415 2416 rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver); RC_CHECK(); 2417 2418 } while (0); 2419 2420 if (RT_SUCCESS(rc)) 2421 rc = sb16AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 2422 2423 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc)); 2424 2425 #undef RC_CHECK 2426 2427 return rc; 2428 } 2429 2418 2430 /** 2419 2431 * @interface_method_impl{PDMDEVREG,pfnReset} … … 2447 2459 sb16Control(pThis, 0); 2448 2460 sb16ResetLegacy(pThis); 2449 }2450 2451 /**2452 * @interface_method_impl{PDMIBASE,pfnQueryInterface}2453 */2454 static DECLCALLBACK(void *) sb16QueryInterface(struct PDMIBASE *pInterface, const char *pszIID)2455 {2456 PSB16STATE pThis = RT_FROM_MEMBER(pInterface, SB16STATE, IBase);2457 Assert(&pThis->IBase == pInterface);2458 2459 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);2460 return NULL;2461 2461 } 2462 2462 … … 2782 2782 PDM_DEVREG_VERSION 2783 2783 }; 2784
Note:
See TracChangeset
for help on using the changeset viewer.