diff options
Diffstat (limited to 'drivers/misc/mei/bus.c')
-rw-r--r-- | drivers/misc/mei/bus.c | 57 |
1 files changed, 45 insertions, 12 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 0b05aa938799..5d5996e39a67 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -44,7 +44,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking) { struct mei_device *bus; - struct mei_cl_cb *cb = NULL; + struct mei_cl_cb *cb; ssize_t rets; if (WARN_ON(!cl || !cl->dev)) @@ -53,6 +53,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bus = cl->dev; mutex_lock(&bus->device_lock); + if (bus->dev_state != MEI_DEV_ENABLED) { + rets = -ENODEV; + goto out; + } + if (!mei_cl_is_connected(cl)) { rets = -ENODEV; goto out; @@ -81,8 +86,6 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, out: mutex_unlock(&bus->device_lock); - if (rets < 0) - mei_io_cb_free(cb); return rets; } @@ -109,6 +112,10 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) bus = cl->dev; mutex_lock(&bus->device_lock); + if (bus->dev_state != MEI_DEV_ENABLED) { + rets = -ENODEV; + goto out; + } cb = mei_cl_read_cb(cl, NULL); if (cb) @@ -230,45 +237,55 @@ static void mei_cl_bus_event_work(struct work_struct *work) * mei_cl_bus_notify_event - schedule notify cb on bus client * * @cl: host client + * + * Return: true if event was scheduled + * false if the client is not waiting for event */ -void mei_cl_bus_notify_event(struct mei_cl *cl) +bool mei_cl_bus_notify_event(struct mei_cl *cl) { struct mei_cl_device *cldev = cl->cldev; if (!cldev || !cldev->event_cb) - return; + return false; if (!(cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF))) - return; + return false; if (!cl->notify_ev) - return; + return false; set_bit(MEI_CL_EVENT_NOTIF, &cldev->events); schedule_work(&cldev->event_work); cl->notify_ev = false; + + return true; } /** - * mei_cl_bus_rx_event - schedule rx evenet + * mei_cl_bus_rx_event - schedule rx event * * @cl: host client + * + * Return: true if event was scheduled + * false if the client is not waiting for event */ -void mei_cl_bus_rx_event(struct mei_cl *cl) +bool mei_cl_bus_rx_event(struct mei_cl *cl) { struct mei_cl_device *cldev = cl->cldev; if (!cldev || !cldev->event_cb) - return; + return false; if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX))) - return; + return false; set_bit(MEI_CL_EVENT_RX, &cldev->events); schedule_work(&cldev->event_work); + + return true; } /** @@ -398,7 +415,7 @@ int mei_cldev_enable(struct mei_cl_device *cldev) if (!cl) { mutex_lock(&bus->device_lock); - cl = mei_cl_alloc_linked(bus, MEI_HOST_CLIENT_ID_ANY); + cl = mei_cl_alloc_linked(bus); mutex_unlock(&bus->device_lock); if (IS_ERR(cl)) return PTR_ERR(cl); @@ -958,6 +975,22 @@ void mei_cl_bus_rescan(struct mei_device *bus) dev_dbg(bus->dev, "rescan end"); } +void mei_cl_bus_rescan_work(struct work_struct *work) +{ + struct mei_device *bus = + container_of(work, struct mei_device, bus_rescan_work); + struct mei_me_client *me_cl; + + mutex_lock(&bus->device_lock); + me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid); + if (me_cl) + mei_amthif_host_init(bus, me_cl); + mei_me_cl_put(me_cl); + mutex_unlock(&bus->device_lock); + + mei_cl_bus_rescan(bus); +} + int __mei_cldev_driver_register(struct mei_cl_driver *cldrv, struct module *owner) { |