|
|
@@ -84,106 +84,6 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * mei_amthif_read - read data from AMTHIF client
|
|
|
- *
|
|
|
- * @dev: the device structure
|
|
|
- * @file: pointer to file object
|
|
|
- * @ubuf: pointer to user data in user space
|
|
|
- * @length: data length to read
|
|
|
- * @offset: data read offset
|
|
|
- *
|
|
|
- * Locking: called under "dev->device_lock" lock
|
|
|
- *
|
|
|
- * Return:
|
|
|
- * returned data length on success,
|
|
|
- * zero if no data to read,
|
|
|
- * negative on failure.
|
|
|
- */
|
|
|
-int mei_amthif_read(struct mei_device *dev, struct file *file,
|
|
|
- char __user *ubuf, size_t length, loff_t *offset)
|
|
|
-{
|
|
|
- struct mei_cl *cl = file->private_data;
|
|
|
- struct mei_cl_cb *cb;
|
|
|
- int rets;
|
|
|
- int wait_ret;
|
|
|
-
|
|
|
- dev_dbg(dev->dev, "checking amthif data\n");
|
|
|
- cb = mei_cl_read_cb(cl, file);
|
|
|
-
|
|
|
- /* Check for if we can block or not*/
|
|
|
- if (cb == NULL && file->f_flags & O_NONBLOCK)
|
|
|
- return -EAGAIN;
|
|
|
-
|
|
|
-
|
|
|
- dev_dbg(dev->dev, "waiting for amthif data\n");
|
|
|
- while (cb == NULL) {
|
|
|
- /* unlock the Mutex */
|
|
|
- mutex_unlock(&dev->device_lock);
|
|
|
-
|
|
|
- wait_ret = wait_event_interruptible(cl->rx_wait,
|
|
|
- !list_empty(&cl->rd_completed) ||
|
|
|
- !mei_cl_is_connected(cl));
|
|
|
-
|
|
|
- /* Locking again the Mutex */
|
|
|
- mutex_lock(&dev->device_lock);
|
|
|
-
|
|
|
- if (wait_ret)
|
|
|
- return -ERESTARTSYS;
|
|
|
-
|
|
|
- if (!mei_cl_is_connected(cl)) {
|
|
|
- rets = -ENODEV;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- cb = mei_cl_read_cb(cl, file);
|
|
|
- }
|
|
|
-
|
|
|
- if (cb->status) {
|
|
|
- rets = cb->status;
|
|
|
- dev_dbg(dev->dev, "read operation failed %d\n", rets);
|
|
|
- goto free;
|
|
|
- }
|
|
|
-
|
|
|
- dev_dbg(dev->dev, "Got amthif data\n");
|
|
|
- /* if the whole message will fit remove it from the list */
|
|
|
- if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
|
|
|
- list_del_init(&cb->list);
|
|
|
- else if (cb->buf_idx <= *offset) {
|
|
|
- /* end of the message has been reached */
|
|
|
- list_del_init(&cb->list);
|
|
|
- rets = 0;
|
|
|
- goto free;
|
|
|
- }
|
|
|
- /* else means that not full buffer will be read and do not
|
|
|
- * remove message from deletion list
|
|
|
- */
|
|
|
-
|
|
|
- dev_dbg(dev->dev, "amthif cb->buf.size - %zu cb->buf_idx - %zu\n",
|
|
|
- cb->buf.size, cb->buf_idx);
|
|
|
-
|
|
|
- /* length is being truncated to PAGE_SIZE, however,
|
|
|
- * the buf_idx may point beyond */
|
|
|
- length = min_t(size_t, length, (cb->buf_idx - *offset));
|
|
|
-
|
|
|
- if (copy_to_user(ubuf, cb->buf.data + *offset, length)) {
|
|
|
- dev_dbg(dev->dev, "failed to copy data to userland\n");
|
|
|
- rets = -EFAULT;
|
|
|
- } else {
|
|
|
- rets = length;
|
|
|
- if ((*offset + length) < cb->buf_idx) {
|
|
|
- *offset += length;
|
|
|
- goto out;
|
|
|
- }
|
|
|
- }
|
|
|
-free:
|
|
|
- dev_dbg(dev->dev, "free amthif cb memory.\n");
|
|
|
- *offset = 0;
|
|
|
- mei_io_cb_free(cb);
|
|
|
-out:
|
|
|
- return rets;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* mei_amthif_read_start - queue message for sending read credential
|
|
|
*
|