提交 45aec1ae 编写于 作者: V venkatesh.pallipadi@intel.com 提交者: Ingo Molnar

x86: PAT export resource_wc in pci sysfs

For the ranges with IORESOURCE_PREFETCH, export a new resource_wc interface in
pci /sysfs along with resource (which is uncached).
Signed-off-by: NVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: NSuresh Siddha <suresh.b.siddha@intel.com>
Acked-by: NJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
上级 b7f09ae5
...@@ -36,6 +36,7 @@ files, each with their own function. ...@@ -36,6 +36,7 @@ files, each with their own function.
local_cpus nearby CPU mask (cpumask, ro) local_cpus nearby CPU mask (cpumask, ro)
resource PCI resource host addresses (ascii, ro) resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap) resource0..N PCI resource N, if present (binary, mmap)
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
rom PCI ROM resource, if present (binary, ro) rom PCI ROM resource, if present (binary, ro)
subsystem_device PCI subsystem device (ascii, ro) subsystem_device PCI subsystem device (ascii, ro)
subsystem_vendor PCI subsystem vendor (ascii, ro) subsystem_vendor PCI subsystem vendor (ascii, ro)
......
...@@ -489,13 +489,14 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, ...@@ -489,13 +489,14 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
* @kobj: kobject for mapping * @kobj: kobject for mapping
* @attr: struct bin_attribute for the file being mapped * @attr: struct bin_attribute for the file being mapped
* @vma: struct vm_area_struct passed into the mmap * @vma: struct vm_area_struct passed into the mmap
* @write_combine: 1 for write_combine mapping
* *
* Use the regular PCI mapping routines to map a PCI resource into userspace. * Use the regular PCI mapping routines to map a PCI resource into userspace.
* FIXME: write combining? maybe automatic for prefetchable regions? * FIXME: write combining? maybe automatic for prefetchable regions?
*/ */
static int static int
pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma) struct vm_area_struct *vma, int write_combine)
{ {
struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct pci_dev *pdev = to_pci_dev(container_of(kobj,
struct device, kobj)); struct device, kobj));
...@@ -518,7 +519,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, ...@@ -518,7 +519,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
vma->vm_pgoff += start >> PAGE_SHIFT; vma->vm_pgoff += start >> PAGE_SHIFT;
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
return pci_mmap_page_range(pdev, vma, mmap_type, 0); return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
}
static int
pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma)
{
return pci_mmap_resource(kobj, attr, vma, 0);
}
static int
pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma)
{
return pci_mmap_resource(kobj, attr, vma, 1);
} }
/** /**
...@@ -541,9 +556,46 @@ pci_remove_resource_files(struct pci_dev *pdev) ...@@ -541,9 +556,46 @@ pci_remove_resource_files(struct pci_dev *pdev)
sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
kfree(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)
{
/* allocate attribute structure, piggyback attribute name */
int name_len = write_combine ? 13 : 10;
struct bin_attribute *res_attr;
int retval;
res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
if (res_attr) {
char *res_attr_name = (char *)(res_attr + 1);
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;
} else {
pdev->res_attr[num] = res_attr;
sprintf(res_attr_name, "resource%d", num);
res_attr->mmap = pci_mmap_resource_uc;
}
res_attr->attr.name = res_attr_name;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
res_attr->size = pci_resource_len(pdev, num);
res_attr->private = &pdev->resource[num];
retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
} else
retval = -ENOMEM;
return retval;
}
/** /**
* pci_create_resource_files - create resource files in sysfs for @dev * pci_create_resource_files - create resource files in sysfs for @dev
* @dev: dev in question * @dev: dev in question
...@@ -557,31 +609,19 @@ static int pci_create_resource_files(struct pci_dev *pdev) ...@@ -557,31 +609,19 @@ static int pci_create_resource_files(struct pci_dev *pdev)
/* Expose the PCI resources from this device as files */ /* Expose the PCI resources from this device as files */
for (i = 0; i < PCI_ROM_RESOURCE; i++) { for (i = 0; i < PCI_ROM_RESOURCE; i++) {
struct bin_attribute *res_attr;
/* skip empty resources */ /* skip empty resources */
if (!pci_resource_len(pdev, i)) if (!pci_resource_len(pdev, i))
continue; continue;
/* allocate attribute structure, piggyback attribute name */ retval = pci_create_attr(pdev, i, 0);
res_attr = kzalloc(sizeof(*res_attr) + 10, GFP_ATOMIC); /* for prefetchable resources, create a WC mappable file */
if (res_attr) { if (!retval && pdev->resource[i].flags & IORESOURCE_PREFETCH)
char *res_attr_name = (char *)(res_attr + 1); retval = pci_create_attr(pdev, i, 1);
pdev->res_attr[i] = res_attr; if (retval) {
sprintf(res_attr_name, "resource%d", i); pci_remove_resource_files(pdev);
res_attr->attr.name = res_attr_name; return retval;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
res_attr->size = pci_resource_len(pdev, i);
res_attr->mmap = pci_mmap_resource;
res_attr->private = &pdev->resource[i];
retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
if (retval) {
pci_remove_resource_files(pdev);
return retval;
}
} else {
return -ENOMEM;
} }
} }
return 0; return 0;
......
...@@ -206,6 +206,7 @@ struct pci_dev { ...@@ -206,6 +206,7 @@ struct pci_dev {
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */ int rom_attr_enabled; /* has display of the rom attribute been enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ 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_PCI_MSI #ifdef CONFIG_PCI_MSI
struct list_head msi_list; struct list_head msi_list;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册