mei: add mei_me_cl_by_uuid_id function
When handling dynamic clients there might be a race scenario in which two me clients with the same me address would be linked in the me clients list, therefore we need to search by both uuid and me address. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
25ca6472b5
Коммит
d880f3294d
|
@ -83,6 +83,7 @@ int mei_amthif_host_init(struct mei_device *dev)
|
|||
}
|
||||
|
||||
cl->me_client_id = me_cl->client_id;
|
||||
cl->cl_uuid = me_cl->props.protocol_name;
|
||||
|
||||
/* Assign iamthif_mtu to the value received from ME */
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev,
|
|||
struct mei_cl *cl;
|
||||
|
||||
list_for_each_entry(cl, &dev->device_list, device_link) {
|
||||
if (!uuid_le_cmp(uuid, cl->device_uuid))
|
||||
if (!uuid_le_cmp(uuid, cl->cl_uuid))
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
|
|||
return -ENODEV;
|
||||
|
||||
/* Check if we have an ME client device */
|
||||
me_cl = mei_me_cl_by_id(dev, cl->me_client_id);
|
||||
me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
|
||||
if (!me_cl)
|
||||
return -ENOTTY;
|
||||
|
||||
|
|
|
@ -69,6 +69,18 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
|
||||
const uuid_le *uuid, u8 client_id)
|
||||
{
|
||||
struct mei_me_client *me_cl;
|
||||
|
||||
list_for_each_entry(me_cl, &dev->me_clients, list)
|
||||
if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0 &&
|
||||
me_cl->client_id == client_id)
|
||||
return me_cl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_me_cl_remove - remove me client matching uuid and client_id
|
||||
*
|
||||
|
@ -753,7 +765,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
|
|||
cl_dbg(dev, cl, "read is pending.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
me_cl = mei_me_cl_by_id(dev, cl->me_client_id);
|
||||
me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
|
||||
if (!me_cl) {
|
||||
cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
|
||||
return -ENOTTY;
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev,
|
||||
const uuid_le *cuuid);
|
||||
struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
|
||||
|
||||
struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
|
||||
const uuid_le *uuid, u8 client_id);
|
||||
|
||||
void mei_me_cl_remove(struct mei_device *dev,
|
||||
const uuid_le *uuid, u8 client_id);
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
|
|||
goto out;
|
||||
}
|
||||
|
||||
me_cl = mei_me_cl_by_id(dev, cl->me_client_id);
|
||||
me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
|
||||
if (!me_cl) {
|
||||
rets = -ENOTTY;
|
||||
goto out;
|
||||
|
@ -459,6 +459,7 @@ static int mei_ioctl_connect_client(struct file *file,
|
|||
}
|
||||
|
||||
cl->me_client_id = me_cl->client_id;
|
||||
cl->cl_uuid = me_cl->props.protocol_name;
|
||||
|
||||
dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
|
||||
cl->me_client_id);
|
||||
|
|
|
@ -212,6 +212,7 @@ struct mei_cl {
|
|||
wait_queue_head_t wait;
|
||||
int status;
|
||||
/* ID of client connected */
|
||||
uuid_le cl_uuid;
|
||||
u8 host_client_id;
|
||||
u8 me_client_id;
|
||||
u8 mei_flow_ctrl_creds;
|
||||
|
@ -223,7 +224,6 @@ struct mei_cl {
|
|||
/* MEI CL bus data */
|
||||
struct mei_cl_device *device;
|
||||
struct list_head device_link;
|
||||
uuid_le device_uuid;
|
||||
};
|
||||
|
||||
/** struct mei_hw_ops
|
||||
|
|
|
@ -507,12 +507,12 @@ int mei_nfc_host_init(struct mei_device *dev)
|
|||
}
|
||||
|
||||
cl_info->me_client_id = me_cl->client_id;
|
||||
cl_info->cl_uuid = me_cl->props.protocol_name;
|
||||
|
||||
ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
cl_info->device_uuid = mei_nfc_info_guid;
|
||||
|
||||
list_add_tail(&cl_info->device_link, &dev->device_list);
|
||||
|
||||
|
@ -525,14 +525,12 @@ int mei_nfc_host_init(struct mei_device *dev)
|
|||
}
|
||||
|
||||
cl->me_client_id = me_cl->client_id;
|
||||
cl->cl_uuid = me_cl->props.protocol_name;
|
||||
|
||||
ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
cl->device_uuid = mei_nfc_guid;
|
||||
|
||||
|
||||
list_add_tail(&cl->device_link, &dev->device_list);
|
||||
|
||||
ndev->req_id = 1;
|
||||
|
|
|
@ -76,6 +76,7 @@ int mei_wd_host_init(struct mei_device *dev)
|
|||
}
|
||||
|
||||
cl->me_client_id = me_cl->client_id;
|
||||
cl->cl_uuid = me_cl->props.protocol_name;
|
||||
|
||||
ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче