mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
Merge branch 'pci/sysfs'
- Convert sysfs "config", "rom", "reset", "label", "index", "acpi_index" to static attributes to fix races in device enumeration (Krzysztof Wilczyński) - Convert sysfs "vpd" to static attribute (Heiner Kallweit, Krzysztof Wilczyński) - Use sysfs_emit() in "show" functions (Krzysztof Wilczyński) * pci/sysfs: PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions PCI/sysfs: Rearrange smbios_attr_group and acpi_attr_group PCI/sysfs: Tidy SMBIOS & ACPI label attributes PCI/sysfs: Convert "index", "acpi_index", "label" to static attributes PCI/sysfs: Define SMBIOS label attributes with DEVICE_ATTR*() PCI/sysfs: Define ACPI label attributes with DEVICE_ATTR*() PCI/sysfs: Rename device_has_dsm() to device_has_acpi_name() PCI/sysfs: Convert "vpd" to static attribute PCI/sysfs: Rename "vpd" attribute accessors PCI/sysfs: Convert "reset" to static attribute PCI/sysfs: Convert "rom" to static attribute PCI/sysfs: Convert "config" to static attribute
This commit is contained in:
commit
bac66f8f97
@ -33,6 +33,21 @@
|
||||
#include <linux/pci-acpi.h>
|
||||
#include "pci.h"
|
||||
|
||||
static bool device_has_acpi_name(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
return acpi_check_dsm(handle, &pci_acpi_dsm_guid, 0x2,
|
||||
1 << DSM_PCI_DEVICE_NAME);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
enum smbios_attr_enum {
|
||||
SMBIOS_ATTR_NONE = 0,
|
||||
@ -45,13 +60,9 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
|
||||
{
|
||||
const struct dmi_device *dmi;
|
||||
struct dmi_dev_onboard *donboard;
|
||||
int domain_nr;
|
||||
int bus;
|
||||
int devfn;
|
||||
|
||||
domain_nr = pci_domain_nr(pdev->bus);
|
||||
bus = pdev->bus->number;
|
||||
devfn = pdev->devfn;
|
||||
int domain_nr = pci_domain_nr(pdev->bus);
|
||||
int bus = pdev->bus->number;
|
||||
int devfn = pdev->devfn;
|
||||
|
||||
dmi = NULL;
|
||||
while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD,
|
||||
@ -62,12 +73,10 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
|
||||
donboard->devfn == devfn) {
|
||||
if (buf) {
|
||||
if (attribute == SMBIOS_ATTR_INSTANCE_SHOW)
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"%d\n",
|
||||
return sysfs_emit(buf, "%d\n",
|
||||
donboard->instance);
|
||||
else if (attribute == SMBIOS_ATTR_LABEL_SHOW)
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"%s\n",
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
dmi->name);
|
||||
}
|
||||
return strlen(dmi->name);
|
||||
@ -76,78 +85,52 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static umode_t smbios_instance_string_exist(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
struct device *dev;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
dev = kobj_to_dev(kobj);
|
||||
pdev = to_pci_dev(dev);
|
||||
|
||||
return find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE) ?
|
||||
S_IRUGO : 0;
|
||||
}
|
||||
|
||||
static ssize_t smbioslabel_show(struct device *dev,
|
||||
static ssize_t smbios_label_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
pdev = to_pci_dev(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return find_smbios_instance_string(pdev, buf,
|
||||
SMBIOS_ATTR_LABEL_SHOW);
|
||||
}
|
||||
static struct device_attribute dev_attr_smbios_label = __ATTR(label, 0444,
|
||||
smbios_label_show, NULL);
|
||||
|
||||
static ssize_t smbiosinstance_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t index_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
pdev = to_pci_dev(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return find_smbios_instance_string(pdev, buf,
|
||||
SMBIOS_ATTR_INSTANCE_SHOW);
|
||||
}
|
||||
static DEVICE_ATTR_RO(index);
|
||||
|
||||
static struct device_attribute smbios_attr_label = {
|
||||
.attr = {.name = "label", .mode = 0444},
|
||||
.show = smbioslabel_show,
|
||||
};
|
||||
|
||||
static struct device_attribute smbios_attr_instance = {
|
||||
.attr = {.name = "index", .mode = 0444},
|
||||
.show = smbiosinstance_show,
|
||||
};
|
||||
|
||||
static struct attribute *smbios_attributes[] = {
|
||||
&smbios_attr_label.attr,
|
||||
&smbios_attr_instance.attr,
|
||||
static struct attribute *smbios_attrs[] = {
|
||||
&dev_attr_smbios_label.attr,
|
||||
&dev_attr_index.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group smbios_attr_group = {
|
||||
.attrs = smbios_attributes,
|
||||
.is_visible = smbios_instance_string_exist,
|
||||
static umode_t smbios_attr_is_visible(struct kobject *kobj, struct attribute *a,
|
||||
int n)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
if (device_has_acpi_name(dev))
|
||||
return 0;
|
||||
|
||||
if (!find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE))
|
||||
return 0;
|
||||
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
const struct attribute_group pci_dev_smbios_attr_group = {
|
||||
.attrs = smbios_attrs,
|
||||
.is_visible = smbios_attr_is_visible,
|
||||
};
|
||||
|
||||
static int pci_create_smbiosname_file(struct pci_dev *pdev)
|
||||
{
|
||||
return sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group);
|
||||
}
|
||||
|
||||
static void pci_remove_smbiosname_file(struct pci_dev *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &smbios_attr_group);
|
||||
}
|
||||
#else
|
||||
static inline int pci_create_smbiosname_file(struct pci_dev *pdev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void pci_remove_smbiosname_file(struct pci_dev *pdev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
@ -169,11 +152,10 @@ static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
|
||||
static int dsm_get_label(struct device *dev, char *buf,
|
||||
enum acpi_attr_enum attr)
|
||||
{
|
||||
acpi_handle handle;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
union acpi_object *obj, *tmp;
|
||||
int len = -1;
|
||||
|
||||
handle = ACPI_HANDLE(dev);
|
||||
if (!handle)
|
||||
return -1;
|
||||
|
||||
@ -209,103 +191,39 @@ static int dsm_get_label(struct device *dev, char *buf,
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool device_has_dsm(struct device *dev)
|
||||
{
|
||||
acpi_handle handle;
|
||||
|
||||
handle = ACPI_HANDLE(dev);
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
return !!acpi_check_dsm(handle, &pci_acpi_dsm_guid, 0x2,
|
||||
1 << DSM_PCI_DEVICE_NAME);
|
||||
}
|
||||
|
||||
static umode_t acpi_index_string_exist(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = kobj_to_dev(kobj);
|
||||
|
||||
if (device_has_dsm(dev))
|
||||
return S_IRUGO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t acpilabel_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t label_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
|
||||
}
|
||||
static DEVICE_ATTR_RO(label);
|
||||
|
||||
static ssize_t acpiindex_show(struct device *dev,
|
||||
static ssize_t acpi_index_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
|
||||
}
|
||||
static DEVICE_ATTR_RO(acpi_index);
|
||||
|
||||
static struct device_attribute acpi_attr_label = {
|
||||
.attr = {.name = "label", .mode = 0444},
|
||||
.show = acpilabel_show,
|
||||
};
|
||||
|
||||
static struct device_attribute acpi_attr_index = {
|
||||
.attr = {.name = "acpi_index", .mode = 0444},
|
||||
.show = acpiindex_show,
|
||||
};
|
||||
|
||||
static struct attribute *acpi_attributes[] = {
|
||||
&acpi_attr_label.attr,
|
||||
&acpi_attr_index.attr,
|
||||
static struct attribute *acpi_attrs[] = {
|
||||
&dev_attr_label.attr,
|
||||
&dev_attr_acpi_index.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group acpi_attr_group = {
|
||||
.attrs = acpi_attributes,
|
||||
.is_visible = acpi_index_string_exist,
|
||||
};
|
||||
|
||||
static int pci_create_acpi_index_label_files(struct pci_dev *pdev)
|
||||
static umode_t acpi_attr_is_visible(struct kobject *kobj, struct attribute *a,
|
||||
int n)
|
||||
{
|
||||
return sysfs_create_group(&pdev->dev.kobj, &acpi_attr_group);
|
||||
}
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
|
||||
static int pci_remove_acpi_index_label_files(struct pci_dev *pdev)
|
||||
{
|
||||
sysfs_remove_group(&pdev->dev.kobj, &acpi_attr_group);
|
||||
if (!device_has_acpi_name(dev))
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int pci_create_acpi_index_label_files(struct pci_dev *pdev)
|
||||
{
|
||||
return -1;
|
||||
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
static inline int pci_remove_acpi_index_label_files(struct pci_dev *pdev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline bool device_has_dsm(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const struct attribute_group pci_dev_acpi_attr_group = {
|
||||
.attrs = acpi_attrs,
|
||||
.is_visible = acpi_attr_is_visible,
|
||||
};
|
||||
#endif
|
||||
|
||||
void pci_create_firmware_label_files(struct pci_dev *pdev)
|
||||
{
|
||||
if (device_has_dsm(&pdev->dev))
|
||||
pci_create_acpi_index_label_files(pdev);
|
||||
else
|
||||
pci_create_smbiosname_file(pdev);
|
||||
}
|
||||
|
||||
void pci_remove_firmware_label_files(struct pci_dev *pdev)
|
||||
{
|
||||
if (device_has_dsm(&pdev->dev))
|
||||
pci_remove_acpi_index_label_files(pdev);
|
||||
else
|
||||
pci_remove_smbiosname_file(pdev);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
|
||||
struct pci_dev *pdev; \
|
||||
\
|
||||
pdev = to_pci_dev(dev); \
|
||||
return sprintf(buf, format_string, pdev->field); \
|
||||
return sysfs_emit(buf, format_string, pdev->field); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(field)
|
||||
|
||||
@ -56,7 +56,7 @@ static ssize_t broken_parity_status_show(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
return sprintf(buf, "%u\n", pdev->broken_parity_status);
|
||||
return sysfs_emit(buf, "%u\n", pdev->broken_parity_status);
|
||||
}
|
||||
|
||||
static ssize_t broken_parity_status_store(struct device *dev,
|
||||
@ -129,7 +129,7 @@ static ssize_t power_state_show(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "%s\n", pci_power_name(pdev->current_state));
|
||||
return sysfs_emit(buf, "%s\n", pci_power_name(pdev->current_state));
|
||||
}
|
||||
static DEVICE_ATTR_RO(power_state);
|
||||
|
||||
@ -138,10 +138,10 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
char *str = buf;
|
||||
int i;
|
||||
int max;
|
||||
resource_size_t start, end;
|
||||
size_t len = 0;
|
||||
|
||||
if (pci_dev->subordinate)
|
||||
max = DEVICE_COUNT_RESOURCE;
|
||||
@ -151,12 +151,12 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
|
||||
for (i = 0; i < max; i++) {
|
||||
struct resource *res = &pci_dev->resource[i];
|
||||
pci_resource_to_user(pci_dev, i, res, &start, &end);
|
||||
str += sprintf(str, "0x%016llx 0x%016llx 0x%016llx\n",
|
||||
len += sysfs_emit_at(buf, len, "0x%016llx 0x%016llx 0x%016llx\n",
|
||||
(unsigned long long)start,
|
||||
(unsigned long long)end,
|
||||
(unsigned long long)res->flags);
|
||||
}
|
||||
return (str - buf);
|
||||
return len;
|
||||
}
|
||||
static DEVICE_ATTR_RO(resource);
|
||||
|
||||
@ -165,7 +165,7 @@ static ssize_t max_link_speed_show(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "%s\n",
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
pci_speed_string(pcie_get_speed_cap(pdev)));
|
||||
}
|
||||
static DEVICE_ATTR_RO(max_link_speed);
|
||||
@ -175,7 +175,7 @@ static ssize_t max_link_width_show(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "%u\n", pcie_get_width_cap(pdev));
|
||||
return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev));
|
||||
}
|
||||
static DEVICE_ATTR_RO(max_link_width);
|
||||
|
||||
@ -193,7 +193,7 @@ static ssize_t current_link_speed_show(struct device *dev,
|
||||
|
||||
speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS];
|
||||
|
||||
return sprintf(buf, "%s\n", pci_speed_string(speed));
|
||||
return sysfs_emit(buf, "%s\n", pci_speed_string(speed));
|
||||
}
|
||||
static DEVICE_ATTR_RO(current_link_speed);
|
||||
|
||||
@ -208,7 +208,7 @@ static ssize_t current_link_width_show(struct device *dev,
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%u\n",
|
||||
return sysfs_emit(buf, "%u\n",
|
||||
(linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
|
||||
}
|
||||
static DEVICE_ATTR_RO(current_link_width);
|
||||
@ -225,7 +225,7 @@ static ssize_t secondary_bus_number_show(struct device *dev,
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%u\n", sec_bus);
|
||||
return sysfs_emit(buf, "%u\n", sec_bus);
|
||||
}
|
||||
static DEVICE_ATTR_RO(secondary_bus_number);
|
||||
|
||||
@ -241,7 +241,7 @@ static ssize_t subordinate_bus_number_show(struct device *dev,
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%u\n", sub_bus);
|
||||
return sysfs_emit(buf, "%u\n", sub_bus);
|
||||
}
|
||||
static DEVICE_ATTR_RO(subordinate_bus_number);
|
||||
|
||||
@ -251,7 +251,7 @@ static ssize_t ari_enabled_show(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
|
||||
return sysfs_emit(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
|
||||
}
|
||||
static DEVICE_ATTR_RO(ari_enabled);
|
||||
|
||||
@ -260,7 +260,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n",
|
||||
return sysfs_emit(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n",
|
||||
pci_dev->vendor, pci_dev->device,
|
||||
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
|
||||
(u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
|
||||
@ -302,7 +302,7 @@ static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
|
||||
struct pci_dev *pdev;
|
||||
|
||||
pdev = to_pci_dev(dev);
|
||||
return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt));
|
||||
return sysfs_emit(buf, "%u\n", atomic_read(&pdev->enable_cnt));
|
||||
}
|
||||
static DEVICE_ATTR_RW(enable);
|
||||
|
||||
@ -338,7 +338,7 @@ static ssize_t numa_node_store(struct device *dev,
|
||||
static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev->numa_node);
|
||||
return sysfs_emit(buf, "%d\n", dev->numa_node);
|
||||
}
|
||||
static DEVICE_ATTR_RW(numa_node);
|
||||
#endif
|
||||
@ -348,7 +348,7 @@ static ssize_t dma_mask_bits_show(struct device *dev,
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", fls64(pdev->dma_mask));
|
||||
return sysfs_emit(buf, "%d\n", fls64(pdev->dma_mask));
|
||||
}
|
||||
static DEVICE_ATTR_RO(dma_mask_bits);
|
||||
|
||||
@ -356,7 +356,7 @@ static ssize_t consistent_dma_mask_bits_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", fls64(dev->coherent_dma_mask));
|
||||
return sysfs_emit(buf, "%d\n", fls64(dev->coherent_dma_mask));
|
||||
}
|
||||
static DEVICE_ATTR_RO(consistent_dma_mask_bits);
|
||||
|
||||
@ -366,7 +366,7 @@ static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr,
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct pci_bus *subordinate = pdev->subordinate;
|
||||
|
||||
return sprintf(buf, "%u\n", subordinate ?
|
||||
return sysfs_emit(buf, "%u\n", subordinate ?
|
||||
!(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
|
||||
: !pdev->no_msi);
|
||||
}
|
||||
@ -523,7 +523,7 @@ static ssize_t d3cold_allowed_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
return sprintf(buf, "%u\n", pdev->d3cold_allowed);
|
||||
return sysfs_emit(buf, "%u\n", pdev->d3cold_allowed);
|
||||
}
|
||||
static DEVICE_ATTR_RW(d3cold_allowed);
|
||||
#endif
|
||||
@ -537,7 +537,7 @@ static ssize_t devspec_show(struct device *dev,
|
||||
|
||||
if (np == NULL)
|
||||
return 0;
|
||||
return sprintf(buf, "%pOF", np);
|
||||
return sysfs_emit(buf, "%pOF", np);
|
||||
}
|
||||
static DEVICE_ATTR_RO(devspec);
|
||||
#endif
|
||||
@ -583,7 +583,7 @@ static ssize_t driver_override_show(struct device *dev,
|
||||
ssize_t len;
|
||||
|
||||
device_lock(dev);
|
||||
len = scnprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
|
||||
len = sysfs_emit(buf, "%s\n", pdev->driver_override);
|
||||
device_unlock(dev);
|
||||
return len;
|
||||
}
|
||||
@ -658,9 +658,9 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
|
||||
struct pci_dev *vga_dev = vga_default_device();
|
||||
|
||||
if (vga_dev)
|
||||
return sprintf(buf, "%u\n", (pdev == vga_dev));
|
||||
return sysfs_emit(buf, "%u\n", (pdev == vga_dev));
|
||||
|
||||
return sprintf(buf, "%u\n",
|
||||
return sysfs_emit(buf, "%u\n",
|
||||
!!(pdev->resource[PCI_ROM_RESOURCE].flags &
|
||||
IORESOURCE_ROM_SHADOW));
|
||||
}
|
||||
@ -808,6 +808,29 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
|
||||
|
||||
return count;
|
||||
}
|
||||
static BIN_ATTR(config, 0644, pci_read_config, pci_write_config, 0);
|
||||
|
||||
static struct bin_attribute *pci_dev_config_attrs[] = {
|
||||
&bin_attr_config,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static umode_t pci_dev_config_attr_is_visible(struct kobject *kobj,
|
||||
struct bin_attribute *a, int n)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
|
||||
|
||||
a->size = PCI_CFG_SPACE_SIZE;
|
||||
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
|
||||
a->size = PCI_CFG_SPACE_EXP_SIZE;
|
||||
|
||||
return a->attr.mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group pci_dev_config_attr_group = {
|
||||
.bin_attrs = pci_dev_config_attrs,
|
||||
.is_bin_visible = pci_dev_config_attr_is_visible,
|
||||
};
|
||||
|
||||
#ifdef HAVE_PCI_LEGACY
|
||||
/**
|
||||
@ -1283,25 +1306,32 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,
|
||||
|
||||
return count;
|
||||
}
|
||||
static BIN_ATTR(rom, 0600, pci_read_rom, pci_write_rom, 0);
|
||||
|
||||
static const struct bin_attribute pci_config_attr = {
|
||||
.attr = {
|
||||
.name = "config",
|
||||
.mode = 0644,
|
||||
},
|
||||
.size = PCI_CFG_SPACE_SIZE,
|
||||
.read = pci_read_config,
|
||||
.write = pci_write_config,
|
||||
static struct bin_attribute *pci_dev_rom_attrs[] = {
|
||||
&bin_attr_rom,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct bin_attribute pcie_config_attr = {
|
||||
.attr = {
|
||||
.name = "config",
|
||||
.mode = 0644,
|
||||
},
|
||||
.size = PCI_CFG_SPACE_EXP_SIZE,
|
||||
.read = pci_read_config,
|
||||
.write = pci_write_config,
|
||||
static umode_t pci_dev_rom_attr_is_visible(struct kobject *kobj,
|
||||
struct bin_attribute *a, int n)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
|
||||
size_t rom_size;
|
||||
|
||||
/* If the device has a ROM, try to expose it in sysfs. */
|
||||
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (!rom_size)
|
||||
return 0;
|
||||
|
||||
a->size = rom_size;
|
||||
|
||||
return a->attr.mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group pci_dev_rom_attr_group = {
|
||||
.bin_attrs = pci_dev_rom_attrs,
|
||||
.is_bin_visible = pci_dev_rom_attr_is_visible,
|
||||
};
|
||||
|
||||
static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
|
||||
@ -1325,102 +1355,35 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_WO(reset);
|
||||
|
||||
static DEVICE_ATTR(reset, 0200, NULL, reset_store);
|
||||
static struct attribute *pci_dev_reset_attrs[] = {
|
||||
&dev_attr_reset.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int pci_create_capabilities_sysfs(struct pci_dev *dev)
|
||||
static umode_t pci_dev_reset_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *a, int n)
|
||||
{
|
||||
int retval;
|
||||
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
|
||||
|
||||
pcie_vpd_create_sysfs_dev_files(dev);
|
||||
|
||||
if (dev->reset_fn) {
|
||||
retval = device_create_file(&dev->dev, &dev_attr_reset);
|
||||
if (retval)
|
||||
goto error;
|
||||
}
|
||||
if (!pdev->reset_fn)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
pcie_vpd_remove_sysfs_dev_files(dev);
|
||||
return retval;
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group pci_dev_reset_attr_group = {
|
||||
.attrs = pci_dev_reset_attrs,
|
||||
.is_visible = pci_dev_reset_attr_is_visible,
|
||||
};
|
||||
|
||||
int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
|
||||
{
|
||||
int retval;
|
||||
int rom_size;
|
||||
struct bin_attribute *attr;
|
||||
|
||||
if (!sysfs_initialized)
|
||||
return -EACCES;
|
||||
|
||||
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
|
||||
else
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
|
||||
if (retval)
|
||||
goto err;
|
||||
|
||||
retval = pci_create_resource_files(pdev);
|
||||
if (retval)
|
||||
goto err_config_file;
|
||||
|
||||
/* If the device has a ROM, try to expose it in sysfs. */
|
||||
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (rom_size) {
|
||||
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
|
||||
if (!attr) {
|
||||
retval = -ENOMEM;
|
||||
goto err_resource_files;
|
||||
}
|
||||
sysfs_bin_attr_init(attr);
|
||||
attr->size = rom_size;
|
||||
attr->attr.name = "rom";
|
||||
attr->attr.mode = 0600;
|
||||
attr->read = pci_read_rom;
|
||||
attr->write = pci_write_rom;
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
|
||||
if (retval) {
|
||||
kfree(attr);
|
||||
goto err_resource_files;
|
||||
}
|
||||
pdev->rom_attr = attr;
|
||||
}
|
||||
|
||||
/* add sysfs entries for various capabilities */
|
||||
retval = pci_create_capabilities_sysfs(pdev);
|
||||
if (retval)
|
||||
goto err_rom_file;
|
||||
|
||||
pci_create_firmware_label_files(pdev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_rom_file:
|
||||
if (pdev->rom_attr) {
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||
kfree(pdev->rom_attr);
|
||||
pdev->rom_attr = NULL;
|
||||
}
|
||||
err_resource_files:
|
||||
pci_remove_resource_files(pdev);
|
||||
err_config_file:
|
||||
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
|
||||
else
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
|
||||
err:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
|
||||
{
|
||||
pcie_vpd_remove_sysfs_dev_files(dev);
|
||||
if (dev->reset_fn) {
|
||||
device_remove_file(&dev->dev, &dev_attr_reset);
|
||||
dev->reset_fn = 0;
|
||||
}
|
||||
return pci_create_resource_files(pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1434,22 +1397,7 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
|
||||
if (!sysfs_initialized)
|
||||
return;
|
||||
|
||||
pci_remove_capabilities_sysfs(pdev);
|
||||
|
||||
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
|
||||
else
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
|
||||
|
||||
pci_remove_resource_files(pdev);
|
||||
|
||||
if (pdev->rom_attr) {
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||
kfree(pdev->rom_attr);
|
||||
pdev->rom_attr = NULL;
|
||||
}
|
||||
|
||||
pci_remove_firmware_label_files(pdev);
|
||||
}
|
||||
|
||||
static int __init pci_sysfs_init(void)
|
||||
@ -1540,6 +1488,16 @@ static const struct attribute_group pci_dev_group = {
|
||||
|
||||
const struct attribute_group *pci_dev_groups[] = {
|
||||
&pci_dev_group,
|
||||
&pci_dev_config_attr_group,
|
||||
&pci_dev_rom_attr_group,
|
||||
&pci_dev_reset_attr_group,
|
||||
&pci_dev_vpd_attr_group,
|
||||
#ifdef CONFIG_DMI
|
||||
&pci_dev_smbios_attr_group,
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI
|
||||
&pci_dev_acpi_attr_group,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -21,16 +21,10 @@ bool pcie_cap_has_rtctl(const struct pci_dev *dev);
|
||||
|
||||
int pci_create_sysfs_dev_files(struct pci_dev *pdev);
|
||||
void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
|
||||
#if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI)
|
||||
static inline void pci_create_firmware_label_files(struct pci_dev *pdev)
|
||||
{ return; }
|
||||
static inline void pci_remove_firmware_label_files(struct pci_dev *pdev)
|
||||
{ return; }
|
||||
#else
|
||||
void pci_create_firmware_label_files(struct pci_dev *pdev);
|
||||
void pci_remove_firmware_label_files(struct pci_dev *pdev);
|
||||
#endif
|
||||
void pci_cleanup_rom(struct pci_dev *dev);
|
||||
#ifdef CONFIG_DMI
|
||||
extern const struct attribute_group pci_dev_smbios_attr_group;
|
||||
#endif
|
||||
|
||||
enum pci_mmap_api {
|
||||
PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
|
||||
@ -143,8 +137,7 @@ static inline bool pcie_downstream_port(const struct pci_dev *dev)
|
||||
|
||||
void pci_vpd_init(struct pci_dev *dev);
|
||||
void pci_vpd_release(struct pci_dev *dev);
|
||||
void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev);
|
||||
void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev);
|
||||
extern const struct attribute_group pci_dev_vpd_attr_group;
|
||||
|
||||
/* PCI Virtual Channel */
|
||||
int pci_save_vc_state(struct pci_dev *dev);
|
||||
@ -696,6 +689,7 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
int pci_acpi_program_hp_params(struct pci_dev *dev);
|
||||
extern const struct attribute_group pci_dev_acpi_attr_group;
|
||||
#else
|
||||
static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ static void pci_stop_dev(struct pci_dev *dev)
|
||||
pci_pme_active(dev, false);
|
||||
|
||||
if (pci_dev_is_added(dev)) {
|
||||
dev->reset_fn = 0;
|
||||
|
||||
device_release_driver(&dev->dev);
|
||||
pci_proc_detach_device(dev);
|
||||
pci_remove_sysfs_dev_files(dev);
|
||||
|
@ -20,7 +20,6 @@ struct pci_vpd_ops {
|
||||
|
||||
struct pci_vpd {
|
||||
const struct pci_vpd_ops *ops;
|
||||
struct bin_attribute *attr; /* Descriptor for sysfs VPD entry */
|
||||
struct mutex lock;
|
||||
unsigned int len;
|
||||
u16 flag;
|
||||
@ -360,58 +359,45 @@ void pci_vpd_release(struct pci_dev *dev)
|
||||
kfree(dev->vpd);
|
||||
}
|
||||
|
||||
static ssize_t read_vpd_attr(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
static ssize_t vpd_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf, loff_t off,
|
||||
size_t count)
|
||||
{
|
||||
struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
|
||||
|
||||
return pci_read_vpd(dev, off, count, buf);
|
||||
}
|
||||
|
||||
static ssize_t write_vpd_attr(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
static ssize_t vpd_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf, loff_t off,
|
||||
size_t count)
|
||||
{
|
||||
struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
|
||||
|
||||
return pci_write_vpd(dev, off, count, buf);
|
||||
}
|
||||
static BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0);
|
||||
|
||||
void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev)
|
||||
static struct bin_attribute *vpd_attrs[] = {
|
||||
&bin_attr_vpd,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static umode_t vpd_attr_is_visible(struct kobject *kobj,
|
||||
struct bin_attribute *a, int n)
|
||||
{
|
||||
int retval;
|
||||
struct bin_attribute *attr;
|
||||
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
|
||||
|
||||
if (!dev->vpd)
|
||||
return;
|
||||
if (!pdev->vpd)
|
||||
return 0;
|
||||
|
||||
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
|
||||
if (!attr)
|
||||
return;
|
||||
|
||||
sysfs_bin_attr_init(attr);
|
||||
attr->size = 0;
|
||||
attr->attr.name = "vpd";
|
||||
attr->attr.mode = S_IRUSR | S_IWUSR;
|
||||
attr->read = read_vpd_attr;
|
||||
attr->write = write_vpd_attr;
|
||||
retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
|
||||
if (retval) {
|
||||
kfree(attr);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->vpd->attr = attr;
|
||||
return a->attr.mode;
|
||||
}
|
||||
|
||||
void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->vpd && dev->vpd->attr) {
|
||||
sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
|
||||
kfree(dev->vpd->attr);
|
||||
}
|
||||
}
|
||||
const struct attribute_group pci_dev_vpd_attr_group = {
|
||||
.bin_attrs = vpd_attrs,
|
||||
.is_bin_visible = vpd_attr_is_visible,
|
||||
};
|
||||
|
||||
int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt)
|
||||
{
|
||||
|
@ -458,7 +458,6 @@ struct pci_dev {
|
||||
|
||||
u32 saved_config_space[16]; /* Config space saved at suspend time */
|
||||
struct hlist_head saved_cap_space;
|
||||
struct bin_attribute *rom_attr; /* Attribute descriptor for sysfs ROM entry */
|
||||
int rom_attr_enabled; /* Display of ROM attribute enabled? */
|
||||
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
|
||||
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
|
||||
|
Loading…
Reference in New Issue
Block a user