Skip to content

Commit d985e2b

Browse files
committed
Merge branch 'pci/reset'
- Add sysfs 'reset_subordinate' to reset hierarchy below bridge (Keith Busch) - Warn if we reset a running device where driver didn't register pci_error_handlers notification callbacks (Keith Busch) * pci/reset: PCI: Warn if a running device is unaware of reset PCI: Add 'reset_subordinate' to reset hierarchy below bridge
2 parents ce1deca + a3151e6 commit d985e2b

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

Documentation/ABI/testing/sysfs-bus-pci

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ Description:
163163
will be present in sysfs. Writing 1 to this file
164164
will perform reset.
165165

166+
What: /sys/bus/pci/devices/.../reset_subordinate
167+
Date: October 2024
168+
Contact: linux-pci@vger.kernel.org
169+
Description:
170+
This is visible only for bridge devices. If you want to reset
171+
all devices attached through the subordinate bus of a specific
172+
bridge device, writing 1 to this will try to do it. This will
173+
affect all devices attached to the system through this bridge
174+
similiar to writing 1 to their individual "reset" file, so use
175+
with caution.
176+
166177
What: /sys/bus/pci/devices/.../vpd
167178
Date: February 2008
168179
Contact: Ben Hutchings <bwh@kernel.org>

drivers/pci/pci-sysfs.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,31 @@ static ssize_t bus_rescan_store(struct device *dev,
521521
static struct device_attribute dev_attr_bus_rescan = __ATTR(rescan, 0200, NULL,
522522
bus_rescan_store);
523523

524+
static ssize_t reset_subordinate_store(struct device *dev,
525+
struct device_attribute *attr,
526+
const char *buf, size_t count)
527+
{
528+
struct pci_dev *pdev = to_pci_dev(dev);
529+
struct pci_bus *bus = pdev->subordinate;
530+
unsigned long val;
531+
532+
if (!capable(CAP_SYS_ADMIN))
533+
return -EPERM;
534+
535+
if (kstrtoul(buf, 0, &val) < 0)
536+
return -EINVAL;
537+
538+
if (val) {
539+
int ret = __pci_reset_bus(bus);
540+
541+
if (ret)
542+
return ret;
543+
}
544+
545+
return count;
546+
}
547+
static DEVICE_ATTR_WO(reset_subordinate);
548+
524549
#if defined(CONFIG_PM) && defined(CONFIG_ACPI)
525550
static ssize_t d3cold_allowed_store(struct device *dev,
526551
struct device_attribute *attr,
@@ -625,6 +650,7 @@ static struct attribute *pci_dev_attrs[] = {
625650
static struct attribute *pci_bridge_attrs[] = {
626651
&dev_attr_subordinate_bus_number.attr,
627652
&dev_attr_secondary_bus_number.attr,
653+
&dev_attr_reset_subordinate.attr,
628654
NULL,
629655
};
630656

drivers/pci/pci.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5158,6 +5158,8 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
51585158
*/
51595159
if (err_handler && err_handler->reset_prepare)
51605160
err_handler->reset_prepare(dev);
5161+
else if (dev->driver)
5162+
pci_warn(dev, "resetting");
51615163

51625164
/*
51635165
* Wake-up device prior to save. PM registers default to D0 after
@@ -5191,6 +5193,8 @@ static void pci_dev_restore(struct pci_dev *dev)
51915193
*/
51925194
if (err_handler && err_handler->reset_done)
51935195
err_handler->reset_done(dev);
5196+
else if (dev->driver)
5197+
pci_warn(dev, "reset done");
51945198
}
51955199

51965200
/* dev->reset_methods[] is a 0-terminated list of indices into this array */
@@ -5880,7 +5884,7 @@ EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
58805884
*
58815885
* Same as above except return -EAGAIN if the bus cannot be locked
58825886
*/
5883-
static int __pci_reset_bus(struct pci_bus *bus)
5887+
int __pci_reset_bus(struct pci_bus *bus)
58845888
{
58855889
int rc;
58865890

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ bool pci_reset_supported(struct pci_dev *dev);
104104
void pci_init_reset_methods(struct pci_dev *dev);
105105
int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
106106
int pci_bus_error_reset(struct pci_dev *dev);
107+
int __pci_reset_bus(struct pci_bus *bus);
107108

108109
struct pci_cap_saved_data {
109110
u16 cap_nr;

0 commit comments

Comments
 (0)