Add convenient wrapper mei_cl_alloc_linked
to simplify error handling

Signed-off-by: Tomas Winkler <tomas.wink...@intel.com>
---
 drivers/misc/mei/client.c | 35 +++++++++++++++++++++++++++++++++--
 drivers/misc/mei/client.h |  2 ++
 drivers/misc/mei/main.c   | 17 +++++------------
 drivers/misc/mei/nfc.c    | 43 +++++++++++++++++++++----------------------
 4 files changed, 61 insertions(+), 36 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 86450c2fc810..830a3facbb2b 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -547,11 +547,11 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
  * mei_cl_link - allocate host id in the host map
  *
  * @cl: host client
- * @id: fixed host id or -1 for generic one
+ * @id: fixed host id or MEI_HOST_CLIENT_ID_ANY (-1) for generic one
  *
  * Return: 0 on success
  *     -EINVAL on incorrect values
- *     -ENONET if client not found
+ *     -EMFILE if open count exceeded.
  */
 int mei_cl_link(struct mei_cl *cl, int id)
 {
@@ -870,6 +870,37 @@ out:
 }
 
 /**
+ * mei_cl_alloc_linked - allocate and link host client
+ *
+ * @dev: the device structure
+ * @id: fixed host id or MEI_HOST_CLIENT_ID_ANY (-1) for generic one
+ *
+ * Return: cl on success ERR_PTR on failure
+ */
+struct mei_cl *mei_cl_alloc_linked(struct mei_device *dev, int id)
+{
+       struct mei_cl *cl;
+       int ret;
+
+       cl = mei_cl_allocate(dev);
+       if (!cl) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       ret = mei_cl_link(cl, id);
+       if (ret)
+               goto err;
+
+       return cl;
+err:
+       kfree(cl);
+       return ERR_PTR(ret);
+}
+
+
+
+/**
  * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
  *
  * @cl: private data of the file object
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index f7d0285b5f57..c3d0e200a642 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -75,6 +75,8 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
 int mei_cl_link(struct mei_cl *cl, int id);
 int mei_cl_unlink(struct mei_cl *cl);
 
+struct mei_cl *mei_cl_alloc_linked(struct mei_device *dev, int id);
+
 int mei_cl_flush_queues(struct mei_cl *cl);
 struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl);
 
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 369de0a070f1..10fc3a6a1574 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -59,24 +59,18 @@ static int mei_open(struct inode *inode, struct file *file)
 
        mutex_lock(&dev->device_lock);
 
-       cl = NULL;
-
-       err = -ENODEV;
        if (dev->dev_state != MEI_DEV_ENABLED) {
                dev_dbg(dev->dev, "dev_state != MEI_ENABLED  dev_state = %s\n",
                    mei_dev_state_str(dev->dev_state));
+               err = -ENODEV;
                goto err_unlock;
        }
 
-       err = -ENOMEM;
-       cl = mei_cl_allocate(dev);
-       if (!cl)
-               goto err_unlock;
-
-       /* open_handle_count check is handled in the mei_cl_link */
-       err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
-       if (err)
+       cl = mei_cl_alloc_linked(dev, MEI_HOST_CLIENT_ID_ANY);
+       if (IS_ERR(cl)) {
+               err = PTR_ERR(cl);
                goto err_unlock;
+       }
 
        file->private_data = cl;
 
@@ -86,7 +80,6 @@ static int mei_open(struct inode *inode, struct file *file)
 
 err_unlock:
        mutex_unlock(&dev->device_lock);
-       kfree(cl);
        return err;
 }
 
diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c
index bb61a119b8bb..c3bcb63686d7 100644
--- a/drivers/misc/mei/nfc.c
+++ b/drivers/misc/mei/nfc.c
@@ -482,8 +482,8 @@ err:
 int mei_nfc_host_init(struct mei_device *dev)
 {
        struct mei_nfc_dev *ndev;
-       struct mei_cl *cl_info, *cl = NULL;
-       struct mei_me_client *me_cl;
+       struct mei_cl *cl_info, *cl;
+       struct mei_me_client *me_cl = NULL;
        int ret;
 
 
@@ -500,17 +500,6 @@ int mei_nfc_host_init(struct mei_device *dev)
                goto err;
        }
 
-       ndev->cl_info = mei_cl_allocate(dev);
-       ndev->cl = mei_cl_allocate(dev);
-
-       cl = ndev->cl;
-       cl_info = ndev->cl_info;
-
-       if (!cl || !cl_info) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
        /* check for valid client id */
        me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid);
        if (!me_cl) {
@@ -519,17 +508,21 @@ int mei_nfc_host_init(struct mei_device *dev)
                goto err;
        }
 
+       cl_info = mei_cl_alloc_linked(dev, MEI_HOST_CLIENT_ID_ANY);
+       if (IS_ERR(cl_info)) {
+               ret = PTR_ERR(cl_info);
+               goto err;
+       }
+
        cl_info->me_client_id = me_cl->client_id;
        cl_info->cl_uuid = me_cl->props.protocol_name;
        mei_me_cl_put(me_cl);
-
-       ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY);
-       if (ret)
-               goto err;
-
+       me_cl = NULL;
 
        list_add_tail(&cl_info->device_link, &dev->device_list);
 
+       ndev->cl_info = cl_info;
+
        /* check for valid client id */
        me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid);
        if (!me_cl) {
@@ -538,16 +531,21 @@ int mei_nfc_host_init(struct mei_device *dev)
                goto err;
        }
 
+       cl = mei_cl_alloc_linked(dev, MEI_HOST_CLIENT_ID_ANY);
+       if (IS_ERR(cl)) {
+               ret = PTR_ERR(cl);
+               goto err;
+       }
+
        cl->me_client_id = me_cl->client_id;
        cl->cl_uuid = me_cl->props.protocol_name;
        mei_me_cl_put(me_cl);
-
-       ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
-       if (ret)
-               goto err;
+       me_cl = NULL;
 
        list_add_tail(&cl->device_link, &dev->device_list);
 
+       ndev->cl = cl;
+
        ndev->req_id = 1;
 
        INIT_WORK(&ndev->init_work, mei_nfc_init);
@@ -557,6 +555,7 @@ int mei_nfc_host_init(struct mei_device *dev)
        return 0;
 
 err:
+       mei_me_cl_put(me_cl);
        mei_nfc_free(ndev);
 
        return ret;
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to