From: Bjorn Helgaas Date: Tue, 4 May 2021 15:43:23 +0000 (-0500) Subject: Merge branch 'pci/sysfs' X-Git-Tag: v5.13-rc1~43^2~21 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=bac66f8f9751b432773b48b7c6baf92b036adaae;p=linux-block.git Merge branch 'pci/sysfs' - 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 --- bac66f8f9751b432773b48b7c6baf92b036adaae diff --cc drivers/pci/pci.h index 37d21aa0b0d5,34449e9a6f0a..0c7c57c8bfa6 --- a/drivers/pci/pci.h +++ b/drivers/pci/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); diff --cc drivers/pci/vpd.c index 8af31c5eec2d,6168cf208d63..26bf7c877de5 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@@ -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;