diff options
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r-- | drivers/pci/pci-sysfs.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index cb04bc29943f..534844df8bf5 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -1017,26 +1017,20 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
1017 | struct vm_area_struct *vma, int write_combine) | 1017 | struct vm_area_struct *vma, int write_combine) |
1018 | { | 1018 | { |
1019 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); | 1019 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); |
1020 | struct resource *res = attr->private; | 1020 | int bar = (unsigned long)attr->private; |
1021 | enum pci_mmap_state mmap_type; | 1021 | enum pci_mmap_state mmap_type; |
1022 | resource_size_t start, end; | 1022 | resource_size_t start, end; |
1023 | int i; | 1023 | struct resource *res = &pdev->resource[bar]; |
1024 | |||
1025 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
1026 | if (res == &pdev->resource[i]) | ||
1027 | break; | ||
1028 | if (i >= PCI_ROM_RESOURCE) | ||
1029 | return -ENODEV; | ||
1030 | 1024 | ||
1031 | if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) | 1025 | if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) |
1032 | return -EINVAL; | 1026 | return -EINVAL; |
1033 | 1027 | ||
1034 | if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { | 1028 | if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS)) { |
1035 | WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", | 1029 | WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", |
1036 | current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, | 1030 | current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, |
1037 | pci_name(pdev), i, | 1031 | pci_name(pdev), bar, |
1038 | (u64)pci_resource_start(pdev, i), | 1032 | (u64)pci_resource_start(pdev, bar), |
1039 | (u64)pci_resource_len(pdev, i)); | 1033 | (u64)pci_resource_len(pdev, bar)); |
1040 | return -EINVAL; | 1034 | return -EINVAL; |
1041 | } | 1035 | } |
1042 | 1036 | ||
@@ -1044,7 +1038,7 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
1044 | * from /proc/bus/pci/ which is a "user visible" value. If this is | 1038 | * from /proc/bus/pci/ which is a "user visible" value. If this is |
1045 | * different from the resource itself, arch will do necessary fixup. | 1039 | * different from the resource itself, arch will do necessary fixup. |
1046 | */ | 1040 | */ |
1047 | pci_resource_to_user(pdev, i, res, &start, &end); | 1041 | pci_resource_to_user(pdev, bar, res, &start, &end); |
1048 | vma->vm_pgoff += start >> PAGE_SHIFT; | 1042 | vma->vm_pgoff += start >> PAGE_SHIFT; |
1049 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; | 1043 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; |
1050 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); | 1044 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); |
@@ -1069,22 +1063,18 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj, | |||
1069 | loff_t off, size_t count, bool write) | 1063 | loff_t off, size_t count, bool write) |
1070 | { | 1064 | { |
1071 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); | 1065 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); |
1072 | struct resource *res = attr->private; | 1066 | int bar = (unsigned long)attr->private; |
1067 | struct resource *res; | ||
1073 | unsigned long port = off; | 1068 | unsigned long port = off; |
1074 | int i; | ||
1075 | 1069 | ||
1076 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | 1070 | res = &pdev->resource[bar]; |
1077 | if (res == &pdev->resource[i]) | ||
1078 | break; | ||
1079 | if (i >= PCI_ROM_RESOURCE) | ||
1080 | return -ENODEV; | ||
1081 | 1071 | ||
1082 | port += pci_resource_start(pdev, i); | 1072 | port += pci_resource_start(pdev, bar); |
1083 | 1073 | ||
1084 | if (port > pci_resource_end(pdev, i)) | 1074 | if (port > pci_resource_end(pdev, bar)) |
1085 | return 0; | 1075 | return 0; |
1086 | 1076 | ||
1087 | if (port + count - 1 > pci_resource_end(pdev, i)) | 1077 | if (port + count - 1 > pci_resource_end(pdev, bar)) |
1088 | return -EINVAL; | 1078 | return -EINVAL; |
1089 | 1079 | ||
1090 | switch (count) { | 1080 | switch (count) { |
@@ -1186,7 +1176,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
1186 | res_attr->attr.name = res_attr_name; | 1176 | res_attr->attr.name = res_attr_name; |
1187 | res_attr->attr.mode = S_IRUSR | S_IWUSR; | 1177 | res_attr->attr.mode = S_IRUSR | S_IWUSR; |
1188 | res_attr->size = pci_resource_len(pdev, num); | 1178 | res_attr->size = pci_resource_len(pdev, num); |
1189 | res_attr->private = &pdev->resource[num]; | 1179 | res_attr->private = (void *)(unsigned long)num; |
1190 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); | 1180 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); |
1191 | if (retval) | 1181 | if (retval) |
1192 | kfree(res_attr); | 1182 | kfree(res_attr); |