From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932832AbcDTIFg (ORCPT ); Wed, 20 Apr 2016 04:05:36 -0400 Received: from mga01.intel.com ([192.55.52.88]:27105 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753765AbcDTIF0 (ORCPT ); Wed, 20 Apr 2016 04:05:26 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,508,1455004800"; d="scan'208";a="88488122" From: Tomas Winkler To: Greg Kroah-Hartman Cc: Alexander Usyskin , linux-kernel@vger.kernel.org, Tomas Winkler Subject: [char-misc-next 2/2] mei: fix waiting for wr_ctrl for corner cases. Date: Wed, 20 Apr 2016 11:03:55 -0400 Message-Id: <1461164635-8916-2-git-send-email-tomas.winkler@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1461164635-8916-1-git-send-email-tomas.winkler@intel.com> References: <1461164635-8916-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 A control message reply may not be received if either a link reset has occurred or disconnection is initiated by the FW. In the both cases the client state will be set straight to DISCONNECTED and the driver will wait till timeout. Adding DISCONNECTED state in the waiting condition will release the client from the stall. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler --- drivers/misc/mei/client.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 85ae11d410cc..eed254da63a8 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -727,6 +727,11 @@ static void mei_cl_wake_all(struct mei_cl *cl) cl_dbg(dev, cl, "Waking up waiting for event clients!\n"); wake_up_interruptible(&cl->ev_wait); } + /* synchronized under device mutex */ + if (waitqueue_active(&cl->wait)) { + cl_dbg(dev, cl, "Waking up ctrl write clients!\n"); + wake_up_interruptible(&cl->wait); + } } /** @@ -879,12 +884,15 @@ static int __mei_cl_disconnect(struct mei_cl *cl) } mutex_unlock(&dev->device_lock); - wait_event_timeout(cl->wait, cl->state == MEI_FILE_DISCONNECT_REPLY, + wait_event_timeout(cl->wait, + cl->state == MEI_FILE_DISCONNECT_REPLY || + cl->state == MEI_FILE_DISCONNECTED, mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); rets = cl->status; - if (cl->state != MEI_FILE_DISCONNECT_REPLY) { + if (cl->state != MEI_FILE_DISCONNECT_REPLY && + cl->state != MEI_FILE_DISCONNECTED) { cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); rets = -ETIME; } @@ -1085,6 +1093,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, mutex_unlock(&dev->device_lock); wait_event_timeout(cl->wait, (cl->state == MEI_FILE_CONNECTED || + cl->state == MEI_FILE_DISCONNECTED || cl->state == MEI_FILE_DISCONNECT_REQUIRED || cl->state == MEI_FILE_DISCONNECT_REPLY), mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); @@ -1333,8 +1342,9 @@ int mei_cl_notify_request(struct mei_cl *cl, } mutex_unlock(&dev->device_lock); - wait_event_timeout(cl->wait, cl->notify_en == request, - mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); + wait_event_timeout(cl->wait, + cl->notify_en == request || !mei_cl_is_connected(cl), + mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); if (cl->notify_en != request && !cl->status) -- 2.5.5