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>
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 3bd07f7..36c0e36 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,6 +33,9 @@
 
  History:
 
+ Version 0.43:
+	Oliver Neukum: avoided DMA coherency issue
+
  Version 0.42:
 	Converted dsbr100 to use video_ioctl2
 	by Douglas Landgraf <dougsland@gmail.com>
@@ -135,7 +138,7 @@
 struct dsbr100_device {
 	struct usb_device *usbdev;
 	struct video_device *videodev;
-	unsigned char transfer_buffer[TB_LEN];
+	u8 *transfer_buffer;
 	int curfreq;
 	int stereo;
 	int users;
@@ -237,10 +240,7 @@
 /* handle unplugging of the device, release data structures
 if nothing keeps us from doing it.  If something is still
 keeping us busy, the release callback of v4l will take care
-of releasing it.  stv680.c does not relase its private
-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) */
+of releasing it. */
 static void usb_dsbr100_disconnect(struct usb_interface *intf)
 {
 	struct dsbr100_device *radio = usb_get_intfdata(intf);
@@ -250,6 +250,7 @@
 		video_unregister_device(radio->videodev);
 		radio->videodev = NULL;
 		if (radio->users) {
+			kfree(radio->transfer_buffer);
 			kfree(radio);
 		} else {
 			radio->removed = 1;
@@ -425,6 +426,7 @@
 		return -ENODEV;
 	radio->users = 0;
 	if (radio->removed) {
+		kfree(radio->transfer_buffer);
 		kfree(radio);
 	}
 	return 0;
@@ -471,7 +473,12 @@
 
 	if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
 		return -ENOMEM;
+	if (!(radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL))) {
+		kfree(radio);
+		return -ENOMEM;
+	}
 	if (!(radio->videodev = video_device_alloc())) {
+		kfree(radio->transfer_buffer);
 		kfree(radio);
 		return -ENOMEM;
 	}
@@ -485,6 +492,7 @@
 	if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
 		warn("Could not register video device");
 		video_device_release(radio->videodev);
+		kfree(radio->transfer_buffer);
 		kfree(radio);
 		return -EIO;
 	}