LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Amey Narkhede <ameynarkhede03@gmail.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: alex.williamson@redhat.com,
Raphael Norwitz <raphael.norwitz@nutanix.com>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kw@linux.com, Shanker Donthineni <sdonthineni@nvidia.com>,
Sinan Kaya <okaya@kernel.org>, Len Brown <lenb@kernel.org>,
"Rafael J . Wysocki" <rjw@rjwysocki.net>,
Amey Narkhede <ameynarkhede03@gmail.com>
Subject: [PATCH v10 2/8] PCI: Add new array for keeping track of ordering of reset methods
Date: Fri, 9 Jul 2021 18:08:07 +0530 [thread overview]
Message-ID: <20210709123813.8700-3-ameynarkhede03@gmail.com> (raw)
In-Reply-To: <20210709123813.8700-1-ameynarkhede03@gmail.com>
Introduce a new array reset_methods in struct pci_dev to keep track of
reset mechanisms supported by the device and their ordering.
Also refactor probing and reset functions to take advantage of calling
convention of reset functions.
Co-developed-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Amey Narkhede <ameynarkhede03@gmail.com>
---
drivers/pci/pci.c | 92 ++++++++++++++++++++++++++-------------------
drivers/pci/pci.h | 9 ++++-
drivers/pci/probe.c | 5 +--
include/linux/pci.h | 7 ++++
4 files changed, 70 insertions(+), 43 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fefa6d7b3..42440cb10 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -72,6 +72,14 @@ static void pci_dev_d3_sleep(struct pci_dev *dev)
msleep(delay);
}
+int pci_reset_supported(struct pci_dev *dev)
+{
+ u8 null_reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
+
+ return memcmp(null_reset_methods,
+ dev->reset_methods, sizeof(null_reset_methods));
+}
+
#ifdef CONFIG_PCI_DOMAINS
int pci_domains_supported = 1;
#endif
@@ -5104,6 +5112,15 @@ static void pci_dev_restore(struct pci_dev *dev)
err_handler->reset_done(dev);
}
+const struct pci_reset_fn_method pci_reset_fn_methods[] = {
+ { },
+ { &pci_dev_specific_reset, .name = "device_specific" },
+ { &pcie_reset_flr, .name = "flr" },
+ { &pci_af_flr, .name = "af_flr" },
+ { &pci_pm_reset, .name = "pm" },
+ { &pci_reset_bus_function, .name = "bus" },
+};
+
/**
* __pci_reset_function_locked - reset a PCI device function while holding
* the @dev mutex lock.
@@ -5126,65 +5143,62 @@ static void pci_dev_restore(struct pci_dev *dev)
*/
int __pci_reset_function_locked(struct pci_dev *dev)
{
- int rc;
+ int i, m, rc = -ENOTTY;
might_sleep();
/*
- * A reset method returns -ENOTTY if it doesn't support this device
- * and we should try the next method.
+ * A reset method returns -ENOTTY if it doesn't support this device and
+ * we should try the next method.
*
- * If it returns 0 (success), we're finished. If it returns any
- * other error, we're also finished: this indicates that further
- * reset mechanisms might be broken on the device.
+ * If it returns 0 (success), we're finished. If it returns any other
+ * error, we're also finished: this indicates that further reset
+ * mechanisms might be broken on the device.
*/
- rc = pci_dev_specific_reset(dev, 0);
- if (rc != -ENOTTY)
- return rc;
- rc = pcie_reset_flr(dev, 0);
- if (rc != -ENOTTY)
- return rc;
- rc = pci_af_flr(dev, 0);
- if (rc != -ENOTTY)
- return rc;
- rc = pci_pm_reset(dev, 0);
- if (rc != -ENOTTY)
- return rc;
- return pci_reset_bus_function(dev, 0);
+ for (i = 0; i < PCI_NUM_RESET_METHODS && (m = dev->reset_methods[i]); i++) {
+ rc = pci_reset_fn_methods[m].reset_fn(dev, 0);
+ if (!rc)
+ return 0;
+ if (rc != -ENOTTY)
+ return rc;
+ }
+
+ return -ENOTTY;
}
EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
/**
- * pci_probe_reset_function - check whether the device can be safely reset
- * @dev: PCI device to reset
+ * pci_init_reset_methods - check whether device can be safely reset
+ * and store supported reset mechanisms.
+ * @dev: PCI device to check for reset mechanisms
*
* Some devices allow an individual function to be reset without affecting
* other functions in the same device. The PCI device must be responsive
- * to PCI config space in order to use this function.
+ * to reads and writes to its PCI config space in order to use this function.
*
- * Returns 0 if the device function can be reset or negative if the
- * device doesn't support resetting a single function.
+ * Stores reset mechanisms supported by device in reset_methods byte array
+ * which is a member of struct pci_dev.
*/
-int pci_probe_reset_function(struct pci_dev *dev)
+void pci_init_reset_methods(struct pci_dev *dev)
{
- int rc;
+ int i, n, rc;
+ u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
+
+ n = 0;
+
+ BUILD_BUG_ON(ARRAY_SIZE(pci_reset_fn_methods) != PCI_NUM_RESET_METHODS);
might_sleep();
- rc = pci_dev_specific_reset(dev, 1);
- if (rc != -ENOTTY)
- return rc;
- rc = pcie_reset_flr(dev, 1);
- if (rc != -ENOTTY)
- return rc;
- rc = pci_af_flr(dev, 1);
- if (rc != -ENOTTY)
- return rc;
- rc = pci_pm_reset(dev, 1);
- if (rc != -ENOTTY)
- return rc;
+ for (i = 1; i < PCI_NUM_RESET_METHODS; i++) {
+ rc = pci_reset_fn_methods[i].reset_fn(dev, 1);
+ if (!rc)
+ reset_methods[n++] = i;
+ else if (rc != -ENOTTY)
+ break;
+ }
- return pci_reset_bus_function(dev, 1);
+ memcpy(dev->reset_methods, reset_methods, sizeof(reset_methods));
}
/**
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 37c913bbc..db1ad94e7 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -33,7 +33,8 @@ enum pci_mmap_api {
int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai,
enum pci_mmap_api mmap_api);
-int pci_probe_reset_function(struct pci_dev *dev);
+int pci_reset_supported(struct pci_dev *dev);
+void pci_init_reset_methods(struct pci_dev *dev);
int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
int pci_bus_error_reset(struct pci_dev *dev);
@@ -606,6 +607,12 @@ struct pci_dev_reset_methods {
int (*reset)(struct pci_dev *dev, int probe);
};
+struct pci_reset_fn_method {
+ int (*reset_fn)(struct pci_dev *pdev, int probe);
+ char *name;
+};
+
+extern const struct pci_reset_fn_method pci_reset_fn_methods[];
#ifdef CONFIG_PCI_QUIRKS
int pci_dev_specific_reset(struct pci_dev *dev, int probe);
#else
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 072a3d4dc..bc4af914a 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2406,9 +2406,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_rcec_init(dev); /* Root Complex Event Collector */
pcie_report_downtraining(dev);
-
- if (pci_probe_reset_function(dev) == 0)
- dev->reset_fn = 1;
+ pci_init_reset_methods(dev);
+ dev->reset_fn = pci_reset_supported(dev);
}
/*
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d432428fd..9f3e85f33 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -49,6 +49,9 @@
PCI_STATUS_SIG_TARGET_ABORT | \
PCI_STATUS_PARITY)
+/* Number of reset methods used in pci_reset_fn_methods array in pci.c */
+#define PCI_NUM_RESET_METHODS 6
+
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
@@ -506,6 +509,10 @@ struct pci_dev {
char *driver_override; /* Driver name to force a match */
unsigned long priv_flags; /* Private flags for the PCI driver */
+ /*
+ * See pci_reset_fn_methods array in pci.c for ordering.
+ */
+ u8 reset_methods[PCI_NUM_RESET_METHODS]; /* Reset methods ordered by priority */
};
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
--
2.32.0
next prev parent reply other threads:[~2021-07-09 12:38 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-09 12:38 [PATCH v10 0/8] Expose and manage PCI device reset Amey Narkhede
2021-07-09 12:38 ` [PATCH v10 1/8] PCI: Add pcie_reset_flr to follow calling convention of other reset methods Amey Narkhede
2021-07-12 22:07 ` Alex Williamson
2021-07-27 22:12 ` Bjorn Helgaas
2021-07-28 18:54 ` Shanker R Donthineni
2021-07-28 20:23 ` Bjorn Helgaas
2021-07-28 21:58 ` Shanker R Donthineni
2021-07-28 22:04 ` Shanker R Donthineni
2021-07-28 22:16 ` Bjorn Helgaas
2021-07-09 12:38 ` Amey Narkhede [this message]
2021-07-27 22:59 ` [PATCH v10 2/8] PCI: Add new array for keeping track of ordering of " Bjorn Helgaas
2021-07-28 17:45 ` Amey Narkhede
2021-07-28 17:59 ` Bjorn Helgaas
2021-07-28 18:17 ` Shanker R Donthineni
2021-07-28 18:08 ` Shanker R Donthineni
2021-07-28 18:31 ` Shanker R Donthineni
2021-07-28 20:25 ` Bjorn Helgaas
2021-07-28 22:01 ` Shanker R Donthineni
2021-07-09 12:38 ` [PATCH v10 3/8] PCI: Remove reset_fn field from pci_dev Amey Narkhede
2021-07-09 12:38 ` [PATCH v10 4/8] PCI/sysfs: Allow userspace to query and set device reset mechanism Amey Narkhede
2021-07-27 23:28 ` Bjorn Helgaas
2021-07-28 1:27 ` Krzysztof Wilczyński
2021-07-28 15:36 ` Bjorn Helgaas
2021-07-28 17:59 ` Amey Narkhede
2021-07-28 18:13 ` Bjorn Helgaas
2021-07-28 18:58 ` Amey Narkhede
2021-07-28 20:18 ` Bjorn Helgaas
2021-07-31 19:15 ` Amey Narkhede
2021-07-28 17:09 ` Bjorn Helgaas
2021-07-09 12:38 ` [PATCH v10 5/8] PCI: Define a function to set ACPI_COMPANION in pci_dev Amey Narkhede
2021-07-12 22:29 ` Alex Williamson
2021-07-09 12:38 ` [PATCH v10 6/8] PCI: Setup ACPI fwnode early and at the same time with OF Amey Narkhede
2021-07-12 23:09 ` Alex Williamson
2021-07-27 23:30 ` Bjorn Helgaas
2021-07-27 23:50 ` Shanker R Donthineni
2021-07-09 12:38 ` [PATCH v10 7/8] PCI: Add support for ACPI _RST reset method Amey Narkhede
2021-07-12 23:09 ` Alex Williamson
2021-07-13 0:51 ` Shanker R Donthineni
2021-07-14 22:56 ` Alex Williamson
2021-07-09 12:38 ` [PATCH v10 8/8] PCI: Change the type of probe argument in reset functions Amey Narkhede
2021-07-12 22:24 ` Alex Williamson
2021-07-27 22:22 ` Bjorn Helgaas
2021-07-28 17:35 ` Amey Narkhede
2021-07-28 17:55 ` Bjorn Helgaas
2021-07-09 12:46 ` [PATCH v10 0/8] Expose and manage PCI device reset Amey Narkhede
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210709123813.8700-3-ameynarkhede03@gmail.com \
--to=ameynarkhede03@gmail.com \
--cc=alex.williamson@redhat.com \
--cc=bhelgaas@google.com \
--cc=kw@linux.com \
--cc=lenb@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=okaya@kernel.org \
--cc=raphael.norwitz@nutanix.com \
--cc=rjw@rjwysocki.net \
--cc=sdonthineni@nvidia.com \
--subject='Re: [PATCH v10 2/8] PCI: Add new array for keeping track of ordering of reset methods' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).