linux/drivers/media/video
Michael d213ad0836 [media] ivtv: Fix corrective action taken upon DMA ERR interrupt to avoid hang
After upgrading the kernel from stock Ubuntu 7.10 to
10.04, with no hardware changes, I started getting the dreaded DMA
TIMEOUT errors, followed by inability to encode until the machine was
rebooted.

I came across a post from Andy in March
(http://www.gossamer-threads.com/lists/ivtv/users/40943#40943) where he
speculates that perhaps the corrective actions being taken after a DMA
ERROR are not sufficient to recover the situation.  After some testing
I suspect that this is indeed the case, and that in fact the corrective
action may be what hangs the card's DMA engine, rather than the
original error.

Specifically these DMA ERROR IRQs seem to present with two different
values in the IVTV_REG_DMASTATUS register: 0x11 and 0x13.  The current
corrective action is to clear that status register back to 0x01 or
0x03, and then issue the next DMA request.  In the case of a 0x13 this
seems to result in a minor glitch in the encoded stream due to the
failed transfer that was not retried, but otherwise things continue OK.
In the case of a 0x11 the card's DMA write engine is never heard from
again, and a DMA TIMEOUT follows shortly after.  0x11 is the killer.

I suspect that the two cases need to be handled differently.  The
difference is in bit 1 (0x02), which is set when the error is about to
be successfully recovered, and clear when things are about to go bad.

Bit 1 of DMASTATUS is described differently in different places either
as a positive "write finished", or an inverted "write busy".  If we
take the first definition, then when an error arises with state 0x11,
it means that the write did not complete.   It makes sense to start a
new transfer, as in the current code.  But if we take the second
definition, then 0x11 means "an error but the write engine is still
busy".  Trying to feed it a new transfer in this situation might not be
a good idea.

As an experiment, I added code to ignore the DMA ERROR IRQ if DMASTATUS
is 0x11.  I.e., don't start a new transfer, don't clear our flags, etc.
The hope was that the card would complete the transfer and issue a ENC
DMA COMPLETE, either successfully or with an error condition there.
However the card still hung.

The only remaining corrective action being taken with a 0x11 status was
then the write back to the status register to clear the error, i.e.
DMASTATUS = DMASTATUS & ~3.  This would have the effect of clearing the
error bit 4, while leaving the lower bits indicating DMA write busy.

Strangely enough, removing this write to the status register solved the
problem!  If the DMA ERROR IRQ with DMASTATUS=0x11 is completely
ignored, with no corrective action at all, then the card will complete
the transfer and issue a new IRQ.  If the status register is written to
when it has the value 0x11, then the DMA engine hangs.  Perhaps it's
illegal to write to
DMASTATUS while the read or write busy bit is set?  At any rate, it
appears that the current corrective action is indeed making things
worse rather than better.

I put together a patch that modifies ivtv_irq_dma_err to do the
following:

- Don't write back to IVTV_REG_DMASTATUS.
- If write-busy is asserted, leave the card alone.  Just extend the
timeout slightly.
- If write-busy is de-asserted, retry the current transfer.

This has completely fixed my DMA TIMEOUT woes.  DMA ERR events still
occur, but now they seem to be correctly handled.  0x11 events no
longer hang the card, and 0x13 events no longer result in a glitch in
the stream, as the failed transfer is retried.  I'm happy.

I've inlined the patch below in case it is of interest.  As described
above, I have a theory about why it works (based on a different
interpretation of bit 1 of DMASTATUS), but I can't guarantee that my
theory is correct.  There may be another explanation, or it may be a
fluke.  Maybe ignoring that IRQ entirely would be equally effective?
Maybe the status register read/writeback sequence is race condition if
the card changes it in the mean time?  Also as I am using a PVR-150
only, I have not been able to test it on other cards, which may be
especially relevant for 350s that support concurrent decoding.
Hopefully the patch does not break the DMA READ path.

Mike

[awalls@md.metrocast.net: Modified patch to add a verbose comment, make minor
brace reformats, and clear the error flags in the IVTV_REG_DMASTATUS iff both
read and write DMA were not in progress.  Mike's conjecture about a race
condition with the writeback is correct; it can confuse the DMA engine.]

[Comment and analysis from the ML post by Michael <mike@rsy.com>]
Signed-off-by: Andy Walls <awalls@md.metrocast.net>
Cc: stable@kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-03-02 13:45:42 -03:00
..
au0828 [media] au0828: fix VBI handling when in V4L2 streaming mode 2011-02-02 12:08:33 -02:00
bt8xx [media] bttv: remove obsolete 'no_tda9875' field 2011-01-19 11:28:09 -02:00
cpia2 [media] cpia2: convert .ioctl to .unlocked_ioctl 2011-01-19 11:28:12 -02:00
cx18 [media] v4l/cx18: update workqueue usage 2011-01-19 11:45:46 -02:00
cx88 Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq 2011-01-07 16:58:04 -08:00
cx231xx [media] DVB: cx231xx drivers does not use dummy frontend anymore 2011-01-19 11:45:48 -02:00
cx23885 [media] cx23885: Remove unused 'err:' labels to quiet compiler warning 2011-03-02 13:45:27 -03:00
cx25840 [media] cx25840: fix probing of cx2583x chips 2011-03-02 13:45:33 -03:00
davinci [media] davinci: convert vpif_display to core-assisted locking 2011-01-19 11:28:21 -02:00
em28xx [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
et61x251 [media] et61x251: remove wrongly claimed usb ids 2011-01-19 11:45:01 -02:00
gspca [media] gspca - zc3xx: Discard the partial frames 2011-01-31 12:05:48 -02:00
hdpvr [media] hdpvr: fix up i2c device registration 2011-01-31 12:18:04 -02:00
ivtv [media] ivtv: Fix corrective action taken upon DMA ERR interrupt to avoid hang 2011-03-02 13:45:42 -03:00
omap Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-01-13 10:05:56 -08:00
pvrusb2 [media] ir-kbd-i2c: improve remote behavior with z8 behind usb 2011-01-31 12:19:15 -02:00
pwc [media] V4L: remove V4L1 compatibility mode 2010-12-29 08:17:07 -02:00
s5p-fimc [media] drivers/media/video: Update WARN uses 2010-12-29 08:16:39 -02:00
saa7134 [media] saa7134: Kworld SBTVD: make both analog and digital to work 2011-01-19 11:45:28 -02:00
saa7164 Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-01-13 10:05:56 -08:00
sn9c102 [media] gspca_sonixj: Probe sensor type independent of bridge type 2011-01-19 11:45:10 -02:00
tlg2300 [media] media, tlg2300: Fix memory leak in alloc_bulk_urbs_generic() 2011-01-19 11:45:45 -02:00
usbvision [media] usbvision: coding style 2010-12-30 08:02:09 -02:00
uvc [media] V4L: remove V4L1 compatibility mode 2010-12-29 08:17:07 -02:00
zoran [media] zoran: use video_device_alloc instead of kmalloc 2011-01-19 11:52:12 -02:00
adv7170.c V4L/DVB: adv7170: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:04 -02:00
adv7175.c [media] adv7175: support s_power 2011-01-19 11:45:55 -02:00
adv7180.c V4L/DVB: v4l: remove unused i2c-id.h headers 2010-10-21 01:06:05 -02:00
adv7343_regs.h
adv7343.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
ak881x.c V4L/DVB: mediabus: fix ambiguous pixel code names 2010-08-02 16:43:36 -03:00
arv.c [media] BKL: trivial ioctl -> unlocked_ioctl video driver conversions 2010-12-01 20:10:10 -02:00
bt819.c V4L/DVB: bt819: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:59 -02:00
bt856.c V4L/DVB: bt856: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:02 -02:00
bt866.c V4L/DVB: bt866: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:00 -02:00
btcx-risc.c
btcx-risc.h
bw-qcam.c [media] BKL: trivial ioctl -> unlocked_ioctl video driver conversions 2010-12-01 20:10:10 -02:00
c-qcam.c [media] BKL: trivial ioctl -> unlocked_ioctl video driver conversions 2010-12-01 20:10:10 -02:00
cafe_ccic-regs.h
cafe_ccic.c [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
cs53l32a.c V4L/DVB: cs53l32a: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:03 -02:00
cs5345.c V4L/DVB: cs5345: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:57 -02:00
cs8420.h
cx2341x.c [media] v4l2-ctrls: use const char * const * for the menu arrays 2010-12-30 08:02:14 -02:00
fsl-viu.c [media] fsl_viu: add VIDIOC_QUERYSTD and VIDIOC_G_STD support 2010-12-29 08:17:16 -02:00
hexium_gemini.c [media] v4l: fix handling of v4l2_input.capabilities 2010-12-30 08:02:29 -02:00
hexium_orion.c [media] v4l: fix handling of v4l2_input.capabilities 2010-12-30 08:02:29 -02:00
ibmmpeg2.h
imx074.c [media] i2c: Remove obsolete cleanup for clientdata 2010-12-29 08:16:47 -02:00
indycam.c V4L/DVB: indycam: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:59 -02:00
indycam.h
ir-kbd-i2c.c [media] ir-kbd-i2c: improve remote behavior with z8 behind usb 2011-01-31 12:19:15 -02:00
Kconfig Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6 2011-01-21 16:50:31 -08:00
ks0127.c V4L/DVB: ks0127: remove obsolete v4l2_i2c_drv.h header 2010-10-21 01:06:04 -02:00
ks0127.h
m52790.c V4L/DVB: m52790: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:59 -02:00
Makefile [media] tda9875: remove duplicate driver 2011-01-19 11:28:08 -02:00
mem2mem_testdev.c [media] Fix double free of video_device in mem2mem_testdev 2011-02-02 10:42:48 -02:00
meye.c [media] BKL: trivial ioctl -> unlocked_ioctl video driver conversions 2010-12-01 20:10:10 -02:00
meye.h V4L/DVB: meye: remove last V4L1 remnants from the code and add v4l2_device 2010-05-18 00:52:36 -03:00
msp3400-driver.c [media] msp3400: fix mute audio regression 2010-10-21 08:56:41 -02:00
msp3400-driver.h V4L/DVB: msp3400: convert to the new control framework 2010-08-08 23:43:04 -03:00
msp3400-kthreads.c V4L/DVB: msp3400: convert to the new control framework 2010-08-08 23:43:04 -03:00
mt9m001.c [media] media: video: do not clear 'driver' from an i2c_client 2010-12-29 08:16:47 -02:00
mt9m111.c [media] media: video: do not clear 'driver' from an i2c_client 2010-12-29 08:16:47 -02:00
mt9t031.c [media] media: video: do not clear 'driver' from an i2c_client 2010-12-29 08:16:47 -02:00
mt9t112.c V4L/DVB: v4l: Use v4l2_get_subdevdata instead of accessing v4l2_subdev::priv 2010-10-21 01:04:51 -02:00
mt9v011.c [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
mt9v022.c [media] media: video: do not clear 'driver' from an i2c_client 2010-12-29 08:16:47 -02:00
mx1_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
mx2_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
mx3_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
mxb.c [media] v4l: fix handling of v4l2_input.capabilities 2010-12-30 08:02:29 -02:00
mxb.h
omap1_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
omap24xxcam-dma.c
omap24xxcam.c media/video: don't use flush_scheduled_work() 2010-12-24 16:14:20 +01:00
omap24xxcam.h
ov772x.c [media] v4l: ov772x: simplify pointer dereference 2010-12-30 22:29:23 -02:00
ov2640.c [media] V4L2: Add a v4l2-subdev (soc-camera) driver for OmniVision OV2640 sensor 2010-12-30 22:29:34 -02:00
ov6650.c i2c: Remove obsolete cleanup for clientdata 2010-11-15 22:40:38 +01:00
ov7670.c [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
ov7670.h [media] ov7670: allow configuration of image size, clock speed, and I/O method 2010-10-23 13:09:23 -02:00
ov9640.c [media] ov9640: fix OmniVision OV9640 sensor driver's priv data retrieving 2010-12-30 22:29:21 -02:00
ov9640.h V4L/DVB (13040): V4L2: Add a v4l2-subdev (soc-camera) driver for OmniVision OV9640 sensor 2009-12-05 18:40:01 -02:00
pms.c [media] BKL: trivial ioctl -> unlocked_ioctl video driver conversions 2010-12-01 20:10:10 -02:00
pxa_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
rj54n1cb0c.c [media] media: video: do not clear 'driver' from an i2c_client 2010-12-29 08:16:47 -02:00
s2255drv.c [media] s2255drv: firmware re-loading changes 2011-02-02 11:13:37 -02:00
saa711x_regs.h
saa717x.c V4L/DVB: saa717x: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:58 -02:00
saa6588.c [media] saa6588: rename rds.h to saa6588.h 2010-12-29 08:17:18 -02:00
saa7110.c V4L/DVB: saa7110: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:02 -02:00
saa7115.c [media] fix saa7111 non-detection 2011-01-31 14:19:50 -02:00
saa7121.h
saa7127.c V4L/DVB: saa7127: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:04 -02:00
saa7146.h
saa7146reg.h
saa7185.c V4L/DVB: saa7185: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:59 -02:00
saa7191.c V4L/DVB: saa7191: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:02 -02:00
saa7191.h
sh_mobile_ceu_camera.c [media] v4l: soc-camera: switch to .unlocked_ioctl 2010-12-30 22:29:26 -02:00
sh_mobile_csi2.c V4L/DVB: V4L2: soc-camera: add a MIPI CSI-2 driver for SH-Mobile platforms 2010-08-02 16:43:39 -03:00
sh_vou.c Merge branch 'bkl_removal' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6 2010-12-17 09:28:17 -08:00
soc_camera_platform.c V4L/DVB: soc_camera_platform: Add necessary v4l2_subdev_video_ops method 2010-08-02 14:05:37 -03:00
soc_camera.c [media] soc_camera: Add the ability to bind regulators to soc_camedra devices 2010-12-30 22:29:37 -02:00
soc_mediabus.c V4L/DVB: mediabus: fix ambiguous pixel code names 2010-08-02 16:43:36 -03:00
sr030pc30.c [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
stk-sensor.c
stk-webcam.c [media] stk-webcam: remove V4L1 compatibility code, replace with V4L2 controls 2010-12-29 08:17:09 -02:00
stk-webcam.h
tcm825x.c i2c: Remove all i2c_set_clientdata(client, NULL) in drivers 2010-06-03 11:33:58 +02:00
tcm825x.h
tda7432.c V4L/DVB: tda7432: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:03 -02:00
tda9840.c V4L/DVB: tda9840: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:58 -02:00
tea6415c.c [media] tea6415c: return -EIO if i2c_check_functionality fails 2010-12-29 08:16:39 -02:00
tea6415c.h
tea6420.c V4L/DVB: tea6420: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:03 -02:00
tea6420.h
ths7303.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
timblogiw.c [media] timblogiw: fix compile warning 2010-12-30 08:02:35 -02:00
tlv320aic23b.c V4L/DVB: tlv320aic23b: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:02 -02:00
tuner-core.c [media] tda18271: allow restricting max out to 4 bytes 2010-10-21 01:17:43 -02:00
tvaudio.c V4L/DVB: tvaudio: remove obsolete tda8425 initialization 2010-10-21 01:06:09 -02:00
tveeprom.c V4L/DVB: tveeprom: Add an entry for tuner code 168: a TCL M30WTP-4N-E tuner 2010-07-08 16:49:59 -03:00
tvp514x_regs.h V4L/DVB (12246): tvp514x: Migration to sub-device framework 2009-09-19 00:18:09 -03:00
tvp514x.c V4L/DVB: tvp514x: remove obsolete enum/try/s/g_fmt 2010-10-21 01:04:37 -02:00
tvp5150_reg.h
tvp5150.c [media] tvp5150: COMPOSITE0 input should not force-enable TV mode 2010-10-21 07:54:24 -02:00
tvp7002_reg.h V4L/DVB: Definitions for TVP7002 in DM365 2010-02-26 15:11:01 -03:00
tvp7002.c media: comment typo fix diable -> disable. 2011-01-03 16:03:38 +01:00
tw9910.c V4L/DVB: v4l: Use v4l2_get_subdevdata instead of accessing v4l2_subdev::priv 2010-10-21 01:04:51 -02:00
upd64031a.c V4L/DVB: upd64031a: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:58 -02:00
upd64083.c V4L/DVB: upd64083: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:03 -02:00
v4l2-common.c [media] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-19 11:45:30 -02:00
v4l2-compat-ioctl32.c [media] v4l2-compat-ioctl32: fix compile warning 2011-01-04 16:47:50 -02:00
v4l2-ctrls.c [media] v4l: Fix a use-before-set in the control framework 2011-01-19 11:52:10 -02:00
v4l2-dev.c [media] v4l2-dev: don't memset video_device.dev 2011-01-19 11:52:13 -02:00
v4l2-device.c [media] v4l2-device: fix 'use-after-freed' oops 2011-01-19 11:52:14 -02:00
v4l2-event.c V4L/DVB: v4l2: add core serialization lock 2010-10-21 01:06:14 -02:00
v4l2-fh.c V4L/DVB: V4L: Events: Support event handling in do_ioctl 2010-05-19 12:58:07 -03:00
v4l2-int-device.c
v4l2-ioctl.c [media] v4l2-ioctl: fix incorrect error code if VIDIOC_DBG_G/S_REGISTER are unsupported 2011-01-19 11:45:13 -02:00
v4l2-mem2mem.c V4L/DVB: videobuf: prepare to make locking optional in videobuf 2010-10-21 01:06:14 -02:00
via-camera.c Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-01-13 10:05:56 -08:00
via-camera.h [media] Add the via framebuffer camera controller driver 2010-10-21 13:45:28 -02:00
videobuf-core.c [media] V4L: remove V4L1 compatibility mode 2010-12-29 08:17:07 -02:00
videobuf-dma-contig.c [media] v4l: videobuf: remove unused is_userptr variable 2010-10-21 07:55:56 -02:00
videobuf-dma-sg.c [media] videobuf-dma-sg: remove obsolete comments 2010-12-29 08:17:07 -02:00
videobuf-dvb.c V4L/DVB: videobuf: add queue argument to videobuf_waiton() 2010-10-21 01:06:14 -02:00
videobuf-vmalloc.c V4L/DVB: videobuf: add ext_lock argument to the queue init functions 2010-10-21 01:06:14 -02:00
vino.c [media] v4l: fix handling of v4l2_input.capabilities 2010-12-30 08:02:29 -02:00
vino.h
vivi.c [media] V4L: remove V4L1 compatibility mode 2010-12-29 08:17:07 -02:00
vp27smpx.c V4L/DVB: vp27smpx: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:57 -02:00
vpx3220.c V4L/DVB: vpx3220: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:06:03 -02:00
w9966.c [media] w9966: zero device state after a detach 2011-01-19 11:52:11 -02:00
wm8739.c V4L/DVB: wm8739: remove obsolete v4l2-i2c-drv.h header 2010-10-21 01:05:57 -02:00
wm8775.c [media] wm8775: Revert changeset fcb9757333 to avoid a regression 2011-01-03 09:09:56 -02:00
zr364xx.c V4L/DVB: videobuf: add ext_lock argument to the queue init functions 2010-10-21 01:06:14 -02:00