From 7fd5baebc81f2ad9206abea8ea06463865f1adc8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 May 2012 09:55:02 +0100 Subject: [PATCH] include/linux/firmware.h: Define COMEDI_RELEASE_FIRMWARE_NOWAIT(fw) 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 --- comedi/drivers/usbdux.c | 9 ++++++++- comedi/drivers/usbduxfast.c | 9 ++++++++- comedi/drivers/usbduxsigma.c | 6 +----- include/linux/firmware.h | 8 ++++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/comedi/drivers/usbdux.c b/comedi/drivers/usbdux.c index 9ac85693..cd7a6aa7 100644 --- a/comedi/drivers/usbdux.c +++ b/comedi/drivers/usbdux.c @@ -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); } diff --git a/comedi/drivers/usbduxfast.c b/comedi/drivers/usbduxfast.c index a6fd4028..d8380620 100644 --- a/comedi/drivers/usbduxfast.c +++ b/comedi/drivers/usbduxfast.c @@ -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 diff --git a/comedi/drivers/usbduxsigma.c b/comedi/drivers/usbduxsigma.c index ba9a3901..8242713a 100644 --- a/comedi/drivers/usbduxsigma.c +++ b/comedi/drivers/usbduxsigma.c @@ -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 */ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 0a6f5553..70687bd1 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -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 -- 2.26.2