diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:35 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:35 +0100 |
| commit | 2b0294d93212c0fdfa9285789459106cad3972b4 (patch) | |
| tree | 9928ab591c940a9586bcda65ffee26005a99aa92 /arch | |
| parent | 0e0824ca26a57bba404a6bf2fd63282e8f1ad757 (diff) | |
| parent | 3a97877d13e1a29c50ab15ed0a0aba87b75061dd (diff) | |
| download | linux-next-history-2b0294d93212c0fdfa9285789459106cad3972b4.tar.gz | |
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/alpha/include/asm/pci.h | 13 | ||||
| -rw-r--r-- | arch/alpha/kernel/pci-sysfs.c | 384 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/machdep.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/pci.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci-common.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-sriov.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 5 |
8 files changed, 229 insertions, 188 deletions
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index 6c04fcbdc8ed2..ad5d1391e1fa8 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h @@ -84,8 +84,17 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, extern int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma, enum pci_mmap_state mmap_state); -extern void pci_adjust_legacy_attr(struct pci_bus *bus, - enum pci_mmap_state mmap_type); +extern bool pci_legacy_has_sparse(struct pci_bus *bus, + enum pci_mmap_state type); #define HAVE_PCI_LEGACY 1 +extern const struct attribute_group pci_dev_resource_attr_group; +extern const struct attribute_group pci_dev_resource_sparse_attr_group; +extern const struct attribute_group pci_dev_resource_dense_attr_group; + +#define ARCH_PCI_DEV_GROUPS \ + &pci_dev_resource_attr_group, \ + &pci_dev_resource_sparse_attr_group, \ + &pci_dev_resource_dense_attr_group, + #endif /* __ALPHA_PCI_H */ diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 3048758304b57..94dbc470cd6c0 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -11,8 +11,7 @@ */ #include <linux/sched.h> -#include <linux/stat.h> -#include <linux/slab.h> +#include <linux/security.h> #include <linux/pci.h> static int hose_mmap_page_range(struct pci_controller *hose, @@ -36,20 +35,18 @@ static int hose_mmap_page_range(struct pci_controller *hose, static int __pci_mmap_fits(struct pci_dev *pdev, int num, struct vm_area_struct *vma, int sparse) { + resource_size_t len = pci_resource_len(pdev, num); unsigned long nr, start, size; int shift = sparse ? 5 : 0; + if (!len) + return 0; + nr = vma_pages(vma); start = vma->vm_pgoff; - size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1; + size = ((len - 1) >> (PAGE_SHIFT - shift)) + 1; - if (start < size && size - start >= nr) - return 1; - WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d " - "(size 0x%08lx)\n", - current->comm, sparse ? " sparse" : "", start, start + nr, - pci_name(pdev), num, size); - return 0; + return start < size && size - start >= nr; } /** @@ -68,26 +65,25 @@ 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; 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)) + if (pci_resource_is_mem(pdev, barno) && + iomem_is_exclusive(pci_resource_start(pdev, barno))) 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); + pcibios_resource_to_bus(pdev->bus, &bar, pci_resource_n(pdev, barno)); vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0)); - mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; + mmap_type = pci_resource_is_mem(pdev, barno) ? pci_mmap_mem : pci_mmap_io; return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse); } @@ -106,33 +102,25 @@ 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 - * @pdev: pci_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; +#define __pci_dev_resource_attr(_bar, _name, _suffix, _mmap) \ +static const struct bin_attribute \ +pci_dev_resource##_bar##_suffix##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0600 }, \ + .private = (void *)(unsigned long)(_bar), \ + .mmap = (_mmap), \ +} - for (i = 0; i < PCI_STD_NUM_BARS; i++) { - struct bin_attribute *res_attr; +#define pci_dev_resource_attr(_bar) \ + __pci_dev_resource_attr(_bar, resource##_bar,, \ + pci_mmap_resource_dense) - res_attr = pdev->res_attr[i]; - if (res_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); - kfree(res_attr); - } +#define pci_dev_resource_sparse_attr(_bar) \ + __pci_dev_resource_attr(_bar, resource##_bar##_sparse, _sparse, \ + pci_mmap_resource_sparse) - res_attr = pdev->res_attr_wc[i]; - if (res_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); - kfree(res_attr); - } - } -} +#define pci_dev_resource_dense_attr(_bar) \ + __pci_dev_resource_attr(_bar, resource##_bar##_dense, _dense, \ + pci_mmap_resource_dense) static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num) { @@ -141,7 +129,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num) long dense_offset; unsigned long sparse_size; - pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]); + pcibios_resource_to_bus(pdev->bus, &bar, pci_resource_n(pdev, num)); /* All core logic chips have 4G sparse address space, except CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM @@ -153,109 +141,10 @@ 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) -{ - /* 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_controller *hose = pdev->sysdata; - char *suffix, *attr_name; - - suffix = ""; /* Assume bwx machine, normal resourceN files. */ - nlen1 = 10; - - if (pdev->resource[num].flags & IORESOURCE_MEM) { - sparse_base = hose->sparse_mem_base; - dense_base = hose->dense_mem_base; - if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) { - sparse_base = 0; - suffix = "_dense"; - nlen1 = 16; /* resourceN_dense */ - } - } else { - sparse_base = hose->sparse_io_base; - dense_base = hose->dense_io_base; - } - - if (sparse_base) { - suffix = "_sparse"; - nlen1 = 17; - if (dense_base) { - nlen2 = 16; /* resourceN_dense */ - res_count = 2; - } - } - - 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); -} - -/** - * pci_create_resource_files - create resource files in sysfs for @pdev - * @pdev: pci_dev in question - * - * Walk the resources in @dev creating files for each resource available. - * - * Return: %0 on success, or negative error code - */ -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); - if (retval) { - pci_remove_resource_files(pdev); - return retval; - } - } - return 0; -} - /* Legacy I/O bus mapping stuff. */ -static int __legacy_mmap_fits(struct pci_controller *hose, - struct vm_area_struct *vma, - unsigned long res_size, int sparse) +static int __legacy_mmap_fits(struct vm_area_struct *vma, + unsigned long res_size) { unsigned long nr, start, size; @@ -263,13 +152,7 @@ static int __legacy_mmap_fits(struct pci_controller *hose, start = vma->vm_pgoff; size = ((res_size - 1) >> PAGE_SHIFT) + 1; - if (start < size && size - start >= nr) - return 1; - WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on hose %d " - "(size 0x%08lx)\n", - current->comm, sparse ? " sparse" : "", start, start + nr, - hose->index, size); - return 0; + return start < size && size - start >= nr; } static inline int has_sparse(struct pci_controller *hose, @@ -290,36 +173,22 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma, int sparse = has_sparse(hose, mmap_type); unsigned long res_size; - res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size : - bus->legacy_io->size; - if (!__legacy_mmap_fits(hose, vma, res_size, sparse)) + res_size = (mmap_type == pci_mmap_mem) ? PCI_LEGACY_MEM_SIZE : + PCI_LEGACY_IO_SIZE; + if (sparse) + res_size <<= 5; + + if (!__legacy_mmap_fits(vma, res_size)) return -EINVAL; return hose_mmap_page_range(hose, vma, mmap_type, sparse); } -/** - * pci_adjust_legacy_attr - adjustment of legacy file attributes - * @bus: bus to create files under - * @mmap_type: I/O port or memory - * - * Adjust file name and size for sparse mappings. - */ -void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type) +bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type) { struct pci_controller *hose = bus->sysdata; - if (!has_sparse(hose, mmap_type)) - return; - - if (mmap_type == pci_mmap_mem) { - bus->legacy_mem->attr.name = "legacy_mem_sparse"; - bus->legacy_mem->size <<= 5; - } else { - bus->legacy_io->attr.name = "legacy_io_sparse"; - bus->legacy_io->size <<= 5; - } - return; + return has_sparse(hose, type); } /* Legacy I/O bus read/write functions */ @@ -370,3 +239,166 @@ int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) } return -EINVAL; } + +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_dev_resource_sparse_attr(0); +pci_dev_resource_sparse_attr(1); +pci_dev_resource_sparse_attr(2); +pci_dev_resource_sparse_attr(3); +pci_dev_resource_sparse_attr(4); +pci_dev_resource_sparse_attr(5); + +pci_dev_resource_dense_attr(0); +pci_dev_resource_dense_attr(1); +pci_dev_resource_dense_attr(2); +pci_dev_resource_dense_attr(3); +pci_dev_resource_dense_attr(4); +pci_dev_resource_dense_attr(5); + +static inline enum pci_mmap_state pci_bar_mmap_type(struct pci_dev *pdev, + int bar) +{ + return pci_resource_is_mem(pdev, bar) ? pci_mmap_mem : pci_mmap_io; +} + +static inline umode_t __pci_resource_attr_is_visible(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + + if (!pci_resource_len(pdev, bar)) + return 0; + + return a->attr.mode; +} + +static umode_t pci_dev_resource_is_visible(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + struct pci_controller *hose = pdev->sysdata; + + if (has_sparse(hose, pci_bar_mmap_type(pdev, bar))) + return 0; + + return __pci_resource_attr_is_visible(kobj, a, bar); +} + +static umode_t pci_dev_resource_sparse_is_visible(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + struct pci_controller *hose = pdev->sysdata; + enum pci_mmap_state type = pci_bar_mmap_type(pdev, bar); + + if (!has_sparse(hose, type)) + return 0; + + if (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar)) + return 0; + + return __pci_resource_attr_is_visible(kobj, a, bar); +} + +static umode_t pci_dev_resource_dense_is_visible(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + struct pci_controller *hose = pdev->sysdata; + enum pci_mmap_state type = pci_bar_mmap_type(pdev, bar); + unsigned long dense_base; + + if (!has_sparse(hose, type)) + return 0; + + if (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar)) + return __pci_resource_attr_is_visible(kobj, a, bar); + + dense_base = (type == pci_mmap_mem) ? hose->dense_mem_base : + hose->dense_io_base; + if (!dense_base) + return 0; + + return __pci_resource_attr_is_visible(kobj, a, bar); +} + +static inline size_t __pci_dev_resource_bin_size(struct kobject *kobj, + int bar, bool sparse) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + size_t size = pci_resource_len(pdev, bar); + + return sparse ? size << 5 : size; +} + +static size_t pci_dev_resource_bin_size(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + return __pci_dev_resource_bin_size(kobj, bar, false); +} + +static size_t pci_dev_resource_sparse_bin_size(struct kobject *kobj, + const struct bin_attribute *a, + int bar) +{ + return __pci_dev_resource_bin_size(kobj, bar, true); +} + +static const struct bin_attribute *const pci_dev_resource_attrs[] = { + &pci_dev_resource0_attr, + &pci_dev_resource1_attr, + &pci_dev_resource2_attr, + &pci_dev_resource3_attr, + &pci_dev_resource4_attr, + &pci_dev_resource5_attr, + NULL, +}; + +static const struct bin_attribute *const pci_dev_resource_sparse_attrs[] = { + &pci_dev_resource0_sparse_attr, + &pci_dev_resource1_sparse_attr, + &pci_dev_resource2_sparse_attr, + &pci_dev_resource3_sparse_attr, + &pci_dev_resource4_sparse_attr, + &pci_dev_resource5_sparse_attr, + NULL, +}; + +static const struct bin_attribute *const pci_dev_resource_dense_attrs[] = { + &pci_dev_resource0_dense_attr, + &pci_dev_resource1_dense_attr, + &pci_dev_resource2_dense_attr, + &pci_dev_resource3_dense_attr, + &pci_dev_resource4_dense_attr, + &pci_dev_resource5_dense_attr, + NULL, +}; + +const struct attribute_group pci_dev_resource_attr_group = { + .bin_attrs = pci_dev_resource_attrs, + .is_bin_visible = pci_dev_resource_is_visible, + .bin_size = pci_dev_resource_bin_size, +}; + +const struct attribute_group pci_dev_resource_sparse_attr_group = { + .bin_attrs = pci_dev_resource_sparse_attrs, + .is_bin_visible = pci_dev_resource_sparse_is_visible, + .bin_size = pci_dev_resource_sparse_bin_size, +}; + +const struct attribute_group pci_dev_resource_dense_attr_group = { + .bin_attrs = pci_dev_resource_dense_attrs, + .is_bin_visible = pci_dev_resource_dense_is_visible, + .bin_size = pci_dev_resource_bin_size, +}; diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 3298eec123a32..256f9309bf4fa 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -169,7 +169,7 @@ struct machdep_calls { #ifdef CONFIG_PCI_IOV void (*pcibios_fixup_sriov)(struct pci_dev *pdev); - resource_size_t (*pcibios_iov_resource_alignment)(struct pci_dev *, int resno); + resource_size_t (*pcibios_iov_resource_alignment)(const struct pci_dev *, int resno); int (*pcibios_sriov_enable)(struct pci_dev *pdev, u16 num_vfs); int (*pcibios_sriov_disable)(struct pci_dev *pdev); #endif /* CONFIG_PCI_IOV */ diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 46a9c4491ed0c..72f286e747863 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -82,8 +82,6 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, extern int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma, enum pci_mmap_state mmap_state); -extern void pci_adjust_legacy_attr(struct pci_bus *bus, - enum pci_mmap_state mmap_type); #define HAVE_PCI_LEGACY 1 extern void pcibios_claim_one_bus(struct pci_bus *b); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 8efe95a0c4ffd..3c4ca90e2ab77 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -254,7 +254,7 @@ resource_size_t pcibios_default_alignment(void) } #ifdef CONFIG_PCI_IOV -resource_size_t pcibios_iov_resource_alignment(struct pci_dev *pdev, int resno) +resource_size_t pcibios_iov_resource_alignment(const struct pci_dev *pdev, int resno) { if (ppc_md.pcibios_iov_resource_alignment) return ppc_md.pcibios_iov_resource_alignment(pdev, resno); diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c index 7105a573aec42..8652078801f2a 100644 --- a/arch/powerpc/platforms/powernv/pci-sriov.c +++ b/arch/powerpc/platforms/powernv/pci-sriov.c @@ -244,8 +244,8 @@ void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev) } } -resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, - int resno) +resource_size_t pnv_pci_iov_resource_alignment(const struct pci_dev *pdev, + int resno) { resource_size_t align = pci_iov_resource_size(pdev, resno); struct pnv_phb *phb = pci_bus_to_pnvhb(pdev->bus); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 42075501663b7..3ac718d471c20 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -251,13 +251,14 @@ struct pnv_iov_data { struct resource holes[PCI_SRIOV_NUM_BARS]; }; -static inline struct pnv_iov_data *pnv_iov_get(struct pci_dev *pdev) +static inline struct pnv_iov_data *pnv_iov_get(const struct pci_dev *pdev) { return pdev->dev.archdata.iov_data; } void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev); -resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno); +resource_size_t pnv_pci_iov_resource_alignment(const struct pci_dev *pdev, + int resno); int pnv_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs); int pnv_pcibios_sriov_disable(struct pci_dev *pdev); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 50b26ed8432d5..1223dc9612429 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -658,7 +658,8 @@ enum get_iov_fw_value_index { WDW_SIZE = 3 /* Get Window Size */ }; -static resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno, +static resource_size_t pseries_get_iov_fw_value(const struct pci_dev *dev, + int resno, enum get_iov_fw_value_index value) { const int *indexes; @@ -788,7 +789,7 @@ static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev) pseries_disable_sriov_resources(pdev); } -static resource_size_t pseries_pci_iov_resource_alignment(struct pci_dev *pdev, +static resource_size_t pseries_pci_iov_resource_alignment(const struct pci_dev *pdev, int resno) { const __be32 *reg; |
