mei: revamp open handler counts

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>
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 88770e0..a48c0e7 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -275,6 +275,7 @@
 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 @@
 		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 @@
 
 	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 @@
 	/*
 	 * 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;