From patchwork Tue Aug 7 16:10:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 175708 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 35C492C00A3 for ; Wed, 8 Aug 2012 02:22:45 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755713Ab2HGQVA (ORCPT ); Tue, 7 Aug 2012 12:21:00 -0400 Received: from mail-gh0-f174.google.com ([209.85.160.174]:58061 "EHLO mail-gh0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755704Ab2HGQU6 (ORCPT ); Tue, 7 Aug 2012 12:20:58 -0400 Received: by mail-gh0-f174.google.com with SMTP id r11so3858495ghr.19 for ; Tue, 07 Aug 2012 09:20:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=zVGdgfSA8v4vdTLRMrEHgvV74jRfHAqX2hgJHY4d/Mo=; b=Lns3mOb/x940AztwSzlQF1rxbthA1K0gxeCZhOQ68wSy4SdTRZAgjyC7VMgpaLBmLG 2VVt/fy2Ph+z8ruansdyBpWlmbR7BW3nxePP/EJGwedb3Gn4NwajGfIr8e98EgK1E7eS Ikk11BwpqNFD7KuQrZKw/c5nD3bq77sM4ry9Xd8iSYgnUu8wjNEusrHGYLcnpcVqfbJu 0ySoxlN7XaGqqUkqpZ1mpPN0qz+HAIbcLCUuuHaAu83VwtYc3H38XTav+p/uhd40uJrH ArrQ4SNCFr7sJrhpG16GXb9jpDeKZ18p3sL5GTulnRIdsWfvirpRiwxXpJHRdnvMvqsp D1Nw== Received: by 10.66.87.227 with SMTP id bb3mr27421892pab.3.1344356457748; Tue, 07 Aug 2012 09:20:57 -0700 (PDT) Received: from localhost.localdomain ([58.250.81.2]) by mx.google.com with ESMTPS id pt2sm11429362pbb.58.2012.08.07.09.20.50 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Aug 2012 09:20:57 -0700 (PDT) From: Jiang Liu To: Bjorn Helgaas , Don Dutile , Yinghai Lu , Greg KH , Kenji Kaneshige Cc: Jiang Liu , Taku Izumi , "Rafael J . Wysocki" , Yijing Wang , Xinwei Hu , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Jiang Liu Subject: [RFC PATCH v1 16/22] PCI/asus-wmi: use PCI bus lock to avoid race conditions Date: Wed, 8 Aug 2012 00:10:56 +0800 Message-Id: <1344355862-2726-17-git-send-email-jiang.liu@huawei.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1344355862-2726-1-git-send-email-jiang.liu@huawei.com> References: <1344355862-2726-1-git-send-email-jiang.liu@huawei.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org This patch uses PCI bus lock mechanism to avoid race conditions when doing PCI device hotplug by asum-wmi driver. Signed-off-by: Jiang Liu --- drivers/platform/x86/asus-wmi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 77aadde..9972bc7 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -533,15 +533,20 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) rfkill_set_sw_state(asus->wlan.rfkill, blocked); if (asus->hotplug_slot) { - bus = pci_find_bus(0, 1); + bus = pci_get_bus(0, 1); if (!bus) { pr_warn("Unable to find PCI bus 1?\n"); goto out_unlock; } + if (pci_bus_lock_states(bus, PCI_BUS_STATE_WORKING)) { + pr_warn("Unable to lock PCI bus 1?\n"); + goto out_put_bus; + } + if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { pr_err("Unable to read PCI config space?\n"); - goto out_unlock; + goto out_unlock_bus; } absent = (l == 0xffffffff); @@ -552,7 +557,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) absent ? "absent" : "present"); pr_warn("skipped wireless hotplug as probably " "inappropriate for this model\n"); - goto out_unlock; + goto out_unlock_bus; } if (!blocked) { @@ -560,7 +565,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) if (dev) { /* Device already present */ pci_dev_put(dev); - goto out_unlock; + goto out_unlock_bus; } dev = pci_scan_single_device(bus, 0); if (dev) { @@ -575,6 +580,11 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) pci_dev_put(dev); } } + +out_unlock_bus: + pci_bus_unlock(bus); +out_put_bus: + pci_bus_put(bus); } out_unlock: @@ -670,7 +680,7 @@ static void asus_hotplug_work(struct work_struct *work) static int asus_setup_pci_hotplug(struct asus_wmi *asus) { int ret = -ENOMEM; - struct pci_bus *bus = pci_find_bus(0, 1); + struct pci_bus *bus = pci_get_bus(0, 1); if (!bus) { pr_err("Unable to find wifi PCI bus\n"); @@ -705,6 +715,8 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) goto error_register; } + pci_bus_put(bus); + return 0; error_register: @@ -715,6 +727,7 @@ error_info: error_slot: destroy_workqueue(asus->hotplug_workqueue); error_workqueue: + pci_bus_put(bus); return ret; }