diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index aa1d35a51e9f3a5f51533a19e31fa85f0c977513..98335b435b75204295f8958ad4dc44449c2a4786 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -749,10 +749,31 @@ void mei_cl_set_disconnected(struct mei_cl *cl) cl->mei_flow_ctrl_creds = 0; cl->timer_count = 0; + if (!cl->me_cl) + return; + + if (!WARN_ON(cl->me_cl->connect_count == 0)) + cl->me_cl->connect_count--; + + if (cl->me_cl->connect_count == 0) + cl->me_cl->mei_flow_ctrl_creds = 0; + mei_me_cl_put(cl->me_cl); cl->me_cl = NULL; } +static int mei_cl_set_connecting(struct mei_cl *cl, struct mei_me_client *me_cl) +{ + cl->me_cl = mei_me_cl_get(me_cl); + if (!cl->me_cl) + return -ENOENT; + + cl->state = MEI_FILE_CONNECTING; + cl->me_cl->connect_count++; + + return 0; +} + /* * mei_cl_send_disconnect - send disconnect request * @@ -1009,13 +1030,9 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, if (rets) goto out; - cl->me_cl = mei_me_cl_get(me_cl); - if (!cl->me_cl) { - rets = -ENODEV; + rets = mei_cl_set_connecting(cl, me_cl); + if (rets) goto out; - } - - cl->state = MEI_FILE_CONNECTING; list_add_tail(&cb->list, &dev->ctrl_wr_list.list); /* run hbuf acquire last so we don't have to undo */ diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 87db0976671cabd60e4279d9215d79b44d593e42..96c0290da5fb8cca17bd32e7eb927f8f18c388bb 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -177,6 +177,8 @@ struct mei_fw_status { * @props: client properties * @client_id: me client id * @mei_flow_ctrl_creds: flow control credits + * @connect_count: number connections to this client + * @reserved: reserved */ struct mei_me_client { struct list_head list; @@ -184,6 +186,8 @@ struct mei_me_client { struct mei_client_properties props; u8 client_id; u8 mei_flow_ctrl_creds; + u8 connect_count; + u8 reserved; };