Skip to content

Commit 60b5cd4

Browse files
committed
Merge branch 'pci/pci-sysfs'
- Move reset related sysfs code from pci.c to pci-sysfs.c where other similar code lives (Ilpo Järvinen) - Simplify reset_method_store() memory management by using __free() instead of explicit kfree() cleanup (Ilpo Järvinen) - Drop unnecessary zero initializer (Ilpo Järvinen) * pci/pci-sysfs: PCI/sysfs: Remove unnecessary zero in initializer PCI/sysfs: Use __free() in reset_method_store() PCI/sysfs: Move reset related sysfs code to correct file
2 parents ccbd884 + 2d54d23 commit 60b5cd4

File tree

3 files changed

+110
-126
lines changed

3 files changed

+110
-126
lines changed

drivers/pci/pci-sysfs.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414

1515
#include <linux/bitfield.h>
16+
#include <linux/cleanup.h>
1617
#include <linux/kernel.h>
1718
#include <linux/sched.h>
1819
#include <linux/pci.h>
@@ -1421,6 +1422,113 @@ static const struct attribute_group pci_dev_reset_attr_group = {
14211422
.is_visible = pci_dev_reset_attr_is_visible,
14221423
};
14231424

1425+
static ssize_t reset_method_show(struct device *dev,
1426+
struct device_attribute *attr, char *buf)
1427+
{
1428+
struct pci_dev *pdev = to_pci_dev(dev);
1429+
ssize_t len = 0;
1430+
int i, m;
1431+
1432+
for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
1433+
m = pdev->reset_methods[i];
1434+
if (!m)
1435+
break;
1436+
1437+
len += sysfs_emit_at(buf, len, "%s%s", len ? " " : "",
1438+
pci_reset_fn_methods[m].name);
1439+
}
1440+
1441+
if (len)
1442+
len += sysfs_emit_at(buf, len, "\n");
1443+
1444+
return len;
1445+
}
1446+
1447+
static int reset_method_lookup(const char *name)
1448+
{
1449+
int m;
1450+
1451+
for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
1452+
if (sysfs_streq(name, pci_reset_fn_methods[m].name))
1453+
return m;
1454+
}
1455+
1456+
return 0; /* not found */
1457+
}
1458+
1459+
static ssize_t reset_method_store(struct device *dev,
1460+
struct device_attribute *attr,
1461+
const char *buf, size_t count)
1462+
{
1463+
struct pci_dev *pdev = to_pci_dev(dev);
1464+
char *tmp_options, *name;
1465+
int m, n;
1466+
u8 reset_methods[PCI_NUM_RESET_METHODS] = {};
1467+
1468+
if (sysfs_streq(buf, "")) {
1469+
pdev->reset_methods[0] = 0;
1470+
pci_warn(pdev, "All device reset methods disabled by user");
1471+
return count;
1472+
}
1473+
1474+
if (sysfs_streq(buf, "default")) {
1475+
pci_init_reset_methods(pdev);
1476+
return count;
1477+
}
1478+
1479+
char *options __free(kfree) = kstrndup(buf, count, GFP_KERNEL);
1480+
if (!options)
1481+
return -ENOMEM;
1482+
1483+
n = 0;
1484+
tmp_options = options;
1485+
while ((name = strsep(&tmp_options, " ")) != NULL) {
1486+
if (sysfs_streq(name, ""))
1487+
continue;
1488+
1489+
name = strim(name);
1490+
1491+
/* Leave previous methods unchanged if input is invalid */
1492+
m = reset_method_lookup(name);
1493+
if (!m) {
1494+
pci_err(pdev, "Invalid reset method '%s'", name);
1495+
return -EINVAL;
1496+
}
1497+
1498+
if (pci_reset_fn_methods[m].reset_fn(pdev, PCI_RESET_PROBE)) {
1499+
pci_err(pdev, "Unsupported reset method '%s'", name);
1500+
return -EINVAL;
1501+
}
1502+
1503+
if (n == PCI_NUM_RESET_METHODS - 1) {
1504+
pci_err(pdev, "Too many reset methods\n");
1505+
return -EINVAL;
1506+
}
1507+
1508+
reset_methods[n++] = m;
1509+
}
1510+
1511+
reset_methods[n] = 0;
1512+
1513+
/* Warn if dev-specific supported but not highest priority */
1514+
if (pci_reset_fn_methods[1].reset_fn(pdev, PCI_RESET_PROBE) == 0 &&
1515+
reset_methods[0] != 1)
1516+
pci_warn(pdev, "Device-specific reset disabled/de-prioritized by user");
1517+
memcpy(pdev->reset_methods, reset_methods, sizeof(pdev->reset_methods));
1518+
return count;
1519+
}
1520+
static DEVICE_ATTR_RW(reset_method);
1521+
1522+
static struct attribute *pci_dev_reset_method_attrs[] = {
1523+
&dev_attr_reset_method.attr,
1524+
NULL,
1525+
};
1526+
1527+
static const struct attribute_group pci_dev_reset_method_attr_group = {
1528+
.attrs = pci_dev_reset_method_attrs,
1529+
.is_visible = pci_dev_reset_attr_is_visible,
1530+
};
1531+
14241532
static ssize_t __resource_resize_show(struct device *dev, int n, char *buf)
14251533
{
14261534
struct pci_dev *pdev = to_pci_dev(dev);

drivers/pci/pci.c

Lines changed: 1 addition & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -5163,7 +5163,7 @@ static void pci_dev_restore(struct pci_dev *dev)
51635163
}
51645164

51655165
/* dev->reset_methods[] is a 0-terminated list of indices into this array */
5166-
static const struct pci_reset_fn_method pci_reset_fn_methods[] = {
5166+
const struct pci_reset_fn_method pci_reset_fn_methods[] = {
51675167
{ },
51685168
{ pci_dev_specific_reset, .name = "device_specific" },
51695169
{ pci_dev_acpi_reset, .name = "acpi" },
@@ -5174,129 +5174,6 @@ static const struct pci_reset_fn_method pci_reset_fn_methods[] = {
51745174
{ cxl_reset_bus_function, .name = "cxl_bus" },
51755175
};
51765176

5177-
static ssize_t reset_method_show(struct device *dev,
5178-
struct device_attribute *attr, char *buf)
5179-
{
5180-
struct pci_dev *pdev = to_pci_dev(dev);
5181-
ssize_t len = 0;
5182-
int i, m;
5183-
5184-
for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
5185-
m = pdev->reset_methods[i];
5186-
if (!m)
5187-
break;
5188-
5189-
len += sysfs_emit_at(buf, len, "%s%s", len ? " " : "",
5190-
pci_reset_fn_methods[m].name);
5191-
}
5192-
5193-
if (len)
5194-
len += sysfs_emit_at(buf, len, "\n");
5195-
5196-
return len;
5197-
}
5198-
5199-
static int reset_method_lookup(const char *name)
5200-
{
5201-
int m;
5202-
5203-
for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
5204-
if (sysfs_streq(name, pci_reset_fn_methods[m].name))
5205-
return m;
5206-
}
5207-
5208-
return 0; /* not found */
5209-
}
5210-
5211-
static ssize_t reset_method_store(struct device *dev,
5212-
struct device_attribute *attr,
5213-
const char *buf, size_t count)
5214-
{
5215-
struct pci_dev *pdev = to_pci_dev(dev);
5216-
char *options, *tmp_options, *name;
5217-
int m, n;
5218-
u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
5219-
5220-
if (sysfs_streq(buf, "")) {
5221-
pdev->reset_methods[0] = 0;
5222-
pci_warn(pdev, "All device reset methods disabled by user");
5223-
return count;
5224-
}
5225-
5226-
if (sysfs_streq(buf, "default")) {
5227-
pci_init_reset_methods(pdev);
5228-
return count;
5229-
}
5230-
5231-
options = kstrndup(buf, count, GFP_KERNEL);
5232-
if (!options)
5233-
return -ENOMEM;
5234-
5235-
n = 0;
5236-
tmp_options = options;
5237-
while ((name = strsep(&tmp_options, " ")) != NULL) {
5238-
if (sysfs_streq(name, ""))
5239-
continue;
5240-
5241-
name = strim(name);
5242-
5243-
m = reset_method_lookup(name);
5244-
if (!m) {
5245-
pci_err(pdev, "Invalid reset method '%s'", name);
5246-
goto error;
5247-
}
5248-
5249-
if (pci_reset_fn_methods[m].reset_fn(pdev, PCI_RESET_PROBE)) {
5250-
pci_err(pdev, "Unsupported reset method '%s'", name);
5251-
goto error;
5252-
}
5253-
5254-
if (n == PCI_NUM_RESET_METHODS - 1) {
5255-
pci_err(pdev, "Too many reset methods\n");
5256-
goto error;
5257-
}
5258-
5259-
reset_methods[n++] = m;
5260-
}
5261-
5262-
reset_methods[n] = 0;
5263-
5264-
/* Warn if dev-specific supported but not highest priority */
5265-
if (pci_reset_fn_methods[1].reset_fn(pdev, PCI_RESET_PROBE) == 0 &&
5266-
reset_methods[0] != 1)
5267-
pci_warn(pdev, "Device-specific reset disabled/de-prioritized by user");
5268-
memcpy(pdev->reset_methods, reset_methods, sizeof(pdev->reset_methods));
5269-
kfree(options);
5270-
return count;
5271-
5272-
error:
5273-
/* Leave previous methods unchanged */
5274-
kfree(options);
5275-
return -EINVAL;
5276-
}
5277-
static DEVICE_ATTR_RW(reset_method);
5278-
5279-
static struct attribute *pci_dev_reset_method_attrs[] = {
5280-
&dev_attr_reset_method.attr,
5281-
NULL,
5282-
};
5283-
5284-
static umode_t pci_dev_reset_method_attr_is_visible(struct kobject *kobj,
5285-
struct attribute *a, int n)
5286-
{
5287-
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
5288-
5289-
if (!pci_reset_supported(pdev))
5290-
return 0;
5291-
5292-
return a->mode;
5293-
}
5294-
5295-
const struct attribute_group pci_dev_reset_method_attr_group = {
5296-
.attrs = pci_dev_reset_method_attrs,
5297-
.is_visible = pci_dev_reset_method_attr_is_visible,
5298-
};
5299-
53005177
/**
53015178
* __pci_reset_function_locked - reset a PCI device function while holding
53025179
* the @dev mutex lock.

drivers/pci/pci.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ struct pci_reset_fn_method {
777777
int (*reset_fn)(struct pci_dev *pdev, bool probe);
778778
char *name;
779779
};
780+
extern const struct pci_reset_fn_method pci_reset_fn_methods[];
780781

781782
#ifdef CONFIG_PCI_QUIRKS
782783
int pci_dev_specific_reset(struct pci_dev *dev, bool probe);
@@ -964,8 +965,6 @@ static inline pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
964965
extern const struct attribute_group aspm_ctrl_attr_group;
965966
#endif
966967

967-
extern const struct attribute_group pci_dev_reset_method_attr_group;
968-
969968
#ifdef CONFIG_X86_INTEL_MID
970969
bool pci_use_mid_pm(void);
971970
int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state);

0 commit comments

Comments
 (0)