IVTV DMA error fix? Patch from Author
Hans Verkuil, the developer behind ivtv, thinks that he may have found the source of the DMA problems that some have been experiencing. From the mailing list:
Date: Fri, 25 Aug 2006 18:49:51 +0200
From: Hans Verkuil
Subject: [ivtv-devel] Please test: DMA error patch
To: ivtv-devel@ivtvdriver.org, ivtv-users@ivtvdriver.org
Message-ID: <200608251849.51195.hverkuil@xs4all.nl>
Content-Type: text/plain; charset=”us-ascii”Hi all,
As promised, here is the patch that should fix the DMA errors:
http://www.xs4all.nl/~hverkuil/ivtv-dma.0.4.diff
http://www.xs4all.nl/~hverkuil/ivtv-dma.0.6.diffThe first is the patch for ivtv-0.4.6, the second is the patch for
ivtv-0.6.3 and ivtv-0.7.0 (and also applies to the ivtv trunk).The patches were made in the driver directory of the ivtv source, so you
have to apply it there.I have personally only tested it for the trunk (bleeding edge
development), but I expect no problems with the other versions since
the code touched by this patch is pretty much unchanged since ivtv-0.2.Please test this thoroughly. Especially in combination with MythTV. If
you can, also combine it with MPEG decoding, VBI recording, X-driver,
etc.Some background information:
There are several possible DMA errors. One in particular is causing all
the problems. When a DMA write error occurs it seems the DMA engine of
the card gets confused as to what the start address is of the card’s
buffers. After the DMA error the start of a buffer is set between 0 and
128 bytes before the actual start. Luckily for me it is not trashed,
but always limited between 0 and 128 bytes.So my solution is to write a special 32-bit start marker value at the
start of the buffer on the card (taking care to first read the original
value), then start the DMA, but making the total size 256 bytes more
than is strictly necessary.When the DMA is finished I check whether I detect the marker value at
the expected place. If not, then I look for it in the first 128 bytes.
The place where I find the marker is the new offset. I now replace the
marker with the original value I saved earlier and I have a complete
buffer. Because I actually DMA a bit more than is needed, I still have
all data, even if it is shifted the maximum of 128 bytes. Without the
extra DMA length the latter 128 bytes might never be copied by the DMA
engine, so that’s the reason for the extra length.This solution is very fast so there is no performance penalty.
During stress testing (lots of CPU frequency changes) you will see these
DMA errors occurring, but rather than giving you a broken MPEG stream
the DMA will be retried and the new offset found to keep the MPEG
stream uncorrupted. If you get a burst of these DMA errors (again,
we’re talking continuous CPU frequency changes here, not a normal
situation), then some corruption may occur but it should be only for a
few frames.As far as I can tell this particular DMA error is now handled correctly.
Unfortunately there is still a ‘ENC: REG_DMAXFER 2 wait failed’ error
where it looks like the complete DMA engine is stalled. Again, reboot
is the only option. It only occurs during a very heavy load and I don’t
think it will happen during normal operation.I’m not sure whether this can be fixed at the moment. There are still
some problems with the way the current DMA handling is done with
possible race conditions. I need more research and testing to determine
whether this is something that can be solved.Please keep me informed on how this works, if the test results are
positive then I’ll make new releases next week.Enjoy (I hope :-),
Hans