ChangeSet 1.1123.18.20, 2003/08/14 16:22:22-07:00, bellucda@tiscali.it

[PATCH] USB: usbvideo cleanup on error


 drivers/usb/media/usbvideo.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)


diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Fri Aug 15 10:44:28 2003
+++ b/drivers/usb/media/usbvideo.c	Fri Aug 15 10:44:28 2003
@@ -777,7 +777,7 @@
 	const struct usb_device_id *id_table)
 {
 	struct usbvideo *cams;
-	int i, base_size;
+	int i, base_size, result;
 
 	/* Check parameters for sanity */
 	if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
@@ -846,9 +846,13 @@
 			up->user_size = num_cams * num_extra;
 			up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
 			if (up->user_data == NULL) {
-				up->user_size = 0;
 				err("%s: Failed to allocate user_data (%d. bytes)",
 				    __FUNCTION__, up->user_size);
+				while (i) {
+					up = &cams->cam[--i];
+					kfree(up->user_data);
+				}
+				kfree(cams);
 				return -ENOMEM;
 			}
 			dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
@@ -878,9 +882,16 @@
 	 * If the handle is not yet updated then the probe() will fail.
 	 */
 	*pCams = cams;
-	usb_register(&cams->usbdrv);
+	result = usb_register(&cams->usbdrv);
+	if (result) {
+		for (i = 0; i < num_cams; i++) {
+			struct uvd *up = &cams->cam[i];
+			kfree(up->user_data);
+		}
+		kfree(cams);
+	}
 
-	return 0;
+	return result;
 }
 
 EXPORT_SYMBOL(usbvideo_register);
