diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2012-10-09 10:50:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-24 18:35:03 -0400 |
commit | 33d28c9205257479be540a31b03339817cf2d62c (patch) | |
tree | 504cd9d808fe25660d3e9ca961223380fdfa6866 /drivers/misc/mei/main.c | |
parent | ebb108ef93605a68f6f38d5eb407e7d5138e8028 (diff) |
mei: add allocation and initialization wrappers for io callback
mei_io_cb_init - allocat and initializate mei_cl_cb
mei_io_cb_alloc_req/resp_buf are separate function as buffers
are not always needed
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r-- | drivers/misc/mei/main.c | 111 |
1 files changed, 87 insertions, 24 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 3d4f6d17d74c..15de4b19caa5 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -516,6 +516,83 @@ out: | |||
516 | } | 516 | } |
517 | 517 | ||
518 | /** | 518 | /** |
519 | * mei_io_cb_init - allocate and initialize io callback | ||
520 | * | ||
521 | * @cl - mei client | ||
522 | * @file: pointer to file structure | ||
523 | * | ||
524 | * returns mei_cl_cb pointer or NULL; | ||
525 | */ | ||
526 | static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) | ||
527 | { | ||
528 | struct mei_cl_cb *cb; | ||
529 | struct mei_device *dev; | ||
530 | |||
531 | dev = cl->dev; | ||
532 | |||
533 | cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); | ||
534 | if (!cb) | ||
535 | return NULL; | ||
536 | |||
537 | INIT_LIST_HEAD(&cb->cb_list); | ||
538 | |||
539 | cb->file_object = fp; | ||
540 | cb->file_private = cl; | ||
541 | cb->buf_idx = 0; | ||
542 | return cb; | ||
543 | } | ||
544 | |||
545 | |||
546 | /** | ||
547 | * mei_io_cb_alloc_req_buf - allocate request buffer | ||
548 | * | ||
549 | * @cb - io callback structure | ||
550 | * @size: size of the buffer | ||
551 | * | ||
552 | * returns 0 on success | ||
553 | * -EINVAL if cb is NULL | ||
554 | * -ENOMEM if allocation failed | ||
555 | */ | ||
556 | static int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length) | ||
557 | { | ||
558 | if (!cb) | ||
559 | return -EINVAL; | ||
560 | |||
561 | if (length == 0) | ||
562 | return 0; | ||
563 | |||
564 | cb->request_buffer.data = kmalloc(length, GFP_KERNEL); | ||
565 | if (!cb->request_buffer.data) | ||
566 | return -ENOMEM; | ||
567 | cb->request_buffer.size = length; | ||
568 | return 0; | ||
569 | } | ||
570 | /** | ||
571 | * mei_io_cb_alloc_req_buf - allocate respose buffer | ||
572 | * | ||
573 | * @cb - io callback structure | ||
574 | * @size: size of the buffer | ||
575 | * | ||
576 | * returns 0 on success | ||
577 | * -EINVAL if cb is NULL | ||
578 | * -ENOMEM if allocation failed | ||
579 | */ | ||
580 | static int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) | ||
581 | { | ||
582 | if (!cb) | ||
583 | return -EINVAL; | ||
584 | |||
585 | if (length == 0) | ||
586 | return 0; | ||
587 | |||
588 | cb->response_buffer.data = kmalloc(length, GFP_KERNEL); | ||
589 | if (!cb->response_buffer.data) | ||
590 | return -ENOMEM; | ||
591 | cb->response_buffer.size = length; | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | /** | ||
519 | * mei_write - the write function. | 596 | * mei_write - the write function. |
520 | * | 597 | * |
521 | * @file: pointer to file structure | 598 | * @file: pointer to file structure |
@@ -581,20 +658,17 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
581 | *offset = 0; | 658 | *offset = 0; |
582 | 659 | ||
583 | 660 | ||
584 | write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); | 661 | write_cb = mei_io_cb_init(cl, file); |
585 | if (!write_cb) { | 662 | if (!write_cb) { |
586 | mutex_unlock(&dev->device_lock); | 663 | dev_err(&dev->pdev->dev, "write cb allocation failed\n"); |
587 | return -ENOMEM; | 664 | rets = -ENOMEM; |
665 | goto unlock_dev; | ||
588 | } | 666 | } |
589 | 667 | rets = mei_io_cb_alloc_req_buf(write_cb, length); | |
590 | write_cb->file_object = file; | 668 | if (rets) |
591 | write_cb->file_private = cl; | ||
592 | write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); | ||
593 | rets = -ENOMEM; | ||
594 | if (!write_cb->request_buffer.data) | ||
595 | goto unlock_dev; | 669 | goto unlock_dev; |
596 | 670 | ||
597 | dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length); | 671 | dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); |
598 | 672 | ||
599 | rets = -EFAULT; | 673 | rets = -EFAULT; |
600 | if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) | 674 | if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) |
@@ -610,14 +684,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
610 | write_cb->request_buffer.data, 4) == 0))) | 684 | write_cb->request_buffer.data, 4) == 0))) |
611 | cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; | 685 | cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; |
612 | 686 | ||
613 | INIT_LIST_HEAD(&write_cb->cb_list); | ||
614 | if (cl == &dev->iamthif_cl) { | 687 | if (cl == &dev->iamthif_cl) { |
615 | write_cb->response_buffer.data = | ||
616 | kmalloc(dev->iamthif_mtu, GFP_KERNEL); | ||
617 | if (!write_cb->response_buffer.data) { | ||
618 | rets = -ENOMEM; | ||
619 | goto unlock_dev; | ||
620 | } | ||
621 | if (dev->dev_state != MEI_DEV_ENABLED) { | 688 | if (dev->dev_state != MEI_DEV_ENABLED) { |
622 | rets = -ENODEV; | 689 | rets = -ENODEV; |
623 | goto unlock_dev; | 690 | goto unlock_dev; |
@@ -632,11 +699,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
632 | rets = -EMSGSIZE; | 699 | rets = -EMSGSIZE; |
633 | goto unlock_dev; | 700 | goto unlock_dev; |
634 | } | 701 | } |
702 | rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); | ||
703 | if (rets) | ||
704 | goto unlock_dev; | ||
635 | 705 | ||
636 | write_cb->response_buffer.size = dev->iamthif_mtu; | ||
637 | write_cb->major_file_operations = MEI_IOCTL; | 706 | write_cb->major_file_operations = MEI_IOCTL; |
638 | write_cb->buf_idx = 0; | ||
639 | write_cb->request_buffer.size = length; | ||
640 | if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { | 707 | if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { |
641 | rets = -ENODEV; | 708 | rets = -ENODEV; |
642 | goto unlock_dev; | 709 | goto unlock_dev; |
@@ -666,9 +733,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
666 | } | 733 | } |
667 | 734 | ||
668 | write_cb->major_file_operations = MEI_WRITE; | 735 | write_cb->major_file_operations = MEI_WRITE; |
669 | /* make sure buffer index is zero before we start */ | ||
670 | write_cb->buf_idx = 0; | ||
671 | write_cb->request_buffer.size = length; | ||
672 | 736 | ||
673 | dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", | 737 | dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", |
674 | cl->host_client_id, cl->me_client_id); | 738 | cl->host_client_id, cl->me_client_id); |
@@ -688,7 +752,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
688 | rets = -EINVAL; | 752 | rets = -EINVAL; |
689 | goto unlock_dev; | 753 | goto unlock_dev; |
690 | } | 754 | } |
691 | write_cb->file_private = cl; | ||
692 | 755 | ||
693 | rets = mei_flow_ctrl_creds(dev, cl); | 756 | rets = mei_flow_ctrl_creds(dev, cl); |
694 | if (rets < 0) | 757 | if (rets < 0) |