mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
186 lines
5.1 KiB
Diff
186 lines
5.1 KiB
Diff
|
From ce9db0874906f6aedd80bb28d457eadfe38bdd02 Mon Sep 17 00:00:00 2001
|
||
|
From: Sudheer Papothi <spapothi@codeaurora.org>
|
||
|
Date: Wed, 26 Oct 2016 01:07:04 +0530
|
||
|
Subject: drivers: qcom: ultrasound: Lock async driver calls
|
||
|
|
||
|
Adds lock to ioctl and other external calls to driver.
|
||
|
Adds missing null check in __usf_set_stream_param.
|
||
|
|
||
|
Change-Id: I142f31c6bb46d6a394ad012077e1703875a120ad
|
||
|
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
|
||
|
---
|
||
|
drivers/misc/qcom/qdsp6v2/ultrasound/usf.c | 66 ++++++++++++++++++++++++++----
|
||
|
1 file changed, 59 insertions(+), 7 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
|
||
|
index d535ccb..9270dbc 100644
|
||
|
--- a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
|
||
|
+++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
|
||
|
@@ -22,6 +22,7 @@
|
||
|
#include <linux/uaccess.h>
|
||
|
#include <linux/time.h>
|
||
|
#include <linux/kmemleak.h>
|
||
|
+#include <linux/mutex.h>
|
||
|
#include <sound/apr_audio.h>
|
||
|
#include <linux/qdsp6v2/usf.h>
|
||
|
#include "q6usm.h"
|
||
|
@@ -128,6 +129,8 @@ struct usf_type {
|
||
|
uint16_t conflicting_event_filters;
|
||
|
/* The requested buttons bitmap */
|
||
|
uint16_t req_buttons_bitmap;
|
||
|
+ /* Mutex for exclusive operations (all public APIs) */
|
||
|
+ struct mutex mutex;
|
||
|
};
|
||
|
|
||
|
struct usf_input_dev_type {
|
||
|
@@ -1376,9 +1379,22 @@ static int __usf_set_stream_param(struct usf_xx_type *usf_xx,
|
||
|
int dir)
|
||
|
{
|
||
|
struct us_client *usc = usf_xx->usc;
|
||
|
- struct us_port_data *port = &usc->port[dir];
|
||
|
+ struct us_port_data *port;
|
||
|
int rc = 0;
|
||
|
|
||
|
+ if (usc == NULL) {
|
||
|
+ pr_err("%s: usc is null\n",
|
||
|
+ __func__);
|
||
|
+ return -EFAULT;
|
||
|
+ }
|
||
|
+
|
||
|
+ port = &usc->port[dir];
|
||
|
+ if (port == NULL) {
|
||
|
+ pr_err("%s: port is null\n",
|
||
|
+ __func__);
|
||
|
+ return -EFAULT;
|
||
|
+ }
|
||
|
+
|
||
|
if (port->param_buf == NULL) {
|
||
|
pr_err("%s: parameter buffer is null\n",
|
||
|
__func__);
|
||
|
@@ -1503,10 +1519,12 @@ static int usf_get_stream_param(struct usf_xx_type *usf_xx,
|
||
|
return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
|
||
|
} /* usf_get_stream_param */
|
||
|
|
||
|
-static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||
|
+static long __usf_ioctl(struct usf_type *usf,
|
||
|
+ unsigned int cmd,
|
||
|
+ unsigned long arg)
|
||
|
{
|
||
|
+
|
||
|
int rc = 0;
|
||
|
- struct usf_type *usf = file->private_data;
|
||
|
struct usf_xx_type *usf_xx = NULL;
|
||
|
|
||
|
switch (cmd) {
|
||
|
@@ -1669,6 +1687,18 @@ static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||
|
release_xx(usf_xx);
|
||
|
|
||
|
return rc;
|
||
|
+} /* __usf_ioctl */
|
||
|
+
|
||
|
+static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||
|
+{
|
||
|
+ struct usf_type *usf = file->private_data;
|
||
|
+ int rc = 0;
|
||
|
+
|
||
|
+ mutex_lock(&usf->mutex);
|
||
|
+ rc = __usf_ioctl(usf, cmd, arg);
|
||
|
+ mutex_unlock(&usf->mutex);
|
||
|
+
|
||
|
+ return rc;
|
||
|
} /* usf_ioctl */
|
||
|
|
||
|
#ifdef CONFIG_COMPAT
|
||
|
@@ -2106,12 +2136,11 @@ static int usf_get_stream_param32(struct usf_xx_type *usf_xx,
|
||
|
return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
|
||
|
} /* usf_get_stream_param32 */
|
||
|
|
||
|
-static long usf_compat_ioctl(struct file *file,
|
||
|
+static long __usf_compat_ioctl(struct usf_type *usf,
|
||
|
unsigned int cmd,
|
||
|
unsigned long arg)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
- struct usf_type *usf = file->private_data;
|
||
|
struct usf_xx_type *usf_xx = NULL;
|
||
|
|
||
|
switch (cmd) {
|
||
|
@@ -2119,7 +2148,7 @@ static long usf_compat_ioctl(struct file *file,
|
||
|
case US_START_RX:
|
||
|
case US_STOP_TX:
|
||
|
case US_STOP_RX: {
|
||
|
- return usf_ioctl(file, cmd, arg);
|
||
|
+ return __usf_ioctl(usf, cmd, arg);
|
||
|
}
|
||
|
|
||
|
case US_SET_TX_INFO32: {
|
||
|
@@ -2228,6 +2257,20 @@ static long usf_compat_ioctl(struct file *file,
|
||
|
release_xx(usf_xx);
|
||
|
|
||
|
return rc;
|
||
|
+} /* __usf_compat_ioctl */
|
||
|
+
|
||
|
+static long usf_compat_ioctl(struct file *file,
|
||
|
+ unsigned int cmd,
|
||
|
+ unsigned long arg)
|
||
|
+{
|
||
|
+ struct usf_type *usf = file->private_data;
|
||
|
+ int rc = 0;
|
||
|
+
|
||
|
+ mutex_lock(&usf->mutex);
|
||
|
+ rc = __usf_compat_ioctl(usf, cmd, arg);
|
||
|
+ mutex_unlock(&usf->mutex);
|
||
|
+
|
||
|
+ return rc;
|
||
|
} /* usf_compat_ioctl */
|
||
|
#endif /* CONFIG_COMPAT */
|
||
|
|
||
|
@@ -2236,13 +2279,17 @@ static int usf_mmap(struct file *file, struct vm_area_struct *vms)
|
||
|
struct usf_type *usf = file->private_data;
|
||
|
int dir = OUT;
|
||
|
struct usf_xx_type *usf_xx = &usf->usf_tx;
|
||
|
+ int rc = 0;
|
||
|
|
||
|
+ mutex_lock(&usf->mutex);
|
||
|
if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */
|
||
|
dir = IN;
|
||
|
usf_xx = &usf->usf_rx;
|
||
|
}
|
||
|
+ rc = q6usm_get_virtual_address(dir, usf_xx->usc, vms);
|
||
|
+ mutex_unlock(&usf->mutex);
|
||
|
|
||
|
- return q6usm_get_virtual_address(dir, usf_xx->usc, vms);
|
||
|
+ return rc;
|
||
|
}
|
||
|
|
||
|
static uint16_t add_opened_dev(int minor)
|
||
|
@@ -2294,6 +2341,8 @@ static int usf_open(struct inode *inode, struct file *file)
|
||
|
usf->usf_tx.us_detect_type = USF_US_DETECT_UNDEF;
|
||
|
usf->usf_rx.us_detect_type = USF_US_DETECT_UNDEF;
|
||
|
|
||
|
+ mutex_init(&usf->mutex);
|
||
|
+
|
||
|
pr_debug("%s:usf in open\n", __func__);
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -2304,6 +2353,7 @@ static int usf_release(struct inode *inode, struct file *file)
|
||
|
|
||
|
pr_debug("%s: release entry\n", __func__);
|
||
|
|
||
|
+ mutex_lock(&usf->mutex);
|
||
|
usf_release_input(usf);
|
||
|
|
||
|
usf_disable(&usf->usf_tx);
|
||
|
@@ -2311,6 +2361,8 @@ static int usf_release(struct inode *inode, struct file *file)
|
||
|
|
||
|
s_opened_devs[usf->dev_ind] = 0;
|
||
|
|
||
|
+ mutex_unlock(&usf->mutex);
|
||
|
+ mutex_destroy(&usf->mutex);
|
||
|
kfree(usf);
|
||
|
pr_debug("%s: release exit\n", __func__);
|
||
|
return 0;
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|