[char-misc-next 15/18] mei: add mei_cl_alloc_linked function

From: Tomas Winkler
Date: Tue Feb 10 2015 - 03:43:03 EST


Add convenient wrapper mei_cl_alloc_linked
to simplify error handling

Signed-off-by: Tomas Winkler <tomas.winkler@xxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/