mei: add mei_me_cl_by_uuid_id function
authorTomas Winkler <tomas.winkler@intel.com>
Thu, 21 Aug 2014 11:29:15 +0000 (14:29 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Sep 2014 05:57:48 +0000 (22:57 -0700)
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>
drivers/misc/mei/amthif.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/client.h
drivers/misc/mei/main.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/nfc.c
drivers/misc/mei/wd.c

index c1fc6dd8faae5d6c523da93a1965fa1a5dc8f6ef..4114758cd1ceabd5539399a4bd978f6a0af3cf81 100644 (file)
@@ -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  */
 
index c829676c471604aec417eef64d14caaffd6e9009..09dad2df7aaeab55200c130ecfdf0ca228bf739c 100644 (file)
@@ -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;
 
index 10d0a04f45d6e48327e7c5807b6ac1fc1a4b74b8..1a4dafb772052489baa2873db370e11f9c852f2f 100644 (file)
@@ -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;
index 8871a852cfbb684636c0ccba48d940edbe65aa0a..f5d03d62292399f10cb4bfff1398d2d86ae47bd9 100644 (file)
 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);
 
index a65b7cc4a8775a9333b2139259088876665cebf4..957f44aaa97ab7e8e3965dd7011c81d786ad5354 100644 (file)
@@ -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);
index 76d8aa30e90dcb95bed94fcec5bc20e0df5ac718..9f684b9b3c93eb314e917d4300ea87c20b2da124 100644 (file)
@@ -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
index 964b4c606646929e353a489328faf634fcdc251a..e0e75d429fdf3a9cbf3e4eef11e1a9779773005d 100644 (file)
@@ -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;
index 8b241eef35d2c6641416f7c9e2787564314a77be..40f46e4c2e9c713414cd4bc497ac101faec91fd1 100644 (file)
@@ -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);