Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
diff --git c/arch/alpha/boot/vmlinux w/arch/alpha/boot/vmlinux
new file mode 100755
index 000000000000..aec4fdb57e52
Binary files /dev/null and w/arch/alpha/boot/vmlinux differ
diff --git c/arch/alpha/kernel/pci-sysfs.c w/arch/alpha/kernel/pci-sysfs.c
index 0021580d79ad..35d0632d0897 100644
--- c/arch/alpha/kernel/pci-sysfs.c
+++ w/arch/alpha/kernel/pci-sysfs.c
@@ -14,6 +14,7 @@
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/security.h>
static int hose_mmap_page_range(struct pci_controller *hose,
struct vm_area_struct *vma,
@@ -39,6 +40,9 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num,
unsigned long nr, start, size;
int shift = sparse ? 5 : 0;
+ if (pci_resource_len(pdev, num) == 0)
+ return 0;
+
nr = vma_pages(vma);
start = vma->vm_pgoff;
size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
@@ -66,21 +70,20 @@ static int pci_mmap_resource(struct kobject *kobj,
struct vm_area_struct *vma, int sparse)
{
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
- struct resource *res = attr->private;
+ int barno = (unsigned long)attr->private;
+ struct resource *res = &pdev->resource[barno];
enum pci_mmap_state mmap_type;
struct pci_bus_region bar;
- int i;
+ int ret;
- for (i = 0; i < PCI_STD_NUM_BARS; i++)
- if (res == &pdev->resource[i])
- break;
- if (i >= PCI_STD_NUM_BARS)
- return -ENODEV;
+ ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
+ if (ret)
+ return ret;
if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
return -EINVAL;
- if (!__pci_mmap_fits(pdev, i, vma, sparse))
+ if (!__pci_mmap_fits(pdev, barno, vma, sparse))
return -EINVAL;
pcibios_resource_to_bus(pdev->bus, &bar, res);
@@ -104,34 +107,6 @@ static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj,
return pci_mmap_resource(kobj, attr, vma, 0);
}
-/**
- * pci_remove_resource_files - cleanup resource files
- * @dev: dev to cleanup
- *
- * If we created resource files for @dev, remove them from sysfs and
- * free their resources.
- */
-void pci_remove_resource_files(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
- struct bin_attribute *res_attr;
-
- res_attr = pdev->res_attr[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
-
- res_attr = pdev->res_attr_wc[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
- }
-}
-
static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
{
struct pci_bus_region bar;
@@ -151,102 +126,58 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
return bar.end < sparse_size;
}
-static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
- char *suffix, struct bin_attribute *res_attr,
- unsigned long sparse)
-{
- size_t size = pci_resource_len(pdev, num);
-
- sprintf(name, "resource%d%s", num, suffix);
- res_attr->mmap = sparse ? pci_mmap_resource_sparse :
- pci_mmap_resource_dense;
- res_attr->attr.name = name;
- res_attr->attr.mode = S_IRUSR | S_IWUSR;
- res_attr->size = sparse ? size << 5 : size;
- res_attr->private = &pdev->resource[num];
- return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
-}
-
-static int pci_create_attr(struct pci_dev *pdev, int num)
+umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
+ struct bin_attribute *attr,
+ int bar,
+ enum pci_resource_type type)
{
- /* allocate attribute structure, piggyback attribute name */
- int retval, nlen1, nlen2 = 0, res_count = 1;
- unsigned long sparse_base, dense_base;
- struct bin_attribute *attr;
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
struct pci_controller *hose = pdev->sysdata;
- char *suffix, *attr_name;
+ resource_size_t resource_size = pci_resource_len(pdev, bar);
+ unsigned long flags = pci_resource_flags(pdev, bar);
+ enum pci_resource_type resource_type = PCI_RESOURCE_NORMAL;
+ unsigned long sparse_base, dense_base;
- suffix = ""; /* Assume bwx machine, normal resourceN files. */
- nlen1 = 10;
+ if (!resource_size)
+ return 0;
- if (pdev->resource[num].flags & IORESOURCE_MEM) {
+ if (flags & IORESOURCE_MEM) {
sparse_base = hose->sparse_mem_base;
dense_base = hose->dense_mem_base;
- if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
+ if (sparse_base && !sparse_mem_mmap_fits(pdev, bar)) {
sparse_base = 0;
- suffix = "_dense";
- nlen1 = 16; /* resourceN_dense */
+ resource_type = PCI_RESOURCE_DENSE;
}
- } else {
+ } else if (flags & IORESOURCE_IO) {
sparse_base = hose->sparse_io_base;
dense_base = hose->dense_io_base;
+ } else {
+ return 0;
}
if (sparse_base) {
- suffix = "_sparse";
- nlen1 = 17;
- if (dense_base) {
- nlen2 = 16; /* resourceN_dense */
- res_count = 2;
- }
+ resource_type = PCI_RESOURCE_SPARSE;
+ if (dense_base)
+ resource_type |= PCI_RESOURCE_DENSE;
}
- attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC);
- if (!attr)
- return -ENOMEM;
-
- /* Create bwx, sparse or single dense file */
- attr_name = (char *)(attr + res_count);
- pdev->res_attr[num] = attr;
- retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr,
- sparse_base);
- if (retval || res_count == 1)
- return retval;
-
- /* Create dense file */
- attr_name += nlen1;
- attr++;
- pdev->res_attr_wc[num] = attr;
- return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0);
-}
+ if (!(resource_type & type))
+ return 0;
-/**
- * pci_create_resource_files - create resource files in sysfs for @dev
- * @dev: dev in question
- *
- * Walk the resources in @dev creating files for each resource available.
- */
-int pci_create_resource_files(struct pci_dev *pdev)
-{
- int i;
- int retval;
+ attr->size = resource_size;
+ attr->mmap = pci_mmap_resource_dense;
- /* Expose the PCI resources from this device as files */
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+ if (resource_type & PCI_RESOURCE_SPARSE) {
+ attr->size = resource_size << 5;
+ attr->mmap = pci_mmap_resource_sparse;
+ }
- /* skip empty resources */
- if (!pci_resource_len(pdev, i))
- continue;
+ attr->private = (void *)(unsigned long)bar;
- retval = pci_create_attr(pdev, i);
- if (retval) {
- pci_remove_resource_files(pdev);
- return retval;
- }
- }
- return 0;
+ return attr->attr.mode;
}
+#ifdef HAVE_PCI_LEGACY
/* Legacy I/O bus mapping stuff. */
static int __legacy_mmap_fits(struct pci_controller *hose,
@@ -366,3 +297,4 @@ int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
}
return -EINVAL;
}
+#endif /* HAVE_PCI_LEGACY */
diff --git c/drivers/pci/bus.c w/drivers/pci/bus.c
index 3cef835b375f..523bd6c59b3e 100644
--- c/drivers/pci/bus.c
+++ w/drivers/pci/bus.c
@@ -316,7 +316,6 @@ void pci_bus_add_device(struct pci_dev *dev)
*/
pcibios_bus_add_device(dev);
pci_fixup_device(pci_fixup_final, dev);
- pci_create_sysfs_dev_files(dev);
pci_proc_attach_device(dev);
pci_bridge_d3_update(dev);
diff --git c/drivers/pci/pci-sysfs.c w/drivers/pci/pci-sysfs.c
index 5d63df7c1820..d00ffa1cbf15 100644
--- c/drivers/pci/pci-sysfs.c
+++ w/drivers/pci/pci-sysfs.c
@@ -965,7 +965,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
b->legacy_io->mmap = pci_mmap_legacy_io;
- b->legacy_io->mapping = iomem_get_mapping();
+ b->legacy_io->f_mapping = iomem_get_mapping;
pci_adjust_legacy_attr(b, pci_mmap_io);
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
@@ -978,7 +978,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = 0600;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
- b->legacy_io->mapping = iomem_get_mapping();
+ b->legacy_io->f_mapping = iomem_get_mapping;
pci_adjust_legacy_attr(b, pci_mmap_mem);
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
@@ -1135,113 +1135,168 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
return pci_resource_io(filp, kobj, attr, buf, off, count, true);
}
-/**
- * pci_remove_resource_files - cleanup resource files
- * @pdev: dev to cleanup
- *
- * If we created resource files for @pdev, remove them from sysfs and
- * free their resources.
- */
-static void pci_remove_resource_files(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
- struct bin_attribute *res_attr;
-
- res_attr = pdev->res_attr[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
-
- res_attr = pdev->res_attr_wc[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
- }
-}
-
-static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+static umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
+ struct bin_attribute *attr,
+ int bar, bool write_combine)
{
- /* allocate attribute structure, piggyback attribute name */
- int name_len = write_combine ? 13 : 10;
- struct bin_attribute *res_attr;
- char *res_attr_name;
- int retval;
-
- res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
- if (!res_attr)
- return -ENOMEM;
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ resource_size_t resource_size = pci_resource_len(pdev, bar);
+ unsigned long flags = pci_resource_flags(pdev, bar);
- res_attr_name = (char *)(res_attr + 1);
+ if (!resource_size)
+ return 0;
- sysfs_bin_attr_init(res_attr);
if (write_combine) {
- pdev->res_attr_wc[num] = res_attr;
- sprintf(res_attr_name, "resource%d_wc", num);
- res_attr->mmap = pci_mmap_resource_wc;
+ if (arch_can_pci_mmap_wc() && (flags &
+ (IORESOURCE_MEM | IORESOURCE_PREFETCH)) ==
+ (IORESOURCE_MEM | IORESOURCE_PREFETCH))
+ attr->mmap = pci_mmap_resource_wc;
+ else
+ return 0;
} else {
- pdev->res_attr[num] = res_attr;
- sprintf(res_attr_name, "resource%d", num);
- if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
- res_attr->read = pci_read_resource_io;
- res_attr->write = pci_write_resource_io;
+ if (flags & IORESOURCE_MEM) {
+ attr->mmap = pci_mmap_resource_uc;
+ } else if (flags & IORESOURCE_IO) {
+ attr->read = pci_read_resource_io;
+ attr->write = pci_write_resource_io;
if (arch_can_pci_mmap_io())
- res_attr->mmap = pci_mmap_resource_uc;
+ attr->mmap = pci_mmap_resource_uc;
} else {
- res_attr->mmap = pci_mmap_resource_uc;
+ return 0;
}
}
- if (res_attr->mmap)
- res_attr->mapping = iomem_get_mapping();
- res_attr->attr.name = res_attr_name;
- res_attr->attr.mode = 0600;
- res_attr->size = pci_resource_len(pdev, num);
- res_attr->private = (void *)(unsigned long)num;
- retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
- if (retval)
- kfree(res_attr);
- return retval;
+ attr->size = resource_size;
+ if (attr->mmap)
+ attr->f_mapping = iomem_get_mapping;
+
+ attr->private = (void *)(unsigned long)bar;
+
+ return attr->attr.mode;
}
-/**
- * pci_create_resource_files - create resource files in sysfs for @dev
- * @pdev: dev in question
- *
- * Walk the resources in @pdev creating files for each resource available.
- */
-static int pci_create_resource_files(struct pci_dev *pdev)
-{
- int i;
- int retval;
-
- /* Expose the PCI resources from this device as files */
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-
- /* skip empty resources */
- if (!pci_resource_len(pdev, i))
- continue;
-
- retval = pci_create_attr(pdev, i, 0);
- /* for prefetchable resources, create a WC mappable file */
- if (!retval && arch_can_pci_mmap_wc() &&
- pdev->resource[i].flags & IORESOURCE_PREFETCH)
- retval = pci_create_attr(pdev, i, 1);
- if (retval) {
- pci_remove_resource_files(pdev);
- return retval;
- }
- }
- return 0;
+#define pci_dev_resource_attr(_bar) \
+static struct bin_attribute \
+pci_dev_resource##_bar##_attr = __BIN_ATTR(resource##_bar, \
+ 0600, NULL, NULL, 0); \
+static struct bin_attribute *pci_dev_resource##_bar##_attrs[] = { \
+ &pci_dev_resource##_bar##_attr, \
+ NULL, \
+}; \
+static umode_t \
+pci_dev_resource##_bar##_attr_is_visible(struct kobject *kobj, \
+ struct bin_attribute *a, \
+ int n) \
+{ \
+ return pci_dev_resource_attr_is_visible(kobj, a, _bar, false); \
+}; \
+static const struct \
+attribute_group pci_dev_resource##_bar##_attr_group = { \
+ .bin_attrs = pci_dev_resource##_bar##_attrs, \
+ .is_bin_visible = pci_dev_resource##_bar##_attr_is_visible, \
+}; \
+static struct bin_attribute \
+pci_dev_resource##_bar##_wc_attr = __BIN_ATTR(resource##_bar##_wc, \
+ 0600, NULL, NULL, 0); \
+static struct bin_attribute *pci_dev_resource##_bar##_wc_attrs[] = { \
+ &pci_dev_resource##_bar##_wc_attr, \
+ NULL, \
+}; \
+static umode_t \
+pci_dev_resource##_bar##_wc_attr_is_visible(struct kobject *kobj, \
+ struct bin_attribute *a, \
+ int n) \
+{ \
+ return pci_dev_resource_attr_is_visible(kobj, a, _bar, true); \
+}; \
+static const struct \
+attribute_group pci_dev_resource##_bar##_wc_attr_group = { \
+ .bin_attrs = pci_dev_resource##_bar##_wc_attrs, \
+ .is_bin_visible = pci_dev_resource##_bar##_wc_attr_is_visible, \
}
+
+#define pci_dev_resource_group(_bar) \
+ &pci_dev_resource##_bar##_attr_group, \
+ &pci_dev_resource##_bar##_wc_attr_group
+
#else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
-int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
-void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
+
+#define pci_dev_resource_attr(_bar) \
+static struct bin_attribute \
+pci_dev_resource##_bar##_attr = __BIN_ATTR(resource##_bar, \
+ 0600, NULL, NULL, 0); \
+static struct bin_attribute *pci_dev_resource##_bar##_attrs[] = { \
+ &pci_dev_resource##_bar##_attr, \
+ NULL, \
+}; \
+static umode_t \
+pci_dev_resource##_bar##_attr_is_visible(struct kobject *kobj, \
+ struct bin_attribute *a, \
+ int n) \
+{ \
+ return pci_dev_resource_attr_is_visible(kobj, a, _bar, \
+ PCI_RESOURCE_NORMAL); \
+}; \
+const struct \
+attribute_group pci_dev_resource##_bar##_attr_group = { \
+ .bin_attrs = pci_dev_resource##_bar##_attrs, \
+ .is_bin_visible = pci_dev_resource##_bar##_attr_is_visible, \
+}; \
+static struct bin_attribute \
+pci_dev_resource##_bar##_sparse_attr = __BIN_ATTR(resource##_bar##_sparse, \
+ 0600, NULL, NULL, 0); \
+static struct bin_attribute *pci_dev_resource##_bar##_sparse_attrs[] = { \
+ &pci_dev_resource##_bar##_sparse_attr, \
+ NULL, \
+}; \
+static umode_t \
+pci_dev_resource##_bar##_sparse_attr_is_visible(struct kobject *kobj, \
+ struct bin_attribute *a, \
+ int n) \
+{ \
+ return pci_dev_resource_attr_is_visible(kobj, a, _bar, \
+ PCI_RESOURCE_SPARSE); \
+}; \
+const struct \
+attribute_group pci_dev_resource##_bar##_sparse_attr_group = { \
+ .bin_attrs = pci_dev_resource##_bar##_sparse_attrs, \
+ .is_bin_visible = pci_dev_resource##_bar##_sparse_attr_is_visible, \
+}; \
+static struct bin_attribute \
+pci_dev_resource##_bar##_dense_attr = __BIN_ATTR(resource##_bar##_dense, \
+ 0600, NULL, NULL, 0); \
+static struct bin_attribute *pci_dev_resource##_bar##_dense_attrs[] = { \
+ &pci_dev_resource##_bar##_dense_attr, \
+ NULL, \
+}; \
+static umode_t \
+pci_dev_resource##_bar##_dense_attr_is_visible(struct kobject *kobj, \
+ struct bin_attribute *a, \
+ int n) \
+{ \
+ return pci_dev_resource_attr_is_visible(kobj, a, _bar, \
+ PCI_RESOURCE_DENSE); \
+}; \
+const struct \
+attribute_group pci_dev_resource##_bar##_dense_attr_group = { \
+ .bin_attrs = pci_dev_resource##_bar##_dense_attrs, \
+ .is_bin_visible = pci_dev_resource##_bar##_dense_attr_is_visible, \
+}
+
+#define pci_dev_resource_group(_bar) \
+ &pci_dev_resource##_bar##_attr_group, \
+ &pci_dev_resource##_bar##_sparse_attr_group, \
+ &pci_dev_resource##_bar##_dense_attr_group
+
#endif
+pci_dev_resource_attr(0);
+pci_dev_resource_attr(1);
+pci_dev_resource_attr(2);
+pci_dev_resource_attr(3);
+pci_dev_resource_attr(4);
+pci_dev_resource_attr(5);
+
/**
* pci_write_rom - used to enable access to the PCI ROM display
* @filp: sysfs file
@@ -1378,43 +1433,11 @@ static const struct attribute_group pci_dev_reset_attr_group = {
.is_visible = pci_dev_reset_attr_is_visible,
};
-int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
-{
- if (!sysfs_initialized)
- return -EACCES;
-
- return pci_create_resource_files(pdev);
-}
-
-/**
- * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
- * @pdev: device whose entries we should free
- *
- * Cleanup when @pdev is removed from sysfs.
- */
-void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
-{
- if (!sysfs_initialized)
- return;
-
- pci_remove_resource_files(pdev);
-}
-
static int __init pci_sysfs_init(void)
{
- struct pci_dev *pdev = NULL;
struct pci_bus *pbus = NULL;
- int retval;
sysfs_initialized = 1;
- for_each_pci_dev(pdev) {
- retval = pci_create_sysfs_dev_files(pdev);
- if (retval) {
- pci_dev_put(pdev);
- return retval;
- }
- }
-
while ((pbus = pci_find_next_bus(pbus)))
pci_create_legacy_files(pbus);
@@ -1488,6 +1511,12 @@ static const struct attribute_group pci_dev_group = {
const struct attribute_group *pci_dev_groups[] = {
&pci_dev_group,
+ pci_dev_resource_group(0),
+ pci_dev_resource_group(1),
+ pci_dev_resource_group(2),
+ pci_dev_resource_group(3),
+ pci_dev_resource_group(4),
+ pci_dev_resource_group(5),
&pci_dev_config_attr_group,
&pci_dev_rom_attr_group,
&pci_dev_reset_attr_group,
diff --git c/drivers/pci/pci.h w/drivers/pci/pci.h
index 93dcdd431072..8c05fdbe21d9 100644
--- c/drivers/pci/pci.h
+++ w/drivers/pci/pci.h
@@ -19,8 +19,6 @@ bool pcie_cap_has_rtctl(const struct pci_dev *dev);
/* Functions internal to the PCI core code */
-int pci_create_sysfs_dev_files(struct pci_dev *pdev);
-void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
void pci_cleanup_rom(struct pci_dev *dev);
#ifdef CONFIG_DMI
extern const struct attribute_group pci_dev_smbios_attr_group;
diff --git c/drivers/pci/remove.c w/drivers/pci/remove.c
index dd12c2fcc7dc..c814ac61e66f 100644
--- c/drivers/pci/remove.c
+++ w/drivers/pci/remove.c
@@ -23,7 +23,6 @@ static void pci_stop_dev(struct pci_dev *dev)
device_release_driver(&dev->dev);
pci_proc_detach_device(dev);
- pci_remove_sysfs_dev_files(dev);
pci_dev_assign_added(dev, false);
}
diff --git c/fs/sysfs/file.c w/fs/sysfs/file.c
index 9aefa7779b29..d019d6ac6ad0 100644
--- c/fs/sysfs/file.c
+++ w/fs/sysfs/file.c
@@ -174,8 +174,8 @@ static int sysfs_kf_bin_open(struct kernfs_open_file *of)
{
struct bin_attribute *battr = of->kn->priv;
- if (battr->mapping)
- of->file->f_mapping = battr->mapping;
+ if (battr->f_mapping)
+ of->file->f_mapping = battr->f_mapping();
return 0;
}
diff --git c/include/linux/pci.h w/include/linux/pci.h
index 540b377ca8f6..6dd98859a325 100644
--- c/include/linux/pci.h
+++ w/include/linux/pci.h
@@ -459,8 +459,6 @@ struct pci_dev {
u32 saved_config_space[16]; /* Config space saved at suspend time */
struct hlist_head saved_cap_space;
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 */
#ifdef CONFIG_HOTPLUG_PCI_PCIE
unsigned int broken_cmd_compl:1; /* No compl for some cmds */
@@ -2452,6 +2450,19 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type);
#endif
+#if !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE))
+enum pci_resource_type {
+ PCI_RESOURCE_NORMAL = BIT(0),
+ PCI_RESOURCE_SPARSE = BIT(1),
+ PCI_RESOURCE_DENSE = BIT(2),
+};
+
+extern umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
+ struct bin_attribute *attr,
+ int bar,
+ enum pci_resource_type type);
+#endif
+
/* Provide the legacy pci_dma_* API */
#include <linux/pci-dma-compat.h>
diff --git c/include/linux/sysfs.h w/include/linux/sysfs.h
index a12556a4b93a..e3f1e8ac1f85 100644
--- c/include/linux/sysfs.h
+++ w/include/linux/sysfs.h
@@ -176,7 +176,7 @@ struct bin_attribute {
struct attribute attr;
size_t size;
void *private;
- struct address_space *mapping;
+ struct address_space *(*f_mapping)(void);
ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment