diff options
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r-- | drivers/misc/mei/main.c | 143 |
1 files changed, 66 insertions, 77 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 401a3d526cd0..beedc91f03a6 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -17,12 +17,12 @@ #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/slab.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/aio.h> -#include <linux/pci.h> #include <linux/poll.h> #include <linux/init.h> #include <linux/ioctl.h> @@ -44,7 +44,7 @@ * @inode: pointer to inode structure * @file: pointer to file structure * - * returns 0 on success, <0 on error + * Return: 0 on success, <0 on error */ static int mei_open(struct inode *inode, struct file *file) { @@ -63,7 +63,7 @@ static int mei_open(struct inode *inode, struct file *file) err = -ENODEV; if (dev->dev_state != MEI_DEV_ENABLED) { - dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", + dev_dbg(dev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", mei_dev_state_str(dev->dev_state)); goto err_unlock; } @@ -96,7 +96,7 @@ err_unlock: * @inode: pointer to inode structure * @file: pointer to file structure * - * returns 0 on success, <0 on error + * Return: 0 on success, <0 on error */ static int mei_release(struct inode *inode, struct file *file) { @@ -157,7 +157,7 @@ out: * @length: buffer length * @offset: data offset in buffer * - * returns >=0 data length on success , <0 on error + * Return: >=0 data length on success , <0 on error */ static ssize_t mei_read(struct file *file, char __user *ubuf, size_t length, loff_t *offset) @@ -211,7 +211,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, err = mei_cl_read_start(cl, length); if (err && err != -EBUSY) { - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "mei start read failure with status = %d\n", err); rets = err; goto out; @@ -254,7 +254,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, } /* now copy the data to user space */ copy_buffer: - dev_dbg(&dev->pdev->dev, "buf.size = %d buf.idx= %ld\n", + dev_dbg(dev->dev, "buf.size = %d buf.idx= %ld\n", cb->response_buffer.size, cb->buf_idx); if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { rets = -EMSGSIZE; @@ -266,7 +266,7 @@ copy_buffer: length = min_t(size_t, length, cb->buf_idx - *offset); if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + dev_dbg(dev->dev, "failed to copy data to userland\n"); rets = -EFAULT; goto free; } @@ -285,7 +285,7 @@ free: cl->reading_state = MEI_IDLE; cl->read_cb = NULL; out: - dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); + dev_dbg(dev->dev, "end mei read rets= %d\n", rets); mutex_unlock(&dev->device_lock); return rets; } @@ -297,17 +297,17 @@ out: * @length: buffer length * @offset: data offset in buffer * - * returns >=0 data length on success , <0 on error + * Return: >=0 data length on success , <0 on error */ static ssize_t mei_write(struct file *file, const char __user *ubuf, size_t length, loff_t *offset) { struct mei_cl *cl = file->private_data; + struct mei_me_client *me_cl; struct mei_cl_cb *write_cb = NULL; struct mei_device *dev; unsigned long timeout = 0; int rets; - int id; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -321,8 +321,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) { + me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); + if (!me_cl) { rets = -ENOTTY; goto out; } @@ -332,13 +332,13 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - if (length > dev->me_clients[id].props.max_msg_length) { + if (length > me_cl->props.max_msg_length) { rets = -EFBIG; goto out; } if (cl->state != MEI_FILE_CONNECTED) { - dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", + dev_err(dev->dev, "host client = %d, is not connected to ME client = %d", cl->host_client_id, cl->me_client_id); rets = -ENODEV; goto out; @@ -377,7 +377,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb = mei_io_cb_init(cl, file); if (!write_cb) { - dev_err(&dev->pdev->dev, "write cb allocation failed\n"); rets = -ENOMEM; goto out; } @@ -387,7 +386,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); if (rets) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); + dev_dbg(dev->dev, "failed to copy data from userland\n"); rets = -EFAULT; goto out; } @@ -396,7 +395,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = mei_amthif_write(dev, write_cb); if (rets) { - dev_err(&dev->pdev->dev, + dev_err(dev->dev, "amthif write failed with status = %d\n", rets); goto out; } @@ -415,27 +414,23 @@ out: /** * mei_ioctl_connect_client - the connect to fw client IOCTL function * - * @dev: the device structure - * @data: IOCTL connect data, input and output parameters * @file: private data of the file object + * @data: IOCTL connect data, input and output parameters * * Locking: called under "dev->device_lock" lock * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ static int mei_ioctl_connect_client(struct file *file, struct mei_connect_client_data *data) { struct mei_device *dev; struct mei_client *client; + struct mei_me_client *me_cl; struct mei_cl *cl; - int i; int rets; cl = file->private_data; - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - dev = cl->dev; if (dev->dev_state != MEI_DEV_ENABLED) { @@ -450,28 +445,29 @@ static int mei_ioctl_connect_client(struct file *file, } /* find ME client we're trying to connect to */ - i = mei_me_cl_by_uuid(dev, &data->in_client_uuid); - if (i < 0 || dev->me_clients[i].props.fixed_address) { - dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n", + me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid); + if (!me_cl || me_cl->props.fixed_address) { + dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n", &data->in_client_uuid); rets = -ENOTTY; goto end; } - cl->me_client_id = dev->me_clients[i].client_id; + cl->me_client_id = me_cl->client_id; + cl->cl_uuid = me_cl->props.protocol_name; - dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", + dev_dbg(dev->dev, "Connect to FW Client ID = %d\n", cl->me_client_id); - dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", - dev->me_clients[i].props.protocol_version); - dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", - dev->me_clients[i].props.max_msg_length); + dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n", + me_cl->props.protocol_version); + dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n", + me_cl->props.max_msg_length); /* if we're connecting to amthif client then we will use the * existing connection */ if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) { - dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); + dev_dbg(dev->dev, "FW Client is amthi\n"); if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { rets = -ENODEV; goto end; @@ -484,10 +480,8 @@ static int mei_ioctl_connect_client(struct file *file, file->private_data = &dev->iamthif_cl; client = &data->out_client_properties; - client->max_msg_length = - dev->me_clients[i].props.max_msg_length; - client->protocol_version = - dev->me_clients[i].props.protocol_version; + client->max_msg_length = me_cl->props.max_msg_length; + client->protocol_version = me_cl->props.protocol_version; rets = dev->iamthif_cl.status; goto end; @@ -496,9 +490,9 @@ static int mei_ioctl_connect_client(struct file *file, /* prepare the output buffer */ client = &data->out_client_properties; - client->max_msg_length = dev->me_clients[i].props.max_msg_length; - client->protocol_version = dev->me_clients[i].props.protocol_version; - dev_dbg(&dev->pdev->dev, "Can connect?\n"); + client->max_msg_length = me_cl->props.max_msg_length; + client->protocol_version = me_cl->props.protocol_version; + dev_dbg(dev->dev, "Can connect?\n"); rets = mei_cl_connect(cl, file); @@ -507,7 +501,6 @@ end: return rets; } - /** * mei_ioctl - the IOCTL function * @@ -515,24 +508,22 @@ end: * @cmd: ioctl command * @data: pointer to mei message structure * - * returns 0 on success , <0 on error + * Return: 0 on success , <0 on error */ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) { struct mei_device *dev; struct mei_cl *cl = file->private_data; - struct mei_connect_client_data *connect_data = NULL; + struct mei_connect_client_data connect_data; int rets; - if (cmd != IOCTL_MEI_CONNECT_CLIENT) - return -EINVAL; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; dev = cl->dev; - dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); + dev_dbg(dev->dev, "IOCTL cmd = 0x%x", cmd); mutex_lock(&dev->device_lock); if (dev->dev_state != MEI_DEV_ENABLED) { @@ -540,38 +531,36 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) goto out; } - dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); - - connect_data = kzalloc(sizeof(struct mei_connect_client_data), - GFP_KERNEL); - if (!connect_data) { - rets = -ENOMEM; - goto out; - } - dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); - if (copy_from_user(connect_data, (char __user *)data, + switch (cmd) { + case IOCTL_MEI_CONNECT_CLIENT: + dev_dbg(dev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); + if (copy_from_user(&connect_data, (char __user *)data, sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); - rets = -EFAULT; - goto out; - } - - rets = mei_ioctl_connect_client(file, connect_data); + dev_dbg(dev->dev, "failed to copy data from userland\n"); + rets = -EFAULT; + goto out; + } - /* if all is ok, copying the data back to user. */ - if (rets) - goto out; + rets = mei_ioctl_connect_client(file, &connect_data); + if (rets) + goto out; - dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); - if (copy_to_user((char __user *)data, connect_data, + /* if all is ok, copying the data back to user. */ + if (copy_to_user((char __user *)data, &connect_data, sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); - rets = -EFAULT; - goto out; + dev_dbg(dev->dev, "failed to copy data to userland\n"); + rets = -EFAULT; + goto out; + } + + break; + + default: + dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); + rets = -ENOIOCTLCMD; } out: - kfree(connect_data); mutex_unlock(&dev->device_lock); return rets; } @@ -583,7 +572,7 @@ out: * @cmd: ioctl command * @data: pointer to mei message structure * - * returns 0 on success , <0 on error + * Return: 0 on success , <0 on error */ #ifdef CONFIG_COMPAT static long mei_compat_ioctl(struct file *file, @@ -600,7 +589,7 @@ static long mei_compat_ioctl(struct file *file, * @file: pointer to file structure * @wait: pointer to poll_table structure * - * returns poll mask + * Return: poll mask */ static unsigned int mei_poll(struct file *file, poll_table *wait) { @@ -670,7 +659,7 @@ static DEFINE_IDR(mei_idr); * * @dev: device pointer * - * returns allocated minor, or -ENOSPC if no free minor left + * Return: allocated minor, or -ENOSPC if no free minor left */ static int mei_minor_get(struct mei_device *dev) { @@ -681,7 +670,7 @@ static int mei_minor_get(struct mei_device *dev) if (ret >= 0) dev->minor = ret; else if (ret == -ENOSPC) - dev_err(&dev->pdev->dev, "too many mei devices\n"); + dev_err(dev->dev, "too many mei devices\n"); mutex_unlock(&mei_minor_lock); return ret; |