Commit bc46b45a authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman

mei: bus: call mei_cl_read_start under device lock

Ensure that mei_cl_read_start is called under the device lock
also in the bus layer. The function updates global ctrl_wr_list
which should be locked.

Cc: <stable@vger.kernel.org> #4.4+
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bedffda8
...@@ -220,17 +220,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv); ...@@ -220,17 +220,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv);
static void mei_cl_bus_event_work(struct work_struct *work) static void mei_cl_bus_event_work(struct work_struct *work)
{ {
struct mei_cl_device *cldev; struct mei_cl_device *cldev;
struct mei_device *bus;
cldev = container_of(work, struct mei_cl_device, event_work); cldev = container_of(work, struct mei_cl_device, event_work);
bus = cldev->bus;
if (cldev->event_cb) if (cldev->event_cb)
cldev->event_cb(cldev, cldev->events, cldev->event_context); cldev->event_cb(cldev, cldev->events, cldev->event_context);
cldev->events = 0; cldev->events = 0;
/* Prepare for the next read */ /* Prepare for the next read */
if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
mutex_lock(&bus->device_lock);
mei_cl_read_start(cldev->cl, 0, NULL); mei_cl_read_start(cldev->cl, 0, NULL);
mutex_unlock(&bus->device_lock);
}
} }
/** /**
...@@ -304,6 +310,7 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev, ...@@ -304,6 +310,7 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
unsigned long events_mask, unsigned long events_mask,
mei_cldev_event_cb_t event_cb, void *context) mei_cldev_event_cb_t event_cb, void *context)
{ {
struct mei_device *bus = cldev->bus;
int ret; int ret;
if (cldev->event_cb) if (cldev->event_cb)
...@@ -316,15 +323,17 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev, ...@@ -316,15 +323,17 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
INIT_WORK(&cldev->event_work, mei_cl_bus_event_work); INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
mutex_lock(&bus->device_lock);
ret = mei_cl_read_start(cldev->cl, 0, NULL); ret = mei_cl_read_start(cldev->cl, 0, NULL);
mutex_unlock(&bus->device_lock);
if (ret && ret != -EBUSY) if (ret && ret != -EBUSY)
return ret; return ret;
} }
if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) { if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
mutex_lock(&cldev->cl->dev->device_lock); mutex_lock(&bus->device_lock);
ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0); ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
mutex_unlock(&cldev->cl->dev->device_lock); mutex_unlock(&bus->device_lock);
if (ret) if (ret)
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment