From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753402AbbCZWaa (ORCPT ); Thu, 26 Mar 2015 18:30:30 -0400 Received: from mga01.intel.com ([192.55.52.88]:27676 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752847AbbCZW3R (ORCPT ); Thu, 26 Mar 2015 18:29:17 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,475,1422950400"; d="scan'208";a="473277996" From: Tomas Winkler To: gregkh@linuxfoundation.org Cc: arnd@arndb.de, linux-kernel@vger.kernel.org, Alexander Usyskin , Tomas Winkler Subject: [char-misc-next 07/11] mei: fix flow control for single buffer clients Date: Fri, 27 Mar 2015 00:28:03 +0200 Message-Id: <1427408887-27979-7-git-send-email-tomas.winkler@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1427408887-27979-1-git-send-email-tomas.winkler@intel.com> References: <1427408887-27979-1-git-send-email-tomas.winkler@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexander Usyskin 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: Alexander Usyskin Signed-off-by: Tomas Winkler --- drivers/misc/mei/client.c | 29 +++++++++++++++++++++++------ drivers/misc/mei/mei_dev.h | 4 ++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index aa1d35a51e9f..98335b435b75 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 711e4fa8b708..f17979c680a9 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; }; -- 1.9.3