Index: /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 31428)
+++ /trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp	(revision 31429)
@@ -381,4 +381,5 @@
     CODECState  Codec;
     uint8_t     u8Counter;
+    uint8_t     u8StreamsInReset;
 } INTELHDLinkState;
 
@@ -428,4 +429,5 @@
 DECLCALLBACK(int)hdaRegWriteU8(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t pu32Value);
 static int hdaLookup(INTELHDLinkState* pState, uint32_t u32Offset);
+static void fetch_bd(INTELHDLinkState *pState);
 
 /* see 302349 p 6.2*/
@@ -462,5 +464,5 @@
     { 0x00010, 0x00002, 0xFFFFFFFF, 0x00000000, hdaRegReadUnimplemented, hdaRegWriteUnimplemented, "GSTS"      , "Global Status" },
     { 0x00020, 0x00004, 0xC00000FF, 0xC00000FF, hdaRegReadU32          , hdaRegWriteU32          , "INTCTL"    , "Interrupt Control" },
-    { 0x00024, 0x00004, 0xC00000FF, 0x400000FF, hdaRegReadINTSTS       , hdaRegWriteINTSTS       , "INTSTS"    , "Interrupt Status" },
+    { 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS       , hdaRegWriteUnimplemented, "INTSTS"    , "Interrupt Status" },
     //** @todo r=michaln: Are guests really not reading the WALCLK register at all?
     { 0x00030, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadUnimplemented, hdaRegWriteUnimplemented, "WALCLK"    , "Wall Clock Counter" },
@@ -582,7 +584,7 @@
     if(   INTCTL_CIE(pState)
        && (   RIRBSTS_RINTFL(pState)
-           ||  RIRBSTS_RIRBOIS(pState)))
-    {
-        INTSTS(pState) |= HDA_REG_FIELD_FLAG_MASK(INTSTS, CIS);
+           || RIRBSTS_RIRBOIS(pState))
+           || STATESTS(pState))
+    {
         fIrq = true;
     }
@@ -590,5 +592,4 @@
         && SDSTS(pState, 4) && HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))
     {
-        INTSTS(pState) |= HDA_REG_FIELD_FLAG_MASK(INTSTS, S4);
         fIrq = true;
     }
@@ -875,16 +876,26 @@
 DECLCALLBACK(int)hdaRegReadINTSTS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value)
 {
-    uint32_t v = INTSTS(pState);
-    v &= ~HDA_REG_FIELD_FLAG_MASK(INTSTS, GIS);
-    v |= (v ? HDA_REG_FIELD_FLAG_MASK(INTSTS, GIS) : 0);
+    uint32_t v = 0;
+    if (   RIRBSTS_RIRBOIS(pState)
+        || RIRBSTS_RINTFL(pState)
+        || HDA_REG_FLAG_VALUE(pState, CORBSTS, CMEI)
+        || STATESTS(pState)) 
+        v |= RT_BIT(30);
+#define HDA_IS_STREAM_EVENT(pState, stream)             \
+       (   (SDSTS((pState),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE))  \
+        || (SDSTS((pState),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE))  \
+        || (SDSTS((pState),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS)))
+#define MARK_STREAM(pState, stream, v) do {(v) |= HDA_IS_STREAM_EVENT((pState),stream) ? RT_BIT((stream)) : 0;}while(0) 
+    MARK_STREAM(pState, 0, v);
+    MARK_STREAM(pState, 1, v);
+    MARK_STREAM(pState, 2, v);
+    MARK_STREAM(pState, 3, v);
+    MARK_STREAM(pState, 4, v);
+    MARK_STREAM(pState, 5, v);
+    MARK_STREAM(pState, 6, v);
+    MARK_STREAM(pState, 7, v);
+    v |= v ? RT_BIT(31) : 0;
     *pu32Value = v;
     return VINF_SUCCESS;
-}
-
-DECLCALLBACK(int)hdaRegWriteINTSTS(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
-{
-    uint32_t v = INTSTS(pState);
-    INTSTS(pState) = (v ^ u32Value) & v;
-    return hdaProcessInterrupt(pState);
 }
 
@@ -942,10 +953,20 @@
     return hdaRegReadU24(pState, offset, index, pu32Value);
 }
-
+#define HDA_STREAM_BITMASK(offset) (1 << (((offset) - 0x80) >> 5))
+#define HDA_IS_STREAM_IN_RESET(pState, offset) ((pState)->u8StreamsInReset & HDA_STREAM_BITMASK((offset)))
 DECLCALLBACK(int)hdaRegWriteSDCTL(INTELHDLinkState* pState, uint32_t offset, uint32_t index, uint32_t u32Value)
 {
-    if((u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)))
-    {
+    if(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST))
+    {
+        LogRel(("hda: guest has iniated hw stream reset\n"));
+        pState->u8StreamsInReset |= HDA_STREAM_BITMASK(offset);
         hdaStreamReset(pState, offset);
+        HDA_REG_IND(pState, index) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST);
+    }
+    else if (HDA_IS_STREAM_IN_RESET(pState, offset))
+    {
+        LogRel(("hda: guest has iniated exit of stream reset\n"));
+        pState->u8StreamsInReset &= ~HDA_STREAM_BITMASK(offset);
+        HDA_REG_IND(pState, index) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST);
     }
     /* @todo: use right offsets for right streams */
@@ -957,4 +978,5 @@
         if (offset == 0x100)
         {
+            fetch_bd(pState);
             AUD_set_active_out(pState->Codec.voice_po, 1);
             //SDSTS(pState, 4) |= (1<<5);
@@ -971,5 +993,5 @@
             AUD_set_active_out(pState->Codec.voice_po, 0);
         }
-        SSYNC(pState) &= ~(1<< (offset - 0x80));
+        //SSYNC(pState) &= ~(1<< (offset - 0x80));
     }
     int rc = hdaRegWriteU24(pState, offset, index, u32Value);
@@ -1181,5 +1203,4 @@
     INTELHDLinkState *pState = (INTELHDLinkState *)pCodecState->pHDAState;
     STATESTS(pState) |= 1 << (pCodecState->id);
-    INTSTS(pState) |= HDA_REG_FIELD_FLAG_MASK(INTSTS, CIS);
     return VINF_SUCCESS;
 }
@@ -1199,5 +1220,5 @@
                 return;
             SDCTL(pState, 4) |= ((pState->Codec.pNodes[2].dac.u32F06_param & (0xf << 4)) >> 4) << 20;
-            fetch_bd(pState);
+            //fetch_bd(pState);
             while(   avail
                   && !fStop)
@@ -1217,9 +1238,8 @@
                     if (   SDCTL(pState, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)
                         && (   (   pState->u32CviPos == pState->u32CviLen
-                                && pState->fCviIoc)
+                                && pState->fCviIoc )
                             || SDLPIB(pState, 4) == SDLCBL(pState, 4)))
                     {
                         SDSTS(pState,4) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
-                        INTSTS(pState) |= HDA_REG_FIELD_FLAG_MASK(INTSTS, S4);
                         hdaProcessInterrupt(pState);
                         if (SDLPIB(pState, 4) == SDLCBL(pState, 4))
@@ -1238,6 +1258,6 @@
                     }
                     fStop = false;
+                    fetch_bd(pState);
                 }
-                fetch_bd(pState);
             }
         }
