Opened 9 years ago
Last modified 9 years ago
#15361 new defect
HDA fails to restart when LPIB == CBL
Reported by: | Julian Day | Owned by: | |
---|---|---|---|
Component: | audio | Version: | VirtualBox 5.0.18 |
Keywords: | HDA | Cc: | |
Guest type: | other | Host type: | all |
Description
The HDA spec describes LPIB as: Link Position in Buffer (LPIB): Indicates the number of bytes that have been received off the link. Since this register reflects the number of bytes that have been received into the current buffer, for the first buffer SDnLPIB will count from 0 to the value in the Cyclic Buffer Length (SDnCBL) register, inclusive. For subsequent buffers, SNnLPIB will count from a value of 1 to the value in the Cyclic Buffer Length register, inclusive.
There seems to be a problem with hdaStreamGetTransferSize() such that when LPIB is the same as CBL and the DMA is stopped, it will not restart. I think that hdaStreamGetTransferSize() should behave as if LPIB is 0 when it has the value of CBL.
I'm using an RTOS called INTEGRITY when I encountered this, but I think that this could happen for any guest which stops and restarts the streams. I would think that it is relatively likely that LPIB could be the same as CBL as the natural time to stop the stream would be following an IOC event.
A couple of other references which might be useful in understanding why I see what I see:
From 3.3.38:
Cyclic Buffer Length (CBL): Indicates the number of bytes in the complete cyclic buffer. Link Position in Buffer (SDnLPIB) will be reset when it reaches this value.
(This supports my statement that when LPIB == CBL, it should behave as if LPIB is 0, although according to the description of LPIB, it is not expected to read back 0.)
4.5.5 Resuming Streams
If a stream which was previously running has been stopped, it can be restarted by setting the RUN bit back to 1. If the stream has been recently stopped, the RUN bit must be checked to make sure that it has transition back to a 0 to indicate that the hardware is ready to restart. When the RUN bit is again set to 1, the DMA engine will then restart at the point it left off.
(This is to support my statement that it should be ok to stop and restart a stream at any point, provided you wait for the RUN bit to clear.)