Commit a03d77f6 authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman

mei: fix flow control for single buffer clients

For ME clients that use single receiving buffer
the driver tracks credentials on mei_me_clients structure
for all connections. The driver needs to book keep the shared
resource correctly and track the connections, particularly
the credit has to be cleaned when there is no active connection
to a particular me client. This solves issue when subsequent
connection will not get an ill impression that it can write.

We add active connection counter the particular ME client and
when the counter reach zero, we clear the credits.
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d49ed64a
...@@ -749,10 +749,31 @@ void mei_cl_set_disconnected(struct mei_cl *cl) ...@@ -749,10 +749,31 @@ void mei_cl_set_disconnected(struct mei_cl *cl)
cl->mei_flow_ctrl_creds = 0; cl->mei_flow_ctrl_creds = 0;
cl->timer_count = 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); mei_me_cl_put(cl->me_cl);
cl->me_cl = NULL; 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 * 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, ...@@ -1009,13 +1030,9 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
if (rets) if (rets)
goto out; goto out;
cl->me_cl = mei_me_cl_get(me_cl); rets = mei_cl_set_connecting(cl, me_cl);
if (!cl->me_cl) { if (rets)
rets = -ENODEV;
goto out; goto out;
}
cl->state = MEI_FILE_CONNECTING;
list_add_tail(&cb->list, &dev->ctrl_wr_list.list); list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
/* run hbuf acquire last so we don't have to undo */ /* run hbuf acquire last so we don't have to undo */
......
...@@ -177,6 +177,8 @@ struct mei_fw_status { ...@@ -177,6 +177,8 @@ struct mei_fw_status {
* @props: client properties * @props: client properties
* @client_id: me client id * @client_id: me client id
* @mei_flow_ctrl_creds: flow control credits * @mei_flow_ctrl_creds: flow control credits
* @connect_count: number connections to this client
* @reserved: reserved
*/ */
struct mei_me_client { struct mei_me_client {
struct list_head list; struct list_head list;
...@@ -184,6 +186,8 @@ struct mei_me_client { ...@@ -184,6 +186,8 @@ struct mei_me_client {
struct mei_client_properties props; struct mei_client_properties props;
u8 client_id; u8 client_id;
u8 mei_flow_ctrl_creds; u8 mei_flow_ctrl_creds;
u8 connect_count;
u8 reserved;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment