mei: revamp open handler counts
authorTomas Winkler <tomas.winkler@intel.com>
Mon, 16 Sep 2013 20:44:47 +0000 (23:44 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Oct 2013 23:01:16 +0000 (16:01 -0700)
Make open counter to be incremented and decremented
from mei_cl_link and mei_cl_unlik function respectively

Nfc was assuming symmetric linking API and thus open handler
count was never decreased. This patch fixes that.
We need to add separate open hander count for amthif which
is handled out of link/unlink functions and doesn't break
the symmetric API.

Last we do not waste clients slots if amthif or wd are not present
in the device. we don't need to allocates slots ahead
it is all covered by link/unlink before the devices is responding
to user space connection and thus not racing on allocation

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/client.c
drivers/misc/mei/init.c
drivers/misc/mei/main.c
drivers/misc/mei/mei_dev.h

index 226c3f3cd3e8e935479f65c8a700568bdfe3ff7c..4f259d411a2c245ab6df0a49cd5e37417afbfa38 100644 (file)
@@ -58,6 +58,7 @@ void mei_amthif_reset_params(struct mei_device *dev)
        dev->iamthif_state = MEI_IAMTHIF_IDLE;
        dev->iamthif_timer = 0;
        dev->iamthif_stall_timer = 0;
+       dev->iamthif_open_count = 0;
 }
 
 /**
@@ -731,8 +732,8 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file)
 */
 int mei_amthif_release(struct mei_device *dev, struct file *file)
 {
-       if (dev->open_handle_count > 0)
-               dev->open_handle_count--;
+       if (dev->iamthif_open_count > 0)
+               dev->iamthif_open_count--;
 
        if (dev->iamthif_file_object == file &&
            dev->iamthif_state != MEI_IAMTHIF_IDLE) {
index 88770e040dd168d806eb4ac17ec2c2f1c3461302..a48c0e71e69d271bc69b1eff78eb5eddef8157c9 100644 (file)
@@ -275,6 +275,7 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
 int mei_cl_link(struct mei_cl *cl, int id)
 {
        struct mei_device *dev;
+       long open_handle_count;
 
        if (WARN_ON(!cl || !cl->dev))
                return -EINVAL;
@@ -291,7 +292,8 @@ int mei_cl_link(struct mei_cl *cl, int id)
                return -EMFILE;
        }
 
-       if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
+       open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
+       if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
                dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
                        MEI_MAX_OPEN_HANDLE_COUNT);
                return -EMFILE;
@@ -337,6 +339,17 @@ int mei_cl_unlink(struct mei_cl *cl)
 
        cl_dbg(dev, cl, "unlink client");
 
+       if (dev->open_handle_count > 0)
+               dev->open_handle_count--;
+
+       /* never clear the 0 bit */
+       if (cl->host_client_id)
+               clear_bit(cl->host_client_id, dev->host_clients_map);
+
+       list_del_init(&cl->link);
+
+       cl->state = MEI_FILE_INITIALIZING;
+
        list_del_init(&cl->link);
 
        return 0;
@@ -358,10 +371,8 @@ void mei_host_client_init(struct work_struct *work)
        /*
         * Reserving the first three client IDs
         * 0: Reserved for MEI Bus Message communications
-        * 1: Reserved for Watchdog
-        * 2: Reserved for AMTHI
         */
-       bitmap_set(dev->host_clients_map, 0, 3);
+       bitmap_set(dev->host_clients_map, 0, 1);
 
        for (i = 0; i < dev->me_clients_num; i++) {
                client_props = &dev->me_clients[i].props;
index 6197018e2f16a24296619442fe6c8744c7c55b88..a7d29a7dcab2551139f09088f44fc25f3872f3f2 100644 (file)
@@ -165,12 +165,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
                /* remove entry if already in list */
                dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
                mei_cl_unlink(&dev->wd_cl);
-               if (dev->open_handle_count > 0)
-                       dev->open_handle_count--;
                mei_cl_unlink(&dev->iamthif_cl);
-               if (dev->open_handle_count > 0)
-                       dev->open_handle_count--;
-
                mei_amthif_reset_params(dev);
                memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
        }
index 87ab5ca1d633c760a5304dc5d159c437ee6816a7..9661a812f55045d2cd522a7877ed8d4759f49b38 100644 (file)
@@ -141,10 +141,6 @@ static int mei_release(struct inode *inode, struct file *file)
            cl->host_client_id,
            cl->me_client_id);
 
-       if (dev->open_handle_count > 0) {
-               clear_bit(cl->host_client_id, dev->host_clients_map);
-               dev->open_handle_count--;
-       }
        mei_cl_unlink(cl);
 
 
@@ -498,11 +494,11 @@ static int mei_ioctl_connect_client(struct file *file,
                        rets = -ENODEV;
                        goto end;
                }
-               clear_bit(cl->host_client_id, dev->host_clients_map);
                mei_cl_unlink(cl);
 
                kfree(cl);
                cl = NULL;
+               dev->iamthif_open_count++;
                file->private_data = &dev->iamthif_cl;
 
                client = &data->out_client_properties;
index 456b322013e269fc61f911d6f5761768c2863d4f..406f68e05b4ed4ccdbc6d9f886386a5d110e307b 100644 (file)
@@ -414,6 +414,7 @@ struct mei_device {
        struct file *iamthif_file_object;
        struct mei_cl iamthif_cl;
        struct mei_cl_cb *iamthif_current_cb;
+       long iamthif_open_count;
        int iamthif_mtu;
        unsigned long iamthif_timer;
        u32 iamthif_stall_timer;