diff options
Diffstat (limited to 'drivers/misc/mei/bus.c')
| -rw-r--r-- | drivers/misc/mei/bus.c | 34 | 
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 1fbe127ff633..a81b890c7ee6 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -35,6 +35,26 @@  ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag,  		      unsigned int mode)  { +	return __mei_cl_send_timeout(cl, buf, length, vtag, mode, MAX_SCHEDULE_TIMEOUT); +} + +/** + * __mei_cl_send_timeout - internal client send (write) + * + * @cl: host client + * @buf: buffer to send + * @length: buffer length + * @vtag: virtual tag + * @mode: sending mode + * @timeout: send timeout in milliseconds. + *           effective only for blocking writes: the MEI_CL_IO_TX_BLOCKING mode bit is set. + *           set timeout to the MAX_SCHEDULE_TIMEOUT to maixum allowed wait. + * + * Return: written size bytes or < 0 on error + */ +ssize_t __mei_cl_send_timeout(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, +			      unsigned int mode, unsigned long timeout) +{  	struct mei_device *bus;  	struct mei_cl_cb *cb;  	ssize_t rets; @@ -108,7 +128,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag,  		cb->buf.size = 0;  	} -	rets = mei_cl_write(cl, cb); +	rets = mei_cl_write(cl, cb, timeout);  	if (mode & MEI_CL_IO_SGL && rets == 0)  		rets = length; @@ -682,13 +702,15 @@ void *mei_cldev_dma_map(struct mei_cl_device *cldev, u8 buffer_id, size_t size)  	if (cl->state == MEI_FILE_UNINITIALIZED) {  		ret = mei_cl_link(cl);  		if (ret) -			goto out; +			goto notlinked;  		/* update pointers */  		cl->cldev = cldev;  	}  	ret = mei_cl_dma_alloc_and_map(cl, NULL, buffer_id, size); -out: +	if (ret) +		mei_cl_unlink(cl); +notlinked:  	mutex_unlock(&bus->device_lock);  	if (ret)  		return ERR_PTR(ret); @@ -738,7 +760,7 @@ int mei_cldev_enable(struct mei_cl_device *cldev)  	if (cl->state == MEI_FILE_UNINITIALIZED) {  		ret = mei_cl_link(cl);  		if (ret) -			goto out; +			goto notlinked;  		/* update pointers */  		cl->cldev = cldev;  	} @@ -765,6 +787,9 @@ int mei_cldev_enable(struct mei_cl_device *cldev)  	}  out: +	if (ret) +		mei_cl_unlink(cl); +notlinked:  	mutex_unlock(&bus->device_lock);  	return ret; @@ -1257,7 +1282,6 @@ static void mei_cl_bus_dev_release(struct device *dev)  	mei_cl_flush_queues(cldev->cl, NULL);  	mei_me_cl_put(cldev->me_cl);  	mei_dev_bus_put(cldev->bus); -	mei_cl_unlink(cldev->cl);  	kfree(cldev->cl);  	kfree(cldev);  }  | 
