diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 226c3f3cd3e8..4f259d411a2c 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -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) { diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 88770e040dd1..a48c0e71e69d 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -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; diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 6197018e2f16..a7d29a7dcab2 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -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)); } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 87ab5ca1d633..9661a812f550 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -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; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 456b322013e2..406f68e05b4e 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -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;