Staging: bcm: Fix semaphore locking error when downloading firmware.
authorKevin McKinney <klmckinney1@gmail.com>
Wed, 23 Nov 2011 01:25:57 +0000 (20:25 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sun, 27 Nov 2011 01:14:48 +0000 (17:14 -0800)
This patch releases semaphore locks when
an error occurrs while attempting to
download firmware for the bcm driver.
When downloading firmware for this driver,
a process is expected to call
the following ioctl's in this order:
(1)IOCTL_BCM_BUFFER_DOWNLOAD_START,
(2)IOCTL_BCM_BUFFER_DOWNLOAD, and (3)
IOCTL_BCM_BUFFER_DOWNLOAD_STOP.
Semaphore, “Adapter->fw_download_sema” is
expected to be acquired in the first ioctl,
IOCTL_BCM_BUFFER_DOWNLOAD_START, and it should
block until IOCTL_BCM_BUFFER_DOWNLOAD_STOP
is called.  In this case, if an error
occurred before STOP finished, the semaphore
"Adapter->fw_download_sema" was not being released.

Signed-off-by: Kevin McKinney <klmckinney1@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/bcm/Bcmchar.c

index 5a3e7c8..d0a0b10 100644 (file)
@@ -802,27 +802,36 @@ cntrlEnd:
                }
 
                /* Copy Ioctl Buffer structure */
-               if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+               if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
+                       up(&Adapter->fw_download_sema);
                        return -EFAULT;
+               }
 
                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
                                "Length for FW DLD is : %lx\n", IoBuffer.InputLength);
 
-               if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
+               if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) {
+                       up(&Adapter->fw_download_sema);
                        return -EINVAL;
+               }
 
                psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
-               if (!psFwInfo)
+               if (!psFwInfo) {
+                       up(&Adapter->fw_download_sema);
                        return -ENOMEM;
+               }
 
-               if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
+               if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
+                       up(&Adapter->fw_download_sema);
                        return -EFAULT;
+               }
 
                if (!psFwInfo->pvMappedFirmwareAddress ||
                        (psFwInfo->u32FirmwareLength == 0)) {
 
                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
                                        psFwInfo->u32FirmwareLength);
+                       up(&Adapter->fw_download_sema);
                        Status = -EINVAL;
                        break;
                }