mei: add mei_cl_alloc_linked function

Add convenient wrapper mei_cl_alloc_linked
to simplify error handling

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tomas Winkler 2015-02-10 10:39:44 +02:00 committed by Greg Kroah-Hartman
parent bca67d681c
commit 03b8d3419f
4 changed files with 61 additions and 36 deletions

View file

@ -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)
{
@ -869,6 +869,37 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
return rets;
}
/**
* 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.
*

View file

@ -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);

View file

@ -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;
}

View file

@ -482,8 +482,8 @@ static void mei_nfc_init(struct work_struct *work)
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;