V4L/DVB (6732): dsbr100 violates DMA coherency rules

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Oliver Neukum 2007-12-03 06:48:43 -03:00 committed by Mauro Carvalho Chehab
parent e1ba33df0c
commit 863c86dd7e

View file

@ -33,6 +33,9 @@
History: History:
Version 0.43:
Oliver Neukum: avoided DMA coherency issue
Version 0.42: Version 0.42:
Converted dsbr100 to use video_ioctl2 Converted dsbr100 to use video_ioctl2
by Douglas Landgraf <dougsland@gmail.com> by Douglas Landgraf <dougsland@gmail.com>
@ -135,7 +138,7 @@ module_param(radio_nr, int, 0);
struct dsbr100_device { struct dsbr100_device {
struct usb_device *usbdev; struct usb_device *usbdev;
struct video_device *videodev; struct video_device *videodev;
unsigned char transfer_buffer[TB_LEN]; u8 *transfer_buffer;
int curfreq; int curfreq;
int stereo; int stereo;
int users; int users;
@ -237,10 +240,7 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
/* handle unplugging of the device, release data structures /* handle unplugging of the device, release data structures
if nothing keeps us from doing it. If something is still if nothing keeps us from doing it. If something is still
keeping us busy, the release callback of v4l will take care keeping us busy, the release callback of v4l will take care
of releasing it. stv680.c does not relase its private of releasing it. */
data, so I don't do this here either. Checking out the
code I'd expect I better did that, but if there's a memory
leak here it's tiny (~50 bytes per disconnect) */
static void usb_dsbr100_disconnect(struct usb_interface *intf) static void usb_dsbr100_disconnect(struct usb_interface *intf)
{ {
struct dsbr100_device *radio = usb_get_intfdata(intf); struct dsbr100_device *radio = usb_get_intfdata(intf);
@ -250,6 +250,7 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
video_unregister_device(radio->videodev); video_unregister_device(radio->videodev);
radio->videodev = NULL; radio->videodev = NULL;
if (radio->users) { if (radio->users) {
kfree(radio->transfer_buffer);
kfree(radio); kfree(radio);
} else { } else {
radio->removed = 1; radio->removed = 1;
@ -425,6 +426,7 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
return -ENODEV; return -ENODEV;
radio->users = 0; radio->users = 0;
if (radio->removed) { if (radio->removed) {
kfree(radio->transfer_buffer);
kfree(radio); kfree(radio);
} }
return 0; return 0;
@ -471,7 +473,12 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
if (!(radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL))) {
kfree(radio);
return -ENOMEM;
}
if (!(radio->videodev = video_device_alloc())) { if (!(radio->videodev = video_device_alloc())) {
kfree(radio->transfer_buffer);
kfree(radio); kfree(radio);
return -ENOMEM; return -ENOMEM;
} }
@ -485,6 +492,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) { if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
warn("Could not register video device"); warn("Could not register video device");
video_device_release(radio->videodev); video_device_release(radio->videodev);
kfree(radio->transfer_buffer);
kfree(radio); kfree(radio);
return -EIO; return -EIO;
} }