diff options
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r-- | drivers/misc/mei/main.c | 59 |
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 | ||
258 | out: | 259 | out: |
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); |
359 | out: | 358 | out: |
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 | ||
446 | end: | 443 | end: |
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); |