include/linux/firmware.h: Define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw)
authorIan Abbott <abbotti@mev.co.uk>
Thu, 31 May 2012 08:55:02 +0000 (09:55 +0100)
committerIan Abbott <abbotti@mev.co.uk>
Thu, 31 May 2012 08:55:02 +0000 (09:55 +0100)
The version of request_firmware_nowait() that takes a gfp_t parameter
also expects its callback function to call release_firmware() to free
the firmware, otherwise there is a memory leak.  The older version of
request_firmware_nowait() doesn't want the callback function to free the
firmware.  Define the macro COMEDI_RELEASE_FIRMWARE_NOWAIT(fw) to be
used in the callback function instead of calling release_firmware(fw)
directly.  This does nothing for the older request_firmware_nowait()
API, but calls release_firmware(fw) for the newer
request_firmware_nowait() API.

Change the request_firmware_nowait callback function in the usbdux,
usbduxfast and usbduxsigma drivers to use
COMEDI_RELEASE_FIRMWARE_NOWAIT().

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
comedi/drivers/usbdux.c
comedi/drivers/usbduxfast.c
comedi/drivers/usbduxsigma.c
include/linux/firmware.h

index 9ac85693dfe9899de8a17c5b1fe1c49eb1febfb6..cd7a6aa7a12d2835bf2f30c0ac97c246e630de3a 100644 (file)
@@ -2503,9 +2503,16 @@ static void usbdux_firmware_request_complete_handler(
                dev_err(&usbdev->dev,
                        "Could not upload firmware (err=%d)\n",
                        ret);
-               return;
+               goto out;
        }
        comedi_usb_auto_config(usbdev, BOARDNAME);
+out:
+       /*
+        * in more recent versions the completion handler
+        * had to release the firmware whereas in older
+        * versions this has been done by the caller
+        */
+       COMEDI_RELEASE_FIRMWARE_NOWAIT(fw);
 }
 
 
index a6fd4028d9804184591778d6ff96dbb89aed4066..d838062027cd8213e56cf610e4dbb16630e1566e 100644 (file)
@@ -1472,10 +1472,17 @@ static void usbduxfast_firmware_request_complete_handler(
                dev_err(&usbdev->dev,
                        "Could not upload firmware (err=%d)\n",
                        ret);
-               return;
+               goto out;
        }
 
        comedi_usb_auto_config(usbdev, BOARDNAME);
+out:
+       /*
+        * in more recent versions the completion handler
+        * had to release the firmware whereas in older
+        * versions this has been done by the caller
+        */
+       COMEDI_RELEASE_FIRMWARE_NOWAIT(fw);
 }
 
 // allocate memory for the urbs and initialise them
index ba9a390113d1d9f6bd777e31f52d84a31ad1e98b..8242713aa3265376af54dbb3e5aeaadadf3592cc 100644 (file)
@@ -2385,11 +2385,7 @@ out:
         * had to release the firmware whereas in older
         * versions this has been done by the caller
         */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
-       release_firmware(fw);
-#else
-       while (0);
-#endif
+       COMEDI_RELEASE_FIRMWARE_NOWAIT(fw);
 }
 
 /* allocate memory for the urbs and initialise them */
index 0a6f55539ec2d291c31460b2dd3d1e369c05f7b4..70687bd14e77eb8d804772b340bcb4a23ec4a636 100644 (file)
@@ -26,6 +26,14 @@ static inline int comedi_internal_request_firmware_nowait(
        comedi_internal_request_firmware_nowait( \
                        module, uevent, name, device, gfp, context, cont)
 
+/* Define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw) for use in the callback function
+ * of request_firmware_nowait().  This version does nothing. */
+#define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw)     do; while (0)
+#else
+/* Define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw) for use in the callback function
+ * of request_firmware_nowait().  This version just calls
+ * release_firmware(fw). */
+#define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw)     release_firmware(fw)
 #endif
 
 #endif