]> git.karo-electronics.de Git - linux-beck.git/blobdiff - drivers/pci/pci-sysfs.c
Merge branch 'pci/resource' into next
[linux-beck.git] / drivers / pci / pci-sysfs.c
index eead54cd01b2bfad6a5514f53067429e616db6b7..e982010f0ed19e0d0379da4a1c02334a1db9f175 100644 (file)
@@ -630,8 +630,7 @@ static ssize_t pci_read_config(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(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
        unsigned int size = 64;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
@@ -707,8 +706,7 @@ static ssize_t pci_write_config(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(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
        unsigned int size = count;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
@@ -769,13 +767,14 @@ 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)
 {
-       struct pci_dev *dev =
-               to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
-       if (off > bin_attr->size)
-               count = 0;
-       else if (count > bin_attr->size - off)
-               count = bin_attr->size - off;
+       if (bin_attr->size > 0) {
+               if (off > bin_attr->size)
+                       count = 0;
+               else if (count > bin_attr->size - off)
+                       count = bin_attr->size - off;
+       }
 
        return pci_read_vpd(dev, off, count, buf);
 }
@@ -784,13 +783,14 @@ 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)
 {
-       struct pci_dev *dev =
-               to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
-       if (off > bin_attr->size)
-               count = 0;
-       else if (count > bin_attr->size - off)
-               count = bin_attr->size - off;
+       if (bin_attr->size > 0) {
+               if (off > bin_attr->size)
+                       count = 0;
+               else if (count > bin_attr->size - off)
+                       count = bin_attr->size - off;
+       }
 
        return pci_write_vpd(dev, off, count, buf);
 }
@@ -812,8 +812,7 @@ static ssize_t pci_read_legacy_io(struct file *filp, struct kobject *kobj,
                                  struct bin_attribute *bin_attr, char *buf,
                                  loff_t off, size_t count)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        /* Only support 1, 2 or 4 byte accesses */
        if (count != 1 && count != 2 && count != 4)
@@ -838,8 +837,7 @@ static ssize_t pci_write_legacy_io(struct file *filp, struct kobject *kobj,
                                   struct bin_attribute *bin_attr, char *buf,
                                   loff_t off, size_t count)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        /* Only support 1, 2 or 4 byte accesses */
        if (count != 1 && count != 2 && count != 4)
@@ -863,8 +861,7 @@ static int pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj,
                               struct bin_attribute *attr,
                               struct vm_area_struct *vma)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
 }
@@ -884,8 +881,7 @@ static int pci_mmap_legacy_io(struct file *filp, struct kobject *kobj,
                              struct bin_attribute *attr,
                              struct vm_area_struct *vma)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
 }
@@ -1000,8 +996,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
                             struct vm_area_struct *vma, int write_combine)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj,
-                                                      struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        struct resource *res = attr->private;
        enum pci_mmap_state mmap_type;
        resource_size_t start, end;
@@ -1054,8 +1049,7 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
                               struct bin_attribute *attr, char *buf,
                               loff_t off, size_t count, bool write)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj,
-                                                      struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        struct resource *res = attr->private;
        unsigned long port = off;
        int i;
@@ -1144,33 +1138,36 @@ 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;
+       char *res_attr_name;
        int retval;
 
        res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
-       if (res_attr) {
-               char *res_attr_name = (char *)(res_attr + 1);
-
-               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;
-               } else {
-                       pdev->res_attr[num] = res_attr;
-                       sprintf(res_attr_name, "resource%d", num);
-                       res_attr->mmap = pci_mmap_resource_uc;
-               }
-               if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
-                       res_attr->read = pci_read_resource_io;
-                       res_attr->write = pci_write_resource_io;
-               }
-               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;
+       if (!res_attr)
+               return -ENOMEM;
+
+       res_attr_name = (char *)(res_attr + 1);
+
+       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;
+       } else {
+               pdev->res_attr[num] = res_attr;
+               sprintf(res_attr_name, "resource%d", num);
+               res_attr->mmap = pci_mmap_resource_uc;
+       }
+       if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+               res_attr->read = pci_read_resource_io;
+               res_attr->write = pci_write_resource_io;
+       }
+       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);
+       if (retval)
+               kfree(res_attr);
 
        return retval;
 }
@@ -1225,7 +1222,7 @@ static ssize_t pci_write_rom(struct file *filp, struct kobject *kobj,
                             struct bin_attribute *bin_attr, char *buf,
                             loff_t off, size_t count)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
 
        if ((off ==  0) && (*buf == '0') && (count == 2))
                pdev->rom_attr_enabled = 0;
@@ -1251,7 +1248,7 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,
                            struct bin_attribute *bin_attr, char *buf,
                            loff_t off, size_t count)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        void __iomem *rom;
        size_t size;
 
@@ -1329,7 +1326,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
                        return -ENOMEM;
 
                sysfs_bin_attr_init(attr);
-               attr->size = dev->vpd->len;
+               attr->size = 0;
                attr->attr.name = "vpd";
                attr->attr.mode = S_IRUSR | S_IWUSR;
                attr->read = read_vpd_attr;
@@ -1366,16 +1363,16 @@ error:
 int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
 {
        int retval;
-       int rom_size = 0;
+       int rom_size;
        struct bin_attribute *attr;
 
        if (!sysfs_initialized)
                return -EACCES;
 
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       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;
 
@@ -1383,12 +1380,8 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
        if (retval)
                goto err_config_file;
 
-       if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
-               rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-       else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
-               rom_size = 0x20000;
-
        /* 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) {
@@ -1419,7 +1412,7 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
        return 0;
 
 err_rom_file:
-       if (rom_size) {
+       if (pdev->rom_attr) {
                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
                kfree(pdev->rom_attr);
                pdev->rom_attr = NULL;
@@ -1427,10 +1420,10 @@ err_rom_file:
 err_resource_files:
        pci_remove_resource_files(pdev);
 err_config_file:
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       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;
 }
@@ -1457,32 +1450,25 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
  */
 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 {
-       int rom_size = 0;
-
        if (!sysfs_initialized)
                return;
 
        pci_remove_capabilities_sysfs(pdev);
 
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       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 (pci_resource_len(pdev, PCI_ROM_RESOURCE))
-               rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-       else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
-               rom_size = 0x20000;
-
-       if (rom_size && pdev->rom_attr) {
+       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)
@@ -1511,7 +1497,7 @@ static struct attribute *pci_dev_dev_attrs[] = {
 static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
                                         struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
 
        if (a == &vga_attr.attr)
@@ -1530,7 +1516,7 @@ static struct attribute *pci_dev_hp_attrs[] = {
 static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
                                            struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
 
        if (pdev->is_virtfn)
@@ -1554,7 +1540,7 @@ static struct attribute *sriov_dev_attrs[] = {
 static umode_t sriov_attrs_are_visible(struct kobject *kobj,
                                       struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
 
        if (!dev_is_pf(dev))
                return 0;