aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r--drivers/misc/mei/main.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 3e2968159506..e9513d651cd3 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -94,7 +94,7 @@ static int mei_release(struct inode *inode, struct file *file)
94{ 94{
95 struct mei_cl *cl = file->private_data; 95 struct mei_cl *cl = file->private_data;
96 struct mei_device *dev; 96 struct mei_device *dev;
97 int rets = 0; 97 int rets;
98 98
99 if (WARN_ON(!cl || !cl->dev)) 99 if (WARN_ON(!cl || !cl->dev))
100 return -ENODEV; 100 return -ENODEV;
@@ -106,11 +106,8 @@ static int mei_release(struct inode *inode, struct file *file)
106 rets = mei_amthif_release(dev, file); 106 rets = mei_amthif_release(dev, file);
107 goto out; 107 goto out;
108 } 108 }
109 if (mei_cl_is_connected(cl)) { 109 rets = mei_cl_disconnect(cl);
110 cl->state = MEI_FILE_DISCONNECTING; 110
111 cl_dbg(dev, cl, "disconnecting\n");
112 rets = mei_cl_disconnect(cl);
113 }
114 mei_cl_flush_queues(cl, file); 111 mei_cl_flush_queues(cl, file);
115 cl_dbg(dev, cl, "removing\n"); 112 cl_dbg(dev, cl, "removing\n");
116 113
@@ -186,8 +183,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
186 183
187 err = mei_cl_read_start(cl, length, file); 184 err = mei_cl_read_start(cl, length, file);
188 if (err && err != -EBUSY) { 185 if (err && err != -EBUSY) {
189 dev_dbg(dev->dev, 186 cl_dbg(dev, cl, "mei start read failure status = %d\n", err);
190 "mei start read failure with status = %d\n", err);
191 rets = err; 187 rets = err;
192 goto out; 188 goto out;
193 } 189 }
@@ -218,6 +214,11 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
218 214
219 cb = mei_cl_read_cb(cl, file); 215 cb = mei_cl_read_cb(cl, file);
220 if (!cb) { 216 if (!cb) {
217 if (mei_cl_is_fixed_address(cl) && dev->allow_fixed_address) {
218 cb = mei_cl_read_cb(cl, NULL);
219 if (cb)
220 goto copy_buffer;
221 }
221 rets = 0; 222 rets = 0;
222 goto out; 223 goto out;
223 } 224 }
@@ -226,11 +227,11 @@ copy_buffer:
226 /* now copy the data to user space */ 227 /* now copy the data to user space */
227 if (cb->status) { 228 if (cb->status) {
228 rets = cb->status; 229 rets = cb->status;
229 dev_dbg(dev->dev, "read operation failed %d\n", rets); 230 cl_dbg(dev, cl, "read operation failed %d\n", rets);
230 goto free; 231 goto free;
231 } 232 }
232 233
233 dev_dbg(dev->dev, "buf.size = %d buf.idx= %ld\n", 234 cl_dbg(dev, cl, "buf.size = %d buf.idx = %ld\n",
234 cb->buf.size, cb->buf_idx); 235 cb->buf.size, cb->buf_idx);
235 if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { 236 if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) {
236 rets = -EMSGSIZE; 237 rets = -EMSGSIZE;
@@ -256,7 +257,7 @@ free:
256 mei_io_cb_free(cb); 257 mei_io_cb_free(cb);
257 258
258out: 259out:
259 dev_dbg(dev->dev, "end mei read rets= %d\n", rets); 260 cl_dbg(dev, cl, "end mei read rets = %d\n", rets);
260 mutex_unlock(&dev->device_lock); 261 mutex_unlock(&dev->device_lock);
261 return rets; 262 return rets;
262} 263}
@@ -274,7 +275,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
274 size_t length, loff_t *offset) 275 size_t length, loff_t *offset)
275{ 276{
276 struct mei_cl *cl = file->private_data; 277 struct mei_cl *cl = file->private_data;
277 struct mei_me_client *me_cl = NULL;
278 struct mei_cl_cb *write_cb = NULL; 278 struct mei_cl_cb *write_cb = NULL;
279 struct mei_device *dev; 279 struct mei_device *dev;
280 unsigned long timeout = 0; 280 unsigned long timeout = 0;
@@ -292,27 +292,27 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
292 goto out; 292 goto out;
293 } 293 }
294 294
295 me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 295 if (!mei_cl_is_connected(cl)) {
296 if (!me_cl) { 296 cl_err(dev, cl, "is not connected");
297 rets = -ENOTTY; 297 rets = -ENODEV;
298 goto out; 298 goto out;
299 } 299 }
300 300
301 if (length == 0) { 301 if (!mei_me_cl_is_active(cl->me_cl)) {
302 rets = 0; 302 rets = -ENOTTY;
303 goto out; 303 goto out;
304 } 304 }
305 305
306 if (length > me_cl->props.max_msg_length) { 306 if (length > mei_cl_mtu(cl)) {
307 rets = -EFBIG; 307 rets = -EFBIG;
308 goto out; 308 goto out;
309 } 309 }
310 310
311 if (!mei_cl_is_connected(cl)) { 311 if (length == 0) {
312 cl_err(dev, cl, "is not connected"); 312 rets = 0;
313 rets = -ENODEV;
314 goto out; 313 goto out;
315 } 314 }
315
316 if (cl == &dev->iamthif_cl) { 316 if (cl == &dev->iamthif_cl) {
317 write_cb = mei_amthif_find_read_list_entry(dev, file); 317 write_cb = mei_amthif_find_read_list_entry(dev, file);
318 318
@@ -350,14 +350,12 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
350 "amthif write failed with status = %d\n", rets); 350 "amthif write failed with status = %d\n", rets);
351 goto out; 351 goto out;
352 } 352 }
353 mei_me_cl_put(me_cl);
354 mutex_unlock(&dev->device_lock); 353 mutex_unlock(&dev->device_lock);
355 return length; 354 return length;
356 } 355 }
357 356
358 rets = mei_cl_write(cl, write_cb, false); 357 rets = mei_cl_write(cl, write_cb, false);
359out: 358out:
360 mei_me_cl_put(me_cl);
361 mutex_unlock(&dev->device_lock); 359 mutex_unlock(&dev->device_lock);
362 if (rets < 0) 360 if (rets < 0)
363 mei_io_cb_free(write_cb); 361 mei_io_cb_free(write_cb);
@@ -395,17 +393,16 @@ static int mei_ioctl_connect_client(struct file *file,
395 393
396 /* find ME client we're trying to connect to */ 394 /* find ME client we're trying to connect to */
397 me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid); 395 me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
398 if (!me_cl || me_cl->props.fixed_address) { 396 if (!me_cl ||
397 (me_cl->props.fixed_address && !dev->allow_fixed_address)) {
399 dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n", 398 dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n",
400 &data->in_client_uuid); 399 &data->in_client_uuid);
400 mei_me_cl_put(me_cl);
401 return -ENOTTY; 401 return -ENOTTY;
402 } 402 }
403 403
404 cl->me_client_id = me_cl->client_id;
405 cl->cl_uuid = me_cl->props.protocol_name;
406
407 dev_dbg(dev->dev, "Connect to FW Client ID = %d\n", 404 dev_dbg(dev->dev, "Connect to FW Client ID = %d\n",
408 cl->me_client_id); 405 me_cl->client_id);
409 dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n", 406 dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n",
410 me_cl->props.protocol_version); 407 me_cl->props.protocol_version);
411 dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n", 408 dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n",
@@ -441,7 +438,7 @@ static int mei_ioctl_connect_client(struct file *file,
441 client->protocol_version = me_cl->props.protocol_version; 438 client->protocol_version = me_cl->props.protocol_version;
442 dev_dbg(dev->dev, "Can connect?\n"); 439 dev_dbg(dev->dev, "Can connect?\n");
443 440
444 rets = mei_cl_connect(cl, file); 441 rets = mei_cl_connect(cl, me_cl, file);
445 442
446end: 443end:
447 mei_me_cl_put(me_cl); 444 mei_me_cl_put(me_cl);
@@ -685,7 +682,7 @@ int mei_register(struct mei_device *dev, struct device *parent)
685 /* Fill in the data structures */ 682 /* Fill in the data structures */
686 devno = MKDEV(MAJOR(mei_devt), dev->minor); 683 devno = MKDEV(MAJOR(mei_devt), dev->minor);
687 cdev_init(&dev->cdev, &mei_fops); 684 cdev_init(&dev->cdev, &mei_fops);
688 dev->cdev.owner = mei_fops.owner; 685 dev->cdev.owner = parent->driver->owner;
689 686
690 /* Add the device */ 687 /* Add the device */
691 ret = cdev_add(&dev->cdev, devno, 1); 688 ret = cdev_add(&dev->cdev, devno, 1);