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: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
bedffda8ca
commit
bc46b45a42
@@ -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,
|
|||||||
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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user