From patchwork Tue May 19 00:00:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rustad, Mark D" X-Patchwork-Id: 473642 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ozlabs.org (Postfix) with ESMTP id 7E078140D4E for ; Tue, 19 May 2015 10:00:50 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 2044490F3B; Tue, 19 May 2015 00:00:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r3-Dj4CAOQwO; Tue, 19 May 2015 00:00:48 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id F2B8690F23; Tue, 19 May 2015 00:00:47 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from fraxinus.osuosl.org (fraxinus.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id 92A351C244B for ; Tue, 19 May 2015 00:00:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 8B26AA28E4 for ; Tue, 19 May 2015 00:00:46 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T8zBUE405XCs for ; Tue, 19 May 2015 00:00:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by fraxinus.osuosl.org (Postfix) with ESMTP id E7A03A256B for ; Tue, 19 May 2015 00:00:45 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 18 May 2015 17:00:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,456,1427785200"; d="scan'208";a="712150442" Received: from mdrustad-wks.jf.intel.com ([134.134.176.89]) by fmsmga001.fm.intel.com with ESMTP; 18 May 2015 17:00:37 -0700 From: Mark D Rustad To: bhelgaas@google.com Date: Mon, 18 May 2015 17:00:37 -0700 Message-ID: <20150519000037.56109.68356.stgit@mdrustad-wks.jf.intel.com> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Cc: linux-pci@vger.kernel.org, intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org Subject: [Intel-wired-lan] [PATCH] pci: Use a bus-global mutex to protect VPD operations X-BeenThere: intel-wired-lan@lists.osuosl.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-wired-lan-bounces@lists.osuosl.org Sender: "Intel-wired-lan" Some devices have a problem with concurrent VPD access to different functions of the same physical device, so move the protecting mutex from the pci_vpd structure to the pci_bus structure. There are a number of reports on support sites for a variety of devices from various vendors getting the "vpd r/w failed" message. This is likely to at least fix some of them. Thanks to Shannon Nelson for helping to come up with this approach. Signed-off-by: Mark Rustad Acked-by: Shannon Nelson Acked-by: Jeff Kirsher --- drivers/pci/access.c | 10 ++++------ drivers/pci/probe.c | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..6a1c8d6f95f1 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -281,7 +281,6 @@ PCI_USER_WRITE_CONFIG(dword, u32) struct pci_vpd_pci22 { struct pci_vpd base; - struct mutex lock; u16 flag; bool busy; u8 cap; @@ -340,7 +339,7 @@ static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, if (pos < 0 || pos > vpd->base.len || end > vpd->base.len) return -EINVAL; - if (mutex_lock_killable(&vpd->lock)) + if (mutex_lock_killable(&dev->bus->vpd_mutex)) return -EINTR; ret = pci_vpd_pci22_wait(dev); @@ -376,7 +375,7 @@ static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, } } out: - mutex_unlock(&vpd->lock); + mutex_unlock(&dev->bus->vpd_mutex); return ret ? ret : count; } @@ -392,7 +391,7 @@ static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count if (pos < 0 || (pos & 3) || (count & 3) || end > vpd->base.len) return -EINVAL; - if (mutex_lock_killable(&vpd->lock)) + if (mutex_lock_killable(&dev->bus->vpd_mutex)) return -EINTR; ret = pci_vpd_pci22_wait(dev); @@ -424,7 +423,7 @@ static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count pos += sizeof(u32); } out: - mutex_unlock(&vpd->lock); + mutex_unlock(&dev->bus->vpd_mutex); return ret ? ret : count; } @@ -453,7 +452,6 @@ int pci_vpd_pci22_init(struct pci_dev *dev) vpd->base.len = PCI_VPD_PCI22_SIZE; vpd->base.ops = &pci_vpd_pci22_ops; - mutex_init(&vpd->lock); vpd->cap = cap; vpd->busy = false; dev->vpd = &vpd->base; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6675a7a1b9fc..40c2a5a751d0 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -494,6 +494,7 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) INIT_LIST_HEAD(&b->devices); INIT_LIST_HEAD(&b->slots); INIT_LIST_HEAD(&b->resources); + mutex_init(&b->vpd_mutex); b->max_bus_speed = PCI_SPEED_UNKNOWN; b->cur_bus_speed = PCI_SPEED_UNKNOWN; #ifdef CONFIG_PCI_DOMAINS_GENERIC diff --git a/include/linux/pci.h b/include/linux/pci.h index 353db8dc4c6e..f8a51d172255 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -454,6 +454,7 @@ struct pci_bus { struct msi_controller *msi; /* MSI controller */ void *sysdata; /* hook for sys-specific extension */ struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */ + struct mutex vpd_mutex; /* bus-wide VPD access mutex */ unsigned char number; /* bus number */ unsigned char primary; /* number of primary bridge */