From patchwork Mon Jul 6 14:46:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 6725281 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1F3209F38C for ; Mon, 6 Jul 2015 14:47:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 29F3F205FE for ; Mon, 6 Jul 2015 14:47:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 32F79205ED for ; Mon, 6 Jul 2015 14:47:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751085AbbGFOrR (ORCPT ); Mon, 6 Jul 2015 10:47:17 -0400 Received: from arroyo.ext.ti.com ([192.94.94.40]:50715 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750945AbbGFOrJ (ORCPT ); Mon, 6 Jul 2015 10:47:09 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id t66El4Bt024730; Mon, 6 Jul 2015 09:47:04 -0500 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id t66El4hg015922; Mon, 6 Jul 2015 09:47:04 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.224.2; Mon, 6 Jul 2015 09:46:52 -0500 Received: from rockdesk.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id t66El07r024212; Mon, 6 Jul 2015 09:47:02 -0500 From: Roger Quadros To: CC: , , , Roger Quadros , Greg Kroah-Hartman Subject: [PATCH 1/2] extcon: fix hang and extcon_get/set_cable_state(). Date: Mon, 6 Jul 2015 17:46:57 +0300 Message-ID: <1436194018-18696-2-git-send-email-rogerq@ti.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1436194018-18696-1-git-send-email-rogerq@ti.com> References: <1436194018-18696-1-git-send-email-rogerq@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Users of find_cable_index_by_name() will cause a kernel hang as the while loop counter is never incremented and end condition is never reached. extcon_get_cable_state() and extcon_set_cable_state() are broken because they use cable index instead of cable id. This causes the first cable state (cable.0) to be always invalid in sysfs or extcon_get_cable_state() users. Introduce a new function find_cable_id_by_name() that fixes both of the above issues. Fixes: commit 73b6ecdb93e8 ("extcon: Redefine the unique id of supported external connectors without 'enum extcon' type") Cc: Greg Kroah-Hartman Signed-off-by: Roger Quadros --- drivers/extcon/extcon.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 76157ab..868c6e2 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -124,15 +124,12 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id return -EINVAL; } -static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) +static int find_cable_id_by_name(struct extcon_dev *edev, const char *name) { - unsigned int id = EXTCON_NONE; + unsigned int id = -EINVAL; int i = 0; - if (edev->max_supported == 0) - return -EINVAL; - - /* Find the the number of extcon cable */ + /* Find the id of extcon cable */ while (extcon_name[i]) { if (!strncmp(extcon_name[i], name, CABLE_NAME_MAX)) { id = i; @@ -140,6 +137,19 @@ static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) } } + return id; +}; + +static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) +{ + unsigned int id = EXTCON_NONE; + + if (edev->max_supported == 0) + return -EINVAL; + + /* Find the the number of extcon cable */ + id = find_cable_id_by_name(edev, name); + if (id == EXTCON_NONE) return -EINVAL; @@ -228,9 +238,11 @@ static ssize_t cable_state_show(struct device *dev, struct extcon_cable *cable = container_of(attr, struct extcon_cable, attr_state); + int i = cable->cable_index; + return sprintf(buf, "%d\n", extcon_get_cable_state_(cable->edev, - cable->cable_index)); + cable->edev->supported_cable[i])); } /** @@ -341,6 +353,9 @@ int extcon_get_cable_state_(struct extcon_dev *edev, const unsigned int id) { int index; + if (id == EXTCON_NONE) + return -EINVAL; + index = find_cable_index_by_id(edev, id); if (index < 0) return index; @@ -361,7 +376,7 @@ EXPORT_SYMBOL_GPL(extcon_get_cable_state_); */ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) { - return extcon_get_cable_state_(edev, find_cable_index_by_name + return extcon_get_cable_state_(edev, find_cable_id_by_name (edev, cable_name)); } EXPORT_SYMBOL_GPL(extcon_get_cable_state); @@ -380,6 +395,9 @@ int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, u32 state; int index; + if (id == EXTCON_NONE) + return -EINVAL; + index = find_cable_index_by_id(edev, id); if (index < 0) return index; @@ -404,7 +422,7 @@ EXPORT_SYMBOL_GPL(extcon_set_cable_state_); int extcon_set_cable_state(struct extcon_dev *edev, const char *cable_name, bool cable_state) { - return extcon_set_cable_state_(edev, find_cable_index_by_name + return extcon_set_cable_state_(edev, find_cable_id_by_name (edev, cable_name), cable_state); } EXPORT_SYMBOL_GPL(extcon_set_cable_state);