diff options
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
| -rw-r--r-- | drivers/pci/pci-sysfs.c | 263 | 
1 files changed, 111 insertions, 152 deletions
| diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index f8afd54ca3e1..beb8d1f4fafe 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -39,7 +39,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf)				\  	struct pci_dev *pdev;						\  									\  	pdev = to_pci_dev(dev);						\ -	return sprintf(buf, format_string, pdev->field);		\ +	return sysfs_emit(buf, format_string, pdev->field);		\  }									\  static DEVICE_ATTR_RO(field) @@ -56,7 +56,7 @@ static ssize_t broken_parity_status_show(struct device *dev,  					 char *buf)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%u\n", pdev->broken_parity_status); +	return sysfs_emit(buf, "%u\n", pdev->broken_parity_status);  }  static ssize_t broken_parity_status_store(struct device *dev, @@ -129,7 +129,7 @@ static ssize_t power_state_show(struct device *dev,  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%s\n", pci_power_name(pdev->current_state)); +	return sysfs_emit(buf, "%s\n", pci_power_name(pdev->current_state));  }  static DEVICE_ATTR_RO(power_state); @@ -138,10 +138,10 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,  			     char *buf)  {  	struct pci_dev *pci_dev = to_pci_dev(dev); -	char *str = buf;  	int i;  	int max;  	resource_size_t start, end; +	size_t len = 0;  	if (pci_dev->subordinate)  		max = DEVICE_COUNT_RESOURCE; @@ -151,12 +151,12 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,  	for (i = 0; i < max; i++) {  		struct resource *res =  &pci_dev->resource[i];  		pci_resource_to_user(pci_dev, i, res, &start, &end); -		str += sprintf(str, "0x%016llx 0x%016llx 0x%016llx\n", -			       (unsigned long long)start, -			       (unsigned long long)end, -			       (unsigned long long)res->flags); +		len += sysfs_emit_at(buf, len, "0x%016llx 0x%016llx 0x%016llx\n", +				     (unsigned long long)start, +				     (unsigned long long)end, +				     (unsigned long long)res->flags);  	} -	return (str - buf); +	return len;  }  static DEVICE_ATTR_RO(resource); @@ -165,8 +165,8 @@ static ssize_t max_link_speed_show(struct device *dev,  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%s\n", -		       pci_speed_string(pcie_get_speed_cap(pdev))); +	return sysfs_emit(buf, "%s\n", +			  pci_speed_string(pcie_get_speed_cap(pdev)));  }  static DEVICE_ATTR_RO(max_link_speed); @@ -175,7 +175,7 @@ static ssize_t max_link_width_show(struct device *dev,  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%u\n", pcie_get_width_cap(pdev)); +	return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev));  }  static DEVICE_ATTR_RO(max_link_width); @@ -193,7 +193,7 @@ static ssize_t current_link_speed_show(struct device *dev,  	speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS]; -	return sprintf(buf, "%s\n", pci_speed_string(speed)); +	return sysfs_emit(buf, "%s\n", pci_speed_string(speed));  }  static DEVICE_ATTR_RO(current_link_speed); @@ -208,7 +208,7 @@ static ssize_t current_link_width_show(struct device *dev,  	if (err)  		return -EINVAL; -	return sprintf(buf, "%u\n", +	return sysfs_emit(buf, "%u\n",  		(linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);  }  static DEVICE_ATTR_RO(current_link_width); @@ -225,7 +225,7 @@ static ssize_t secondary_bus_number_show(struct device *dev,  	if (err)  		return -EINVAL; -	return sprintf(buf, "%u\n", sec_bus); +	return sysfs_emit(buf, "%u\n", sec_bus);  }  static DEVICE_ATTR_RO(secondary_bus_number); @@ -241,7 +241,7 @@ static ssize_t subordinate_bus_number_show(struct device *dev,  	if (err)  		return -EINVAL; -	return sprintf(buf, "%u\n", sub_bus); +	return sysfs_emit(buf, "%u\n", sub_bus);  }  static DEVICE_ATTR_RO(subordinate_bus_number); @@ -251,7 +251,7 @@ static ssize_t ari_enabled_show(struct device *dev,  {  	struct pci_dev *pci_dev = to_pci_dev(dev); -	return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus)); +	return sysfs_emit(buf, "%u\n", pci_ari_enabled(pci_dev->bus));  }  static DEVICE_ATTR_RO(ari_enabled); @@ -260,11 +260,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,  {  	struct pci_dev *pci_dev = to_pci_dev(dev); -	return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n", -		       pci_dev->vendor, pci_dev->device, -		       pci_dev->subsystem_vendor, pci_dev->subsystem_device, -		       (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), -		       (u8)(pci_dev->class)); +	return sysfs_emit(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n", +			  pci_dev->vendor, pci_dev->device, +			  pci_dev->subsystem_vendor, pci_dev->subsystem_device, +			  (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), +			  (u8)(pci_dev->class));  }  static DEVICE_ATTR_RO(modalias); @@ -302,7 +302,7 @@ static ssize_t enable_show(struct device *dev, struct device_attribute *attr,  	struct pci_dev *pdev;  	pdev = to_pci_dev(dev); -	return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt)); +	return sysfs_emit(buf, "%u\n", atomic_read(&pdev->enable_cnt));  }  static DEVICE_ATTR_RW(enable); @@ -338,7 +338,7 @@ static ssize_t numa_node_store(struct device *dev,  static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,  			      char *buf)  { -	return sprintf(buf, "%d\n", dev->numa_node); +	return sysfs_emit(buf, "%d\n", dev->numa_node);  }  static DEVICE_ATTR_RW(numa_node);  #endif @@ -348,7 +348,7 @@ static ssize_t dma_mask_bits_show(struct device *dev,  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%d\n", fls64(pdev->dma_mask)); +	return sysfs_emit(buf, "%d\n", fls64(pdev->dma_mask));  }  static DEVICE_ATTR_RO(dma_mask_bits); @@ -356,7 +356,7 @@ static ssize_t consistent_dma_mask_bits_show(struct device *dev,  					     struct device_attribute *attr,  					     char *buf)  { -	return sprintf(buf, "%d\n", fls64(dev->coherent_dma_mask)); +	return sysfs_emit(buf, "%d\n", fls64(dev->coherent_dma_mask));  }  static DEVICE_ATTR_RO(consistent_dma_mask_bits); @@ -366,9 +366,9 @@ static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr,  	struct pci_dev *pdev = to_pci_dev(dev);  	struct pci_bus *subordinate = pdev->subordinate; -	return sprintf(buf, "%u\n", subordinate ? -		       !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) -			   : !pdev->no_msi); +	return sysfs_emit(buf, "%u\n", subordinate ? +			  !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) +			    : !pdev->no_msi);  }  static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, @@ -523,7 +523,7 @@ static ssize_t d3cold_allowed_show(struct device *dev,  				   struct device_attribute *attr, char *buf)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return sprintf(buf, "%u\n", pdev->d3cold_allowed); +	return sysfs_emit(buf, "%u\n", pdev->d3cold_allowed);  }  static DEVICE_ATTR_RW(d3cold_allowed);  #endif @@ -537,7 +537,7 @@ static ssize_t devspec_show(struct device *dev,  	if (np == NULL)  		return 0; -	return sprintf(buf, "%pOF", np); +	return sysfs_emit(buf, "%pOF", np);  }  static DEVICE_ATTR_RO(devspec);  #endif @@ -583,7 +583,7 @@ static ssize_t driver_override_show(struct device *dev,  	ssize_t len;  	device_lock(dev); -	len = scnprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override); +	len = sysfs_emit(buf, "%s\n", pdev->driver_override);  	device_unlock(dev);  	return len;  } @@ -658,11 +658,11 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,  	struct pci_dev *vga_dev = vga_default_device();  	if (vga_dev) -		return sprintf(buf, "%u\n", (pdev == vga_dev)); +		return sysfs_emit(buf, "%u\n", (pdev == vga_dev)); -	return sprintf(buf, "%u\n", -		!!(pdev->resource[PCI_ROM_RESOURCE].flags & -		   IORESOURCE_ROM_SHADOW)); +	return sysfs_emit(buf, "%u\n", +			  !!(pdev->resource[PCI_ROM_RESOURCE].flags & +			     IORESOURCE_ROM_SHADOW));  }  static DEVICE_ATTR_RO(boot_vga); @@ -808,6 +808,29 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,  	return count;  } +static BIN_ATTR(config, 0644, pci_read_config, pci_write_config, 0); + +static struct bin_attribute *pci_dev_config_attrs[] = { +	&bin_attr_config, +	NULL, +}; + +static umode_t pci_dev_config_attr_is_visible(struct kobject *kobj, +					      struct bin_attribute *a, int n) +{ +	struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + +	a->size = PCI_CFG_SPACE_SIZE; +	if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) +		a->size = PCI_CFG_SPACE_EXP_SIZE; + +	return a->attr.mode; +} + +static const struct attribute_group pci_dev_config_attr_group = { +	.bin_attrs = pci_dev_config_attrs, +	.is_bin_visible = pci_dev_config_attr_is_visible, +};  #ifdef HAVE_PCI_LEGACY  /** @@ -1283,25 +1306,32 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,  	return count;  } +static BIN_ATTR(rom, 0600, pci_read_rom, pci_write_rom, 0); -static const struct bin_attribute pci_config_attr = { -	.attr =	{ -		.name = "config", -		.mode = 0644, -	}, -	.size = PCI_CFG_SPACE_SIZE, -	.read = pci_read_config, -	.write = pci_write_config, +static struct bin_attribute *pci_dev_rom_attrs[] = { +	&bin_attr_rom, +	NULL,  }; -static const struct bin_attribute pcie_config_attr = { -	.attr =	{ -		.name = "config", -		.mode = 0644, -	}, -	.size = PCI_CFG_SPACE_EXP_SIZE, -	.read = pci_read_config, -	.write = pci_write_config, +static umode_t pci_dev_rom_attr_is_visible(struct kobject *kobj, +					   struct bin_attribute *a, int n) +{ +	struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); +	size_t rom_size; + +	/* If the device has a ROM, try to expose it in sysfs. */ +	rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); +	if (!rom_size) +		return 0; + +	a->size = rom_size; + +	return a->attr.mode; +} + +static const struct attribute_group pci_dev_rom_attr_group = { +	.bin_attrs = pci_dev_rom_attrs, +	.is_bin_visible = pci_dev_rom_attr_is_visible,  };  static ssize_t reset_store(struct device *dev, struct device_attribute *attr, @@ -1325,102 +1355,35 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,  	return count;  } +static DEVICE_ATTR_WO(reset); -static DEVICE_ATTR(reset, 0200, NULL, reset_store); +static struct attribute *pci_dev_reset_attrs[] = { +	&dev_attr_reset.attr, +	NULL, +}; -static int pci_create_capabilities_sysfs(struct pci_dev *dev) +static umode_t pci_dev_reset_attr_is_visible(struct kobject *kobj, +					     struct attribute *a, int n)  { -	int retval; - -	pcie_vpd_create_sysfs_dev_files(dev); +	struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); -	if (dev->reset_fn) { -		retval = device_create_file(&dev->dev, &dev_attr_reset); -		if (retval) -			goto error; -	} -	return 0; +	if (!pdev->reset_fn) +		return 0; -error: -	pcie_vpd_remove_sysfs_dev_files(dev); -	return retval; +	return a->mode;  } +static const struct attribute_group pci_dev_reset_attr_group = { +	.attrs = pci_dev_reset_attrs, +	.is_visible = pci_dev_reset_attr_is_visible, +}; +  int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)  { -	int retval; -	int rom_size; -	struct bin_attribute *attr; -  	if (!sysfs_initialized)  		return -EACCES; -	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; - -	retval = pci_create_resource_files(pdev); -	if (retval) -		goto err_config_file; - -	/* 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) { -			retval = -ENOMEM; -			goto err_resource_files; -		} -		sysfs_bin_attr_init(attr); -		attr->size = rom_size; -		attr->attr.name = "rom"; -		attr->attr.mode = 0600; -		attr->read = pci_read_rom; -		attr->write = pci_write_rom; -		retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); -		if (retval) { -			kfree(attr); -			goto err_resource_files; -		} -		pdev->rom_attr = attr; -	} - -	/* add sysfs entries for various capabilities */ -	retval = pci_create_capabilities_sysfs(pdev); -	if (retval) -		goto err_rom_file; - -	pci_create_firmware_label_files(pdev); - -	return 0; - -err_rom_file: -	if (pdev->rom_attr) { -		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); -		kfree(pdev->rom_attr); -		pdev->rom_attr = NULL; -	} -err_resource_files: -	pci_remove_resource_files(pdev); -err_config_file: -	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; -} - -static void pci_remove_capabilities_sysfs(struct pci_dev *dev) -{ -	pcie_vpd_remove_sysfs_dev_files(dev); -	if (dev->reset_fn) { -		device_remove_file(&dev->dev, &dev_attr_reset); -		dev->reset_fn = 0; -	} +	return pci_create_resource_files(pdev);  }  /** @@ -1434,22 +1397,7 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)  	if (!sysfs_initialized)  		return; -	pci_remove_capabilities_sysfs(pdev); - -	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 (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) @@ -1540,6 +1488,16 @@ static const struct attribute_group pci_dev_group = {  const struct attribute_group *pci_dev_groups[] = {  	&pci_dev_group, +	&pci_dev_config_attr_group, +	&pci_dev_rom_attr_group, +	&pci_dev_reset_attr_group, +	&pci_dev_vpd_attr_group, +#ifdef CONFIG_DMI +	&pci_dev_smbios_attr_group, +#endif +#ifdef CONFIG_ACPI +	&pci_dev_acpi_attr_group, +#endif  	NULL,  }; @@ -1567,7 +1525,8 @@ static const struct attribute_group *pci_dev_attr_groups[] = {  	&pci_dev_attr_group,  	&pci_dev_hp_attr_group,  #ifdef CONFIG_PCI_IOV -	&sriov_dev_attr_group, +	&sriov_pf_dev_attr_group, +	&sriov_vf_dev_attr_group,  #endif  	&pci_bridge_attr_group,  	&pcie_dev_attr_group, | 
