aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/bcm
diff options
context:
space:
mode:
authorKevin McKinney <klmckinney1@gmail.com>2011-11-22 20:25:57 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-26 17:14:48 -0800
commitd9f26a6689a3e4ae643fca9c2acda3148b717e63 (patch)
treef9aa6e45e7806b4c151974f533a27438ea006111 /drivers/staging/bcm
parentabe33fc0933f9221193fc047fbf93cf9db23c8f6 (diff)
Staging: bcm: Fix semaphore locking error when downloading firmware.
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>
Diffstat (limited to 'drivers/staging/bcm')
-rw-r--r--drivers/staging/bcm/Bcmchar.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 5a3e7c846a3..d0a0b10c5d4 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -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;
}