Index: trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88288)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88289)
@@ -122,5 +122,5 @@
 static uint32_t lsbindex(uint32_t u)
 {
-    return popcount ((u&-u)-1);
+    return popcount((u & -u) - 1);
 }
 
@@ -170,6 +170,6 @@
     if (close(*phFile))
     {
-        LogRel(("OSS: Closing stream failed: %s\n", strerror(errno)));
-        rc = VERR_GENERAL_FAILURE; /** @todo */
+        rc = RTErrConvertFromErrno(errno);
+        LogRel(("OSS: Closing stream failed: %s / %Rrc\n", strerror(errno), rc));
     }
     else
@@ -180,4 +180,100 @@
 
     return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnInit}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_Init(PPDMIHOSTAUDIO pInterface)
+{
+    RT_NOREF(pInterface);
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnShutdown}
+ */
+static DECLCALLBACK(void) drvHostOssAudioHA_Shutdown(PPDMIHOSTAUDIO pInterface)
+{
+    RT_NOREF(pInterface);
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
+{
+    RT_NOREF(pInterface);
+
+    RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "OSS");
+
+    pBackendCfg->cbStreamIn  = sizeof(OSSAUDIOSTREAM);
+    pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM);
+
+    int hFile = open("/dev/dsp", O_WRONLY | O_NONBLOCK, 0);
+    if (hFile == -1)
+    {
+        /* Try opening the mixing device instead. */
+        hFile = open("/dev/mixer", O_RDONLY | O_NONBLOCK, 0);
+    }
+    if (hFile != -1)
+    {
+        int ossVer = -1;
+        int err = ioctl(hFile, OSS_GETVERSION, &ossVer);
+        if (err == 0)
+        {
+            LogRel2(("OSS: Using version: %d\n", ossVer));
+#ifdef VBOX_WITH_AUDIO_OSS_SYSINFO
+            oss_sysinfo ossInfo;
+            RT_ZERO(ossInfo);
+            err = ioctl(hFile, OSS_SYSINFO, &ossInfo);
+            if (err == 0)
+            {
+                LogRel2(("OSS: Number of DSPs: %d\n", ossInfo.numaudios));
+                LogRel2(("OSS: Number of mixers: %d\n", ossInfo.nummixers));
+
+                int cDev = ossInfo.nummixers;
+                if (!cDev)
+                    cDev = ossInfo.numaudios;
+
+                pBackendCfg->cMaxStreamsIn   = UINT32_MAX;
+                pBackendCfg->cMaxStreamsOut  = UINT32_MAX;
+            }
+            else
+#endif
+            {
+                /* Since we cannot query anything, assume that we have at least
+                 * one input and one output if we found "/dev/dsp" or "/dev/mixer". */
+
+                pBackendCfg->cMaxStreamsIn   = UINT32_MAX;
+                pBackendCfg->cMaxStreamsOut  = UINT32_MAX;
+            }
+        }
+        else
+            LogRel(("OSS: Unable to determine installed version: %s (%d)\n", strerror(err), err));
+        close(hFile);
+    }
+    else
+        LogRel(("OSS: No devices found, audio is not available\n"));
+
+    return VINF_SUCCESS;
+}
+
+
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
+ */
+static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostOssAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
+{
+    AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
+    RT_NOREF(enmDir);
+
+    return PDMAUDIOBACKENDSTS_RUNNING;
 }
 
@@ -293,4 +389,133 @@
 
 
+static int ossCreateStreamIn(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
+{
+    int rc;
+
+    int hFile = -1;
+
+    do
+    {
+        OSSAUDIOSTREAMCFG ossReq;
+        memcpy(&ossReq.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
+
+        ossReq.cFragments     = s_OSSConf.nfrags;
+        ossReq.cbFragmentSize = s_OSSConf.fragsize;
+
+        OSSAUDIOSTREAMCFG ossAcq;
+        RT_ZERO(ossAcq);
+
+        rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile);
+        if (RT_SUCCESS(rc))
+        {
+            memcpy(&pCfgAcq->Props, &ossAcq.Props, sizeof(PDMAUDIOPCMPROPS));
+
+            if (ossAcq.cFragments * ossAcq.cbFragmentSize & pStreamOSS->uAlign)
+            {
+                LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n",
+                        ossAcq.cFragments * ossAcq.cbFragmentSize, pStreamOSS->uAlign + 1));
+            }
+
+            if (RT_SUCCESS(rc))
+            {
+                pStreamOSS->hFile = hFile;
+
+                pCfgAcq->Backend.cFramesPeriod     = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, ossAcq.cbFragmentSize);
+                pCfgAcq->Backend.cFramesBufferSize = pCfgAcq->Backend.cFramesPeriod * 2; /* Use "double buffering". */
+                /** @todo Pre-buffering required? */
+            }
+        }
+
+    } while (0);
+
+    if (RT_FAILURE(rc))
+        ossStreamClose(&hFile);
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+
+static int ossCreateStreamOut(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
+{
+    OSSAUDIOSTREAMCFG reqStream;
+    RT_ZERO(reqStream);
+
+    memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
+    reqStream.cFragments     = s_OSSConf.nfrags;
+    reqStream.cbFragmentSize = s_OSSConf.fragsize;
+
+    OSSAUDIOSTREAMCFG obtStream;
+    RT_ZERO(obtStream);
+
+    int hFile = -1;
+    int rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY, &reqStream, &obtStream, &hFile);
+    if (RT_SUCCESS(rc))
+    {
+        memcpy(&pCfgAcq->Props, &obtStream.Props, sizeof(PDMAUDIOPCMPROPS));
+
+        if ((obtStream.cFragments * obtStream.cbFragmentSize) & pStreamOSS->uAlign)
+            LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n",
+                    obtStream.cFragments * obtStream.cbFragmentSize, pStreamOSS->uAlign + 1));
+
+        pStreamOSS->hFile = hFile;
+
+        pCfgAcq->Backend.cFramesPeriod     = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, obtStream.cbFragmentSize);
+        pCfgAcq->Backend.cFramesBufferSize = pCfgAcq->Backend.cFramesPeriod * 2; /* Use "double buffering" */
+
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                        PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
+{
+    AssertPtr(pInterface);
+    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamOSS, VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
+
+    pStreamOSS->pCfg = PDMAudioStrmCfgDup(pCfgAcq);
+    AssertReturn(pStreamOSS->pCfg, VERR_NO_MEMORY);
+
+    int rc;
+    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
+        rc = ossCreateStreamIn( pStreamOSS, pCfgReq, pCfgAcq);
+    else
+        rc = ossCreateStreamOut(pStreamOSS, pCfgReq, pCfgAcq);
+
+    if (RT_FAILURE(rc))
+    {
+        PDMAudioStrmCfgFree(pStreamOSS->pCfg);
+        pStreamOSS->pCfg = NULL;
+    }
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamOSS, VERR_INVALID_POINTER);
+
+    ossStreamClose(&pStreamOSS->hFile);
+    PDMAudioStrmCfgFree(pStreamOSS->pCfg);
+    pStreamOSS->pCfg = NULL;
+
+    return VINF_SUCCESS;
+}
+
+
 static int ossControlStreamIn(/*PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd*/ void)
 {
@@ -345,10 +570,152 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnInit}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_Init(PPDMIHOSTAUDIO pInterface)
-{
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                         PDMAUDIOSTREAMCMD enmStreamCmd)
+{
+    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
+    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
+
+    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
+
+    if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */
+        return VINF_SUCCESS;
+
+    int rc;
+    if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN)
+        rc = ossControlStreamIn(/*pInterface,  pStream, enmStreamCmd*/);
+    else
+        rc = ossControlStreamOut(pStreamOSS, enmStreamCmd);
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
+ */
+static DECLCALLBACK(uint32_t) drvHostOssAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface, pStream);
+    return UINT32_MAX;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
+ */
+static DECLCALLBACK(uint32_t) drvHostOssAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+{
+    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
+    AssertPtr(pStreamOSS);
     RT_NOREF(pInterface);
 
+    /*
+     * Note! This logic was found in StreamPlay and corrected a little.
+     *
+     * The logic here must match what StreamPlay does.
+     */
+    audio_buf_info abinfo = { 0, 0, 0, 0 };
+    int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
+    AssertMsgReturn(rc2 >= 0, ("SNDCTL_DSP_GETOSPACE failed: %s (%d)\n", strerror(errno), errno), 0);
+
+#if 0 /** @todo we could return abinfo.bytes here iff StreamPlay didn't use the fragmented approach */
+    /** @todo r=bird: WTF do we make a fuss over abinfo.bytes for when we don't even use it?!? */
+    AssertLogRelMsgReturn(abinfo.bytes >= 0, ("OSS: Warning: Invalid available size: %d\n", abinfo.bytes), VERR_INTERNAL_ERROR_3);
+    if ((unsigned)abinfo.bytes > cbBuf)
+    {
+        LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf));
+        abinfo.bytes = cbBuf;
+        /* Keep going. */
+    }
+#endif
+
+    return (uint32_t)(abinfo.fragments * abinfo.fragsize);
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
+ */
+static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostOssAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface, pStream);
+    return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_StreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+{
+    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
+    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
+
+    LogFlowFuncEnter();
+
+    /* Nothing to do here for OSS. */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
+ */
+static DECLCALLBACK(int) drvHostOssAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                      const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
+{
+    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamOSS, VERR_INVALID_POINTER);
+    RT_NOREF(pInterface);
+
+    /*
+     * Figure out now much to write.
+     */
+    uint32_t cbToWrite;
+    audio_buf_info abinfo;
+    int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
+    AssertLogRelMsgReturn(rc2 >= 0, ("OSS: Failed to retrieve current playback buffer: %s (%d)\n", strerror(errno), errno),
+                          RTErrConvertFromErrno(errno));
+
+#if 0   /** @todo r=bird: WTF do we make a fuss over abinfo.bytes for when we don't even use it?!? */
+    AssertLogRelMsgReturn(abinfo.bytes >= 0, ("OSS: Warning: Invalid available size: %d\n", abinfo.bytes), VERR_INTERNAL_ERROR_3);
+    if ((unsigned)abinfo.bytes > cbBuf)
+    {
+        LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf));
+        abinfo.bytes = cbBuf;
+        /* Keep going. */
+    }
+#endif
+    cbToWrite = (unsigned)(abinfo.fragments * abinfo.fragsize);
+    cbToWrite = RT_MIN(cbToWrite, cbBuf);
+
+    /*
+     * Write.
+     */
+    uint8_t const *pbBuf    = (uint8_t const *)pvBuf;
+    uint32_t       cbChunk  = cbToWrite;
+    uint32_t       offChunk = 0;
+    while (cbChunk > 0)
+    {
+        ssize_t cbWritten = write(pStreamOSS->hFile, &pbBuf[offChunk], RT_MIN(cbChunk, (unsigned)s_OSSConf.fragsize));
+        if (cbWritten >= 0)
+        {
+            AssertLogRelMsg(!(cbWritten & pStreamOSS->uAlign),
+                            ("OSS: Misaligned write (written %#zx, alignment %#x)\n", cbWritten, pStreamOSS->uAlign));
+
+            Assert((uint32_t)cbWritten <= cbChunk);
+            offChunk += (uint32_t)cbWritten;
+            cbChunk  -= (uint32_t)cbWritten;
+        }
+        else
+        {
+            LogRel(("OSS: Failed writing output data: %s (%d)\n", strerror(errno), errno));
+            return RTErrConvertFromErrno(errno);
+        }
+    }
+
+    *pcbWritten = cbToWrite;
     return VINF_SUCCESS;
 }
@@ -403,410 +770,4 @@
 
 
-static int ossDestroyStreamIn(PPDMAUDIOBACKENDSTREAM pStream)
-{
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-
-    LogFlowFuncEnter();
-
-    ossStreamClose(&pStreamOSS->hFile);
-
-    return VINF_SUCCESS;
-}
-
-
-static int ossDestroyStreamOut(PPDMAUDIOBACKENDSTREAM pStream)
-{
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-
-    ossStreamClose(&pStreamOSS->hFile);
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
-{
-    RT_NOREF(pInterface);
-
-    RTStrPrintf2(pBackendCfg->szName, sizeof(pBackendCfg->szName), "OSS");
-
-    pBackendCfg->cbStreamIn  = sizeof(OSSAUDIOSTREAM);
-    pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM);
-
-    int hFile = open("/dev/dsp", O_WRONLY | O_NONBLOCK, 0);
-    if (hFile == -1)
-    {
-        /* Try opening the mixing device instead. */
-        hFile = open("/dev/mixer", O_RDONLY | O_NONBLOCK, 0);
-    }
-
-    int ossVer = -1;
-
-#ifdef VBOX_WITH_AUDIO_OSS_SYSINFO
-    oss_sysinfo ossInfo;
-    RT_ZERO(ossInfo);
-#endif
-
-    if (hFile != -1)
-    {
-        int err = ioctl(hFile, OSS_GETVERSION, &ossVer);
-        if (err == 0)
-        {
-            LogRel2(("OSS: Using version: %d\n", ossVer));
-#ifdef VBOX_WITH_AUDIO_OSS_SYSINFO
-            err = ioctl(hFile, OSS_SYSINFO, &ossInfo);
-            if (err == 0)
-            {
-                LogRel2(("OSS: Number of DSPs: %d\n", ossInfo.numaudios));
-                LogRel2(("OSS: Number of mixers: %d\n", ossInfo.nummixers));
-
-                int cDev = ossInfo.nummixers;
-                if (!cDev)
-                    cDev = ossInfo.numaudios;
-
-                pBackendCfg->cMaxStreamsIn   = UINT32_MAX;
-                pBackendCfg->cMaxStreamsOut  = UINT32_MAX;
-            }
-            else
-            {
-#endif
-                /* Since we cannot query anything, assume that we have at least
-                 * one input and one output if we found "/dev/dsp" or "/dev/mixer". */
-
-                pBackendCfg->cMaxStreamsIn   = UINT32_MAX;
-                pBackendCfg->cMaxStreamsOut  = UINT32_MAX;
-#ifdef VBOX_WITH_AUDIO_OSS_SYSINFO
-            }
-#endif
-        }
-        else
-            LogRel(("OSS: Unable to determine installed version: %s (%d)\n", strerror(err), err));
-    }
-    else
-        LogRel(("OSS: No devices found, audio is not available\n"));
-
-    if (hFile != -1)
-        close(hFile);
-
-    return VINF_SUCCESS;
-}
-
-
-static int ossCreateStreamIn(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
-{
-    int rc;
-
-    int hFile = -1;
-
-    do
-    {
-        OSSAUDIOSTREAMCFG ossReq;
-        memcpy(&ossReq.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
-
-        ossReq.cFragments     = s_OSSConf.nfrags;
-        ossReq.cbFragmentSize = s_OSSConf.fragsize;
-
-        OSSAUDIOSTREAMCFG ossAcq;
-        RT_ZERO(ossAcq);
-
-        rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile);
-        if (RT_SUCCESS(rc))
-        {
-            memcpy(&pCfgAcq->Props, &ossAcq.Props, sizeof(PDMAUDIOPCMPROPS));
-
-            if (ossAcq.cFragments * ossAcq.cbFragmentSize & pStreamOSS->uAlign)
-            {
-                LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n",
-                        ossAcq.cFragments * ossAcq.cbFragmentSize, pStreamOSS->uAlign + 1));
-            }
-
-            if (RT_SUCCESS(rc))
-            {
-                pStreamOSS->hFile = hFile;
-
-                pCfgAcq->Backend.cFramesPeriod     = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, ossAcq.cbFragmentSize);
-                pCfgAcq->Backend.cFramesBufferSize = pCfgAcq->Backend.cFramesPeriod * 2; /* Use "double buffering". */
-                /** @todo Pre-buffering required? */
-            }
-        }
-
-    } while (0);
-
-    if (RT_FAILURE(rc))
-        ossStreamClose(&hFile);
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-
-static int ossCreateStreamOut(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
-{
-    OSSAUDIOSTREAMCFG reqStream;
-    RT_ZERO(reqStream);
-
-    memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
-    reqStream.cFragments     = s_OSSConf.nfrags;
-    reqStream.cbFragmentSize = s_OSSConf.fragsize;
-
-    OSSAUDIOSTREAMCFG obtStream;
-    RT_ZERO(obtStream);
-
-    int hFile = -1;
-    int rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY, &reqStream, &obtStream, &hFile);
-    if (RT_SUCCESS(rc))
-    {
-        memcpy(&pCfgAcq->Props, &obtStream.Props, sizeof(PDMAUDIOPCMPROPS));
-
-        if ((obtStream.cFragments * obtStream.cbFragmentSize) & pStreamOSS->uAlign)
-            LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n",
-                    obtStream.cFragments * obtStream.cbFragmentSize, pStreamOSS->uAlign + 1));
-
-        pStreamOSS->hFile = hFile;
-
-        pCfgAcq->Backend.cFramesPeriod     = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, obtStream.cbFragmentSize);
-        pCfgAcq->Backend.cFramesBufferSize = pCfgAcq->Backend.cFramesPeriod * 2; /* Use "double buffering" */
-
-    }
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                      const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
-{
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-    AssertPtrReturn(pStreamOSS, VERR_INVALID_POINTER);
-    RT_NOREF(pInterface);
-
-    /*
-     * Figure out now much to write.
-     */
-    uint32_t cbToWrite;
-    audio_buf_info abinfo;
-    int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
-    AssertLogRelMsgReturn(rc2 >= 0, ("OSS: Failed to retrieve current playback buffer: %s (%d)\n", strerror(errno), errno),
-                          RTErrConvertFromErrno(errno));
-
-#if 0   /** @todo r=bird: WTF do we make a fuss over abinfo.bytes for when we don't even use it?!? */
-    AssertLogRelMsgReturn(abinfo.bytes >= 0, ("OSS: Warning: Invalid available size: %d\n", abinfo.bytes), VERR_INTERNAL_ERROR_3);
-    if ((unsigned)abinfo.bytes > cbBuf)
-    {
-        LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf));
-        abinfo.bytes = cbBuf;
-        /* Keep going. */
-    }
-#endif
-    cbToWrite = (unsigned)(abinfo.fragments * abinfo.fragsize);
-    cbToWrite = RT_MIN(cbToWrite, cbBuf);
-
-    /*
-     * Write.
-     */
-    uint8_t const *pbBuf    = (uint8_t const *)pvBuf;
-    uint32_t       cbChunk  = cbToWrite;
-    uint32_t       offChunk = 0;
-    while (cbChunk > 0)
-    {
-        ssize_t cbWritten = write(pStreamOSS->hFile, &pbBuf[offChunk], RT_MIN(cbChunk, (unsigned)s_OSSConf.fragsize));
-        if (cbWritten >= 0)
-        {
-            AssertLogRelMsg(!(cbWritten & pStreamOSS->uAlign),
-                            ("OSS: Misaligned write (written %#zx, alignment %#x)\n", cbWritten, pStreamOSS->uAlign));
-
-            Assert((uint32_t)cbWritten <= cbChunk);
-            offChunk += (uint32_t)cbWritten;
-            cbChunk  -= (uint32_t)cbWritten;
-        }
-        else
-        {
-            LogRel(("OSS: Failed writing output data: %s (%d)\n", strerror(errno), errno));
-            return RTErrConvertFromErrno(errno);
-        }
-    }
-
-    *pcbWritten = cbToWrite;
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnShutdown}
- */
-static DECLCALLBACK(void) drvHostOssAudioHA_Shutdown(PPDMIHOSTAUDIO pInterface)
-{
-    RT_NOREF(pInterface);
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
- */
-static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostOssAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
-{
-    AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
-    RT_NOREF(enmDir);
-
-    return PDMAUDIOBACKENDSTS_RUNNING;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                        PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
-{
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfgReq,    VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
-
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-
-    int rc;
-    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
-        rc = ossCreateStreamIn (pStreamOSS, pCfgReq, pCfgAcq);
-    else
-        rc = ossCreateStreamOut(pStreamOSS, pCfgReq, pCfgAcq);
-
-    if (RT_SUCCESS(rc))
-    {
-        pStreamOSS->pCfg = PDMAudioStrmCfgDup(pCfgAcq);
-        if (!pStreamOSS->pCfg)
-            rc = VERR_NO_MEMORY;
-    }
-
-    return rc;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-
-    if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */
-        return VINF_SUCCESS;
-
-    int rc;
-    if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN)
-        rc = ossDestroyStreamIn(pStream);
-    else
-        rc = ossDestroyStreamOut(pStream);
-
-    if (RT_SUCCESS(rc))
-    {
-        PDMAudioStrmCfgFree(pStreamOSS->pCfg);
-        pStreamOSS->pCfg = NULL;
-    }
-
-    return rc;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                         PDMAUDIOSTREAMCMD enmStreamCmd)
-{
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-
-    if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */
-        return VINF_SUCCESS;
-
-    int rc;
-    if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN)
-        rc = ossControlStreamIn(/*pInterface,  pStream, enmStreamCmd*/);
-    else
-        rc = ossControlStreamOut(pStreamOSS, enmStreamCmd);
-
-    return rc;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
- */
-static DECLCALLBACK(int) drvHostOssAudioHA_StreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-
-    LogFlowFuncEnter();
-
-    /* Nothing to do here for OSS. */
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
- */
-static DECLCALLBACK(uint32_t) drvHostOssAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return UINT32_MAX;
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
- */
-static DECLCALLBACK(uint32_t) drvHostOssAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
-    AssertPtr(pStreamOSS);
-    RT_NOREF(pInterface);
-
-    /*
-     * Note! This logic was found in StreamPlay and corrected a little.
-     *
-     * The logic here must match what StreamPlay does.
-     */
-    audio_buf_info abinfo = { 0, 0, 0, 0 };
-    int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
-    AssertMsgReturn(rc2 >= 0, ("SNDCTL_DSP_GETOSPACE failed: %s (%d)\n", strerror(errno), errno), 0);
-
-#if 0 /** @todo we could return abinfo.bytes here iff StreamPlay didn't use the fragmented approach */
-    /** @todo r=bird: WTF do we make a fuss over abinfo.bytes for when we don't even use it?!? */
-    AssertLogRelMsgReturn(abinfo.bytes >= 0, ("OSS: Warning: Invalid available size: %d\n", abinfo.bytes), VERR_INTERNAL_ERROR_3);
-    if ((unsigned)abinfo.bytes > cbBuf)
-    {
-        LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf));
-        abinfo.bytes = cbBuf;
-        /* Keep going. */
-    }
-#endif
-
-    return (uint32_t)(abinfo.fragments * abinfo.fragsize);
-}
-
-
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostOssAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED;
-}
 
 /**
