From patchwork Fri Feb 13 04:54:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 5822971 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BE7F8BF440 for ; Fri, 13 Feb 2015 04:56:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E603E2022A for ; Fri, 13 Feb 2015 04:56:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F1B612025B for ; Fri, 13 Feb 2015 04:56:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751466AbbBME4G (ORCPT ); Thu, 12 Feb 2015 23:56:06 -0500 Received: from e23smtp04.au.ibm.com ([202.81.31.146]:50186 "EHLO e23smtp04.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751500AbbBME4E (ORCPT ); Thu, 12 Feb 2015 23:56:04 -0500 Received: from /spool/local by e23smtp04.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 13 Feb 2015 14:56:02 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp04.au.ibm.com (202.81.31.210) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 13 Feb 2015 14:56:00 +1000 Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id EDAB33578048 for ; Fri, 13 Feb 2015 15:55:59 +1100 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1D4tpPV37945352 for ; Fri, 13 Feb 2015 15:55:59 +1100 Received: from d23av04.au.ibm.com (localhost [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1D4tPpl027607 for ; Fri, 13 Feb 2015 15:55:26 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1D4tP16027102; Fri, 13 Feb 2015 15:55:25 +1100 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.253.15]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 92391A037D; Fri, 13 Feb 2015 15:55:02 +1100 (AEDT) Received: from shangw (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 1DEF216A9B8; Fri, 13 Feb 2015 15:55:00 +1100 (AEDT) Received: by shangw (Postfix, from userid 1000) id C85763E0734; Fri, 13 Feb 2015 15:55:00 +1100 (EST) From: Gavin Shan To: linux-pci@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, bhelgaas@google.com, cascardo@linux.vnet.ibm.com, Gavin Shan Subject: [PATCH 2/4] PCI: Introduce list for device reset methods Date: Fri, 13 Feb 2015 15:54:57 +1100 Message-Id: <1423803299-22356-3-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1423803299-22356-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1423803299-22356-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15021304-0013-0000-0000-000000D0039B Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 The patch introduces list to hold the PCI device specific reset methods. With help of the list, we can register PCI device specific reset method dynamically as we do in next one patch. Signed-off-by: Gavin Shan --- drivers/pci/pci.h | 1 + drivers/pci/quirks.c | 75 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e67b22f..82e648a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -310,6 +310,7 @@ struct pci_dev_reset_method { u16 vendor; u16 device; int (*reset)(struct pci_dev *dev, int probe); + struct list_head node; }; #ifdef CONFIG_PCI_QUIRKS diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 512bbbb..37f4c5d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3508,20 +3508,44 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe) #define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156 #define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166 -static const struct pci_dev_reset_method pci_dev_reset_methods[] = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, - reset_intel_82599_sfp_virtfn }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M_VGA, - reset_ivb_igd }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA, - reset_ivb_igd }, - { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, - reset_intel_generic_dev }, - { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, - reset_chelsio_generic_dev }, - { 0 } +static LIST_HEAD(pci_dev_reset_list); +static DEFINE_MUTEX(pci_dev_reset_mutex); +static bool pci_dev_reset_populated = false; +static struct pci_dev_reset_method pci_dev_reset_methods[] = { + { .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82599_SFP_VF, + .reset = reset_intel_82599_sfp_virtfn + }, + { .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_IVB_M_VGA, + .reset = reset_ivb_igd + }, + { .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_IVB_M2_VGA, + .reset =reset_ivb_igd + }, + { .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_ANY_ID, + .reset = reset_intel_generic_dev + }, + { .vendor = PCI_VENDOR_ID_CHELSIO, + .device = PCI_ANY_ID, + .reset = reset_chelsio_generic_dev + } }; +static void pci_dev_populate_reset(void) +{ + struct pci_dev_reset_method *m; + int i; + + for (i = ARRAY_SIZE(pci_dev_reset_methods) - 1; i >= 0; i--) { + m = &pci_dev_reset_methods[i]; + INIT_LIST_HEAD(&m->node); + list_add(&m->node, &pci_dev_reset_list); + } +} + /* * These device-specific reset methods are here rather than in a driver * because when a host assigns a device to a guest VM, the host may need @@ -3529,16 +3553,29 @@ static const struct pci_dev_reset_method pci_dev_reset_methods[] = { */ int pci_dev_specific_reset(struct pci_dev *dev, int probe) { - const struct pci_dev_reset_method *i; + struct pci_dev_reset_method *m; + int ret; - for (i = pci_dev_reset_methods; i->reset; i++) { - if ((i->vendor == dev->vendor || - i->vendor == (u16)PCI_ANY_ID) && - (i->device == dev->device || - i->device == (u16)PCI_ANY_ID)) - return i->reset(dev, probe); + mutex_lock(&pci_dev_reset_mutex); + + if (!pci_dev_reset_populated) { + pci_dev_populate_reset(); + pci_dev_reset_populated = true; } + list_for_each_entry(m, &pci_dev_reset_list, node) { + if ((m->vendor == dev->vendor || + m->vendor == (u16)PCI_ANY_ID) && + (m->device == dev->device || + m->device == (u16)PCI_ANY_ID)) { + ret = m->reset(dev, probe); + mutex_unlock(&pci_dev_reset_mutex); + return ret; + } + } + + mutex_unlock(&pci_dev_reset_mutex); + return -ENOTTY; }