diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-03-27 11:29:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-29 11:45:59 -0400 |
commit | 44d88d919261256e3bd999cde05572c8c4afb642 (patch) | |
tree | 95f1bc31837598f45fe5260b8f1be6ebf3f304ed /drivers/misc/mei | |
parent | cf3baefba04073237decb1b8a8c114b0b45bfc80 (diff) |
mei: bus: Synchronous API for the data transmission
Define a truly synchronous API for the bus Tx path by putting all pending
request to the write list and wait for the interrupt tx handler to wake
us up.
The ___mei_cl_send() out path is also slightly reworked to make it look more
like main.c:mei_write().
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/bus.c | 39 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 1 |
2 files changed, 30 insertions, 10 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index c626dc9937eb..2b4b5b3f639f 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -222,7 +222,8 @@ void mei_cl_driver_unregister(struct mei_cl_driver *driver) | |||
222 | } | 222 | } |
223 | EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); | 223 | EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); |
224 | 224 | ||
225 | int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) | 225 | static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, |
226 | bool blocking) | ||
226 | { | 227 | { |
227 | struct mei_device *dev; | 228 | struct mei_device *dev; |
228 | struct mei_msg_hdr mei_hdr; | 229 | struct mei_msg_hdr mei_hdr; |
@@ -273,11 +274,8 @@ int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) | |||
273 | cb->buf_idx = 0; | 274 | cb->buf_idx = 0; |
274 | mei_hdr.msg_complete = 0; | 275 | mei_hdr.msg_complete = 0; |
275 | cl->writing_state = MEI_WRITING; | 276 | cl->writing_state = MEI_WRITING; |
276 | list_add_tail(&cb->list, &dev->write_list.list); | ||
277 | |||
278 | mutex_unlock(&dev->device_lock); | ||
279 | 277 | ||
280 | return length; | 278 | goto out; |
281 | } | 279 | } |
282 | 280 | ||
283 | dev->hbuf_is_ready = false; | 281 | dev->hbuf_is_ready = false; |
@@ -303,19 +301,30 @@ int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) | |||
303 | cl->writing_state = MEI_WRITING; | 301 | cl->writing_state = MEI_WRITING; |
304 | cb->buf_idx = mei_hdr.length; | 302 | cb->buf_idx = mei_hdr.length; |
305 | 303 | ||
306 | if (!mei_hdr.msg_complete) { | 304 | out: |
307 | list_add_tail(&cb->list, &dev->write_list.list); | 305 | if (mei_hdr.msg_complete) { |
308 | } else { | ||
309 | if (mei_cl_flow_ctrl_reduce(cl)) { | 306 | if (mei_cl_flow_ctrl_reduce(cl)) { |
310 | err = -EIO; | 307 | err = -ENODEV; |
311 | goto out_err; | 308 | goto out_err; |
312 | } | 309 | } |
313 | |||
314 | list_add_tail(&cb->list, &dev->write_waiting_list.list); | 310 | list_add_tail(&cb->list, &dev->write_waiting_list.list); |
311 | } else { | ||
312 | list_add_tail(&cb->list, &dev->write_list.list); | ||
315 | } | 313 | } |
316 | 314 | ||
317 | mutex_unlock(&dev->device_lock); | 315 | mutex_unlock(&dev->device_lock); |
318 | 316 | ||
317 | if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { | ||
318 | if (wait_event_interruptible(cl->tx_wait, | ||
319 | cl->writing_state == MEI_WRITE_COMPLETE)) { | ||
320 | if (signal_pending(current)) | ||
321 | err = -EINTR; | ||
322 | err = -ERESTARTSYS; | ||
323 | mutex_lock(&dev->device_lock); | ||
324 | goto out_err; | ||
325 | } | ||
326 | } | ||
327 | |||
319 | return mei_hdr.length; | 328 | return mei_hdr.length; |
320 | 329 | ||
321 | out_err: | 330 | out_err: |
@@ -382,6 +391,16 @@ out: | |||
382 | return r_length; | 391 | return r_length; |
383 | } | 392 | } |
384 | 393 | ||
394 | inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length) | ||
395 | { | ||
396 | return ___mei_cl_send(cl, buf, length, 0); | ||
397 | } | ||
398 | |||
399 | inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) | ||
400 | { | ||
401 | return ___mei_cl_send(cl, buf, length, 1); | ||
402 | } | ||
403 | |||
385 | int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) | 404 | int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) |
386 | { | 405 | { |
387 | struct mei_cl *cl = device->cl; | 406 | struct mei_cl *cl = device->cl; |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 7d594bedc685..325f71abeb7a 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -273,6 +273,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, | |||
273 | uuid_le uuid, char *name); | 273 | uuid_le uuid, char *name); |
274 | void mei_cl_remove_device(struct mei_cl_device *device); | 274 | void mei_cl_remove_device(struct mei_cl_device *device); |
275 | 275 | ||
276 | int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length); | ||
276 | int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length); | 277 | int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length); |
277 | int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); | 278 | int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); |
278 | 279 | ||