[media] as102: map URB DMA addresses in the driver
authorGianluca Gennari <gennarone@gmail.com>
Tue, 14 Feb 2012 12:25:00 +0000 (09:25 -0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Thu, 21 Jun 2012 13:32:49 +0000 (16:32 +0300)
commitae342566311f71e3bd57ac230d708fc9df742925
tree629e0113d108ddbd276346a336a326fd6eea257b
parentefa81b55b9260716078425f5bd60878be53bb619
[media] as102: map URB DMA addresses in the driver

On a set-top-box based on the Broadcom 7405 SoC (MIPS), the Abilis as102 driver
causes a kernel oops while trying to map the URB stream buffers DMA addresses:

CPU 0 Unable to handle kernel paging request at virtual address 007b9900,
epc == 80010cc4, ra == 8039d108

Call Trace:
[<80010cc4>] mips_dma_map_page+0x14/0x108
[<8039d108>] usb_hcd_map_urb_for_dma+0x338/0x4a8
[<8039d540>] usb_hcd_submit_urb+0x2c8/0x8cc
[<e13655d8>] as102_submit_urb_stream+0x64/0xc8 [dvb_as102]
[<e1365680>] as102_usb_start_stream+0x44/0x80 [dvb_as102]
[<e1363628>] as102_dvb_dmx_start_feed+0xb4/0x17c [dvb_as102]
[<803e20f4>] dmx_ts_feed_start_filtering+0x5c/0x134
[<803de454>] dvb_dmxdev_start_feed+0xd4/0x158
[<803dff28>] dvb_dmxdev_filter_start+0x2b8/0x448
[<803e07ac>] dvb_demux_do_ioctl+0x2a0/0x654
[<803ddc8c>] dvb_usercopy+0x124/0x204
[<800d5284>] do_vfs_ioctl+0xa0/0x6c0
[<800d58e8>] sys_ioctl+0x44/0xa8
[<8000ecfc>] stack_done+0x20/0x40

On other boxes based on older SoCs (7401) this doesn't happen, so it looks like
a bug in the kernel specific to MIPS SMP. This issue has been reproduced on
several kernel versions from 2.6.18 to 3.1.0.

Since the base DMA address and the offsets are known, it is possible to map
the DMA addresses of the URB buffers directly in the driver. This workaround
fixes the problem and has been tested on both MIPS and x86 CPUs with success.

By the way, with this fix the driver works perfectly fine on the set-top-box:
both UHF and VHF frequencies are tuned without problems, and zapping is quite
fast. SNR and signal strength reports seems to work fine, too.

The only remaining problem (on both the PC and the set-top-box) is that after
a soft reboot the device is not recognized again by the kernel. It requires
a power cycle (or a manual unplug/replug) to be recognized again. So probably
the device state is not reset properly at shut-down.

Signed-off-by: Gianluca Gennari <gennarone@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/staging/media/as102/as102_usb_drv.c