Merge branch 'pci/sysfs'
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 4 May 2021 15:43:23 +0000 (10:43 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 4 May 2021 15:43:23 +0000 (10:43 -0500)
- Convert sysfs "config", "rom", "reset", "label", "index", "acpi_index" to
  static attributes to fix races in device enumeration (Krzysztof
  Wilczyński)

- Convert sysfs "vpd" to static attribute (Heiner Kallweit, Krzysztof
  Wilczyński)

- Use sysfs_emit() in "show" functions (Krzysztof Wilczyński)

* pci/sysfs:
  PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions
  PCI/sysfs: Rearrange smbios_attr_group and acpi_attr_group
  PCI/sysfs: Tidy SMBIOS & ACPI label attributes
  PCI/sysfs: Convert "index", "acpi_index", "label" to static attributes
  PCI/sysfs: Define SMBIOS label attributes with DEVICE_ATTR*()
  PCI/sysfs: Define ACPI label attributes with DEVICE_ATTR*()
  PCI/sysfs: Rename device_has_dsm() to device_has_acpi_name()
  PCI/sysfs: Convert "vpd" to static attribute
  PCI/sysfs: Rename "vpd" attribute accessors
  PCI/sysfs: Convert "reset" to static attribute
  PCI/sysfs: Convert "rom" to static attribute
  PCI/sysfs: Convert "config" to static attribute

1  2 
drivers/pci/pci.h
drivers/pci/vpd.c
include/linux/pci.h

@@@ -141,10 -135,9 +135,9 @@@ static inline bool pcie_downstream_port
               type == PCI_EXP_TYPE_PCIE_BRIDGE;
  }
  
 -int pci_vpd_init(struct pci_dev *dev);
 +void pci_vpd_init(struct pci_dev *dev);
  void pci_vpd_release(struct pci_dev *dev);
- void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev);
- void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev);
+ extern const struct attribute_group pci_dev_vpd_attr_group;
  
  /* PCI Virtual Channel */
  int pci_save_vc_state(struct pci_dev *dev);
@@@ -375,54 -418,67 +374,41 @@@ static ssize_t vpd_write(struct file *f
  {
        struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
  
 -      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);
  }
+ static BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0);
  
- void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev)
- {
-       int retval;
-       struct bin_attribute *attr;
-       if (!dev->vpd)
-               return;
+ static struct bin_attribute *vpd_attrs[] = {
+       &bin_attr_vpd,
+       NULL,
+ };
  
-       attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
-       if (!attr)
-               return;
+ static umode_t vpd_attr_is_visible(struct kobject *kobj,
+                                  struct bin_attribute *a, int n)
+ {
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
  
-       sysfs_bin_attr_init(attr);
-       attr->size = 0;
-       attr->attr.name = "vpd";
-       attr->attr.mode = S_IRUSR | S_IWUSR;
-       attr->read = read_vpd_attr;
-       attr->write = write_vpd_attr;
-       retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
-       if (retval) {
-               kfree(attr);
-               return;
-       }
+       if (!pdev->vpd)
+               return 0;
  
-       dev->vpd->attr = attr;
+       return a->attr.mode;
  }
  
- void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev)
- {
-       if (dev->vpd && dev->vpd->attr) {
-               sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
-               kfree(dev->vpd->attr);
-       }
- }
+ const struct attribute_group pci_dev_vpd_attr_group = {
+       .bin_attrs = vpd_attrs,
+       .is_bin_visible = vpd_attr_is_visible,
+ };
  
 -int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
 +int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt)
  {
 -      int i;
 +      int i = 0;
  
 -      for (i = off; i < len; ) {
 -              u8 val = buf[i];
 -
 -              if (val & PCI_VPD_LRDT) {
 -                      /* Don't return success of the tag isn't complete */
 -                      if (i + PCI_VPD_LRDT_TAG_SIZE > len)
 -                              break;
 -
 -                      if (val == rdt)
 -                              return i;
 -
 -                      i += PCI_VPD_LRDT_TAG_SIZE +
 -                           pci_vpd_lrdt_size(&buf[i]);
 -              } else {
 -                      u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
 -
 -                      if (tag == rdt)
 -                              return i;
 -
 -                      if (tag == PCI_VPD_SRDT_END)
 -                              break;
 +      /* look for LRDT tags only, end tag is the only SRDT tag */
 +      while (i + PCI_VPD_LRDT_TAG_SIZE <= len && buf[i] & PCI_VPD_LRDT) {
 +              if (buf[i] == rdt)
 +                      return i;
  
 -                      i += PCI_VPD_SRDT_TAG_SIZE +
 -                           pci_vpd_srdt_size(&buf[i]);
 -              }
 +              i += PCI_VPD_LRDT_TAG_SIZE + pci_vpd_lrdt_size(buf + i);
        }
  
        return -ENOENT;
Simple merge