^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright 2002-2004 Greg Kroah-Hartman <greg@kroah.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (C) Copyright 2002-2004 IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (C) Copyright 2003 Matthew Wilcox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) Copyright 2003 Hewlett-Packard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * File attributes for PCI devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Modeled after usb's driverfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/topology.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/vgaarb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int sysfs_initialized; /* = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* show configuration fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define pci_config_attr(field, format_string) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct pci_dev *pdev; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) pdev = to_pci_dev(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return sprintf(buf, format_string, pdev->field); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static DEVICE_ATTR_RO(field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pci_config_attr(vendor, "0x%04x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pci_config_attr(device, "0x%04x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) pci_config_attr(subsystem_vendor, "0x%04x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pci_config_attr(subsystem_device, "0x%04x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) pci_config_attr(revision, "0x%02x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) pci_config_attr(class, "0x%06x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) pci_config_attr(irq, "%u\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static ssize_t broken_parity_status_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return sprintf(buf, "%u\n", pdev->broken_parity_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static ssize_t broken_parity_status_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) pdev->broken_parity_status = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static DEVICE_ATTR_RW(broken_parity_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static ssize_t pci_dev_show_local_cpu(struct device *dev, bool list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const struct cpumask *mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) cpumask_of_node(dev_to_node(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return cpumap_print_to_pagebuf(list, buf, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static ssize_t local_cpus_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return pci_dev_show_local_cpu(dev, false, attr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static DEVICE_ATTR_RO(local_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static ssize_t local_cpulist_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return pci_dev_show_local_cpu(dev, true, attr, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static DEVICE_ATTR_RO(local_cpulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * PCI Bus Class Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static ssize_t cpuaffinity_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return cpumap_print_to_pagebuf(false, buf, cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static DEVICE_ATTR_RO(cpuaffinity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static ssize_t cpulistaffinity_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return cpumap_print_to_pagebuf(true, buf, cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static DEVICE_ATTR_RO(cpulistaffinity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* show resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char *str = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) resource_size_t start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (pci_dev->subordinate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) max = DEVICE_COUNT_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) max = PCI_BRIDGE_RESOURCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) for (i = 0; i < max; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct resource *res = &pci_dev->resource[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pci_resource_to_user(pci_dev, i, res, &start, &end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) str += sprintf(str, "0x%016llx 0x%016llx 0x%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (unsigned long long)start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) (unsigned long long)end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (unsigned long long)res->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static DEVICE_ATTR_RO(resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static ssize_t max_link_speed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pci_speed_string(pcie_get_speed_cap(pdev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static DEVICE_ATTR_RO(max_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static ssize_t max_link_width_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return sprintf(buf, "%u\n", pcie_get_width_cap(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static DEVICE_ATTR_RO(max_link_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static ssize_t current_link_speed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u16 linkstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) enum pci_bus_speed speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return sprintf(buf, "%s\n", pci_speed_string(speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static DEVICE_ATTR_RO(current_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static ssize_t current_link_width_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u16 linkstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static DEVICE_ATTR_RO(current_link_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static ssize_t secondary_bus_number_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 sec_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, &sec_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return sprintf(buf, "%u\n", sec_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static DEVICE_ATTR_RO(secondary_bus_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static ssize_t subordinate_bus_number_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u8 sub_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, &sub_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return sprintf(buf, "%u\n", sub_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static DEVICE_ATTR_RO(subordinate_bus_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static ssize_t ari_enabled_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static DEVICE_ATTR_RO(ari_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pci_dev->vendor, pci_dev->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pci_dev->subsystem_vendor, pci_dev->subsystem_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) (u8)(pci_dev->class));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static DEVICE_ATTR_RO(modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ssize_t result = kstrtoul(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* this can crash the machine when done on the "wrong" device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) device_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (dev->driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) result = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else if (pci_is_enabled(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) device_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return result < 0 ? result : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static DEVICE_ATTR_RW(enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static ssize_t numa_node_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int node, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = kstrtoint(buf, 0, &node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (node != NUMA_NO_NODE && !node_online(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pci_alert(pdev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev->numa_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return sprintf(buf, "%d\n", dev->numa_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static DEVICE_ATTR_RW(numa_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static ssize_t dma_mask_bits_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return sprintf(buf, "%d\n", fls64(pdev->dma_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static DEVICE_ATTR_RO(dma_mask_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static ssize_t consistent_dma_mask_bits_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return sprintf(buf, "%d\n", fls64(dev->coherent_dma_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static DEVICE_ATTR_RO(consistent_dma_mask_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct pci_bus *subordinate = pdev->subordinate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return sprintf(buf, "%u\n", subordinate ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) : !pdev->no_msi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct pci_bus *subordinate = pdev->subordinate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * "no_msi" and "bus_flags" only affect what happens when a driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * requests MSI or MSI-X. They don't affect any drivers that have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * already requested MSI or MSI-X.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!subordinate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pdev->no_msi = !val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) pci_info(pdev, "MSI/MSI-X %s for future drivers\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) val ? "allowed" : "disallowed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dev_info(&subordinate->dev, "MSI/MSI-X %s for future drivers of devices on this bus\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) val ? "allowed" : "disallowed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static DEVICE_ATTR_RW(msi_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct pci_bus *b = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) while ((b = pci_find_next_bus(b)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pci_rescan_bus(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static BUS_ATTR_WO(rescan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static struct attribute *pci_bus_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) &bus_attr_rescan.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static const struct attribute_group pci_bus_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .attrs = pci_bus_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) const struct attribute_group *pci_bus_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) &pci_bus_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static ssize_t dev_rescan_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pci_rescan_bus(pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static struct device_attribute dev_attr_dev_rescan = __ATTR(rescan, 0200, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dev_rescan_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (val && device_remove_file_self(dev, attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0220, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) remove_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static ssize_t bus_rescan_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct pci_bus *bus = to_pci_bus(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pci_rescan_bus_bridge_resize(bus->self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) pci_rescan_bus(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static struct device_attribute dev_attr_bus_rescan = __ATTR(rescan, 0200, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) bus_rescan_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #if defined(CONFIG_PM) && defined(CONFIG_ACPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static ssize_t d3cold_allowed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (kstrtoul(buf, 0, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pdev->d3cold_allowed = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (pdev->d3cold_allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pci_d3cold_enable(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) pci_d3cold_disable(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) pm_runtime_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static ssize_t d3cold_allowed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return sprintf(buf, "%u\n", pdev->d3cold_allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static DEVICE_ATTR_RW(d3cold_allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static ssize_t devspec_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct device_node *np = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (np == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return sprintf(buf, "%pOF", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static DEVICE_ATTR_RO(devspec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static ssize_t driver_override_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) char *driver_override, *old, *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* We need to keep extra room for a newline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (count >= (PAGE_SIZE - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) driver_override = kstrndup(buf, count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!driver_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) cp = strchr(driver_override, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) device_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) old = pdev->driver_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (strlen(driver_override)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) pdev->driver_override = driver_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) kfree(driver_override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pdev->driver_override = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) device_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) kfree(old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static ssize_t driver_override_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) device_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) len = scnprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) device_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static DEVICE_ATTR_RW(driver_override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static struct attribute *pci_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) &dev_attr_resource.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) &dev_attr_vendor.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) &dev_attr_device.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) &dev_attr_subsystem_vendor.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) &dev_attr_subsystem_device.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) &dev_attr_revision.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) &dev_attr_class.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) &dev_attr_irq.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) &dev_attr_local_cpus.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) &dev_attr_local_cpulist.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) &dev_attr_modalias.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) &dev_attr_numa_node.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) &dev_attr_dma_mask_bits.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &dev_attr_consistent_dma_mask_bits.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) &dev_attr_enable.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) &dev_attr_broken_parity_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &dev_attr_msi_bus.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #if defined(CONFIG_PM) && defined(CONFIG_ACPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) &dev_attr_d3cold_allowed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) &dev_attr_devspec.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) &dev_attr_driver_override.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) &dev_attr_ari_enabled.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static struct attribute *pci_bridge_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) &dev_attr_subordinate_bus_number.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) &dev_attr_secondary_bus_number.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static struct attribute *pcie_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) &dev_attr_current_link_speed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) &dev_attr_current_link_width.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) &dev_attr_max_link_width.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) &dev_attr_max_link_speed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static struct attribute *pcibus_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) &dev_attr_bus_rescan.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) &dev_attr_cpuaffinity.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) &dev_attr_cpulistaffinity.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static const struct attribute_group pcibus_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .attrs = pcibus_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) const struct attribute_group *pcibus_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) &pcibus_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct pci_dev *vga_dev = vga_default_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (vga_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return sprintf(buf, "%u\n", (pdev == vga_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) !!(pdev->resource[PCI_ROM_RESOURCE].flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) IORESOURCE_ROM_SHADOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static DEVICE_ATTR_RO(boot_vga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned int size = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) loff_t init_off = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u8 *data = (u8 *) buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* Several chips lock up trying to read undefined config space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) size = dev->cfg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) size = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (off > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (off + count > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) size -= off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) count = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) size = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pci_config_pm_runtime_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if ((off & 1) && size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) pci_user_read_config_byte(dev, off, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) data[off - init_off] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if ((off & 3) && size > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) pci_user_read_config_word(dev, off, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) data[off - init_off] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) data[off - init_off + 1] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) off += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) while (size > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pci_user_read_config_dword(dev, off, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) data[off - init_off] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) data[off - init_off + 1] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) data[off - init_off + 2] = (val >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) data[off - init_off + 3] = (val >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) off += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (size >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) pci_user_read_config_word(dev, off, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) data[off - init_off] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) data[off - init_off + 1] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) off += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pci_user_read_config_byte(dev, off, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) data[off - init_off] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) --size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) pci_config_pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) unsigned int size = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) loff_t init_off = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) u8 *data = (u8 *) buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (off > dev->cfg_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (off + count > dev->cfg_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) size = dev->cfg_size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) count = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) pci_config_pm_runtime_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if ((off & 1) && size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) pci_user_write_config_byte(dev, off, data[off - init_off]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if ((off & 3) && size > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u16 val = data[off - init_off];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) val |= (u16) data[off - init_off + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pci_user_write_config_word(dev, off, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) off += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) while (size > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) u32 val = data[off - init_off];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) val |= (u32) data[off - init_off + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) val |= (u32) data[off - init_off + 2] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) val |= (u32) data[off - init_off + 3] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) pci_user_write_config_dword(dev, off, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) off += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (size >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u16 val = data[off - init_off];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) val |= (u16) data[off - init_off + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) pci_user_write_config_word(dev, off, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) off += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pci_user_write_config_byte(dev, off, data[off - init_off]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) --size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) pci_config_pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) #ifdef HAVE_PCI_LEGACY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * pci_read_legacy_io - read byte(s) from legacy I/O port space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * @kobj: kobject corresponding to file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * @bin_attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * @buf: buffer to store results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * @off: offset into legacy I/O port space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * @count: number of bytes to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * callback routine (pci_legacy_read).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static ssize_t pci_read_legacy_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* Only support 1, 2 or 4 byte accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (count != 1 && count != 2 && count != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return pci_legacy_read(bus, off, (u32 *)buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * pci_write_legacy_io - write byte(s) to legacy I/O port space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * @kobj: kobject corresponding to file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * @bin_attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * @buf: buffer containing value to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * @off: offset into legacy I/O port space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * @count: number of bytes to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * callback routine (pci_legacy_write).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static ssize_t pci_write_legacy_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* Only support 1, 2 or 4 byte accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (count != 1 && count != 2 && count != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return pci_legacy_write(bus, off, *(u32 *)buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * @kobj: kobject corresponding to device to be mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * @attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * @vma: struct vm_area_struct passed to mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * legacy memory space (first meg of bus space) into application virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * memory space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static int pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * pci_mmap_legacy_io - map legacy PCI IO into user memory space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * @kobj: kobject corresponding to device to be mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * @attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * @vma: struct vm_area_struct passed to mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * legacy IO space (first meg of bus space) into application virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * memory space. Returns -ENOSYS if the operation isn't supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int pci_mmap_legacy_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * pci_adjust_legacy_attr - adjustment of legacy file attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * @b: bus to create files under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * @mmap_type: I/O port or memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * Stub implementation. Can be overridden by arch if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) void __weak pci_adjust_legacy_attr(struct pci_bus *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) enum pci_mmap_state mmap_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * pci_create_legacy_files - create legacy I/O port and memory files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * @b: bus to create files under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * Some platforms allow access to legacy I/O port and ISA memory space on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * a per-bus basis. This routine creates the files and ties them into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * their associated read, write and mmap files from pci-sysfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * On error unwind, but don't propagate the error to the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * as it is ok to set up the PCI bus without these files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) void pci_create_legacy_files(struct pci_bus *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) b->legacy_io = kcalloc(2, sizeof(struct bin_attribute),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (!b->legacy_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) goto kzalloc_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) sysfs_bin_attr_init(b->legacy_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) b->legacy_io->attr.name = "legacy_io";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) b->legacy_io->size = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) b->legacy_io->attr.mode = 0600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) b->legacy_io->read = pci_read_legacy_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) b->legacy_io->write = pci_write_legacy_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) b->legacy_io->mmap = pci_mmap_legacy_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) pci_adjust_legacy_attr(b, pci_mmap_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) error = device_create_bin_file(&b->dev, b->legacy_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) goto legacy_io_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /* Allocated above after the legacy_io struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) b->legacy_mem = b->legacy_io + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) sysfs_bin_attr_init(b->legacy_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) b->legacy_mem->attr.name = "legacy_mem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) b->legacy_mem->size = 1024*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) b->legacy_mem->attr.mode = 0600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) b->legacy_mem->mmap = pci_mmap_legacy_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) pci_adjust_legacy_attr(b, pci_mmap_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) error = device_create_bin_file(&b->dev, b->legacy_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) goto legacy_mem_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) legacy_mem_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) device_remove_bin_file(&b->dev, b->legacy_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) legacy_io_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) kfree(b->legacy_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) b->legacy_io = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) kzalloc_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev_warn(&b->dev, "could not create legacy I/O port and ISA memory resources in sysfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) void pci_remove_legacy_files(struct pci_bus *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (b->legacy_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) device_remove_bin_file(&b->dev, b->legacy_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) device_remove_bin_file(&b->dev, b->legacy_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) kfree(b->legacy_io); /* both are allocated here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) #endif /* HAVE_PCI_LEGACY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) #if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) enum pci_mmap_api mmap_api)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned long nr, start, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) resource_size_t pci_start = 0, pci_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (pci_resource_len(pdev, resno) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) nr = vma_pages(vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) start = vma->vm_pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (mmap_api == PCI_MMAP_PROCFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) pci_resource_to_user(pdev, resno, &pdev->resource[resno],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) &pci_start, &pci_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pci_start >>= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (start >= pci_start && start < pci_start + size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) start + nr <= pci_start + size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * pci_mmap_resource - map a PCI resource into user memory space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * @kobj: kobject for mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * @attr: struct bin_attribute for the file being mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * @vma: struct vm_area_struct passed into the mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * @write_combine: 1 for write_combine mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * Use the regular PCI mapping routines to map a PCI resource into userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct vm_area_struct *vma, int write_combine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int bar = (unsigned long)attr->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) enum pci_mmap_state mmap_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct resource *res = &pdev->resource[bar];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int pci_mmap_resource_uc(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return pci_mmap_resource(kobj, attr, vma, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static int pci_mmap_resource_wc(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return pci_mmap_resource(kobj, attr, vma, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct bin_attribute *attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) loff_t off, size_t count, bool write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) int bar = (unsigned long)attr->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unsigned long port = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) port += pci_resource_start(pdev, bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (port > pci_resource_end(pdev, bar))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (port + count - 1 > pci_resource_end(pdev, bar))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) switch (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) outb(*(u8 *)buf, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) *(u8 *)buf = inb(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) outw(*(u16 *)buf, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) *(u16 *)buf = inw(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) outl(*(u32 *)buf, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) *(u32 *)buf = inl(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static ssize_t pci_read_resource_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct bin_attribute *attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return pci_resource_io(filp, kobj, attr, buf, off, count, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct bin_attribute *attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return pci_resource_io(filp, kobj, attr, buf, off, count, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * pci_remove_resource_files - cleanup resource files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * @pdev: dev to cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * If we created resource files for @pdev, remove them from sysfs and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * free their resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static void pci_remove_resource_files(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) for (i = 0; i < PCI_STD_NUM_BARS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct bin_attribute *res_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) res_attr = pdev->res_attr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (res_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) kfree(res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) res_attr = pdev->res_attr_wc[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (res_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) kfree(res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /* allocate attribute structure, piggyback attribute name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) int name_len = write_combine ? 13 : 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct bin_attribute *res_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) char *res_attr_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (!res_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) res_attr_name = (char *)(res_attr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) sysfs_bin_attr_init(res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (write_combine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) pdev->res_attr_wc[num] = res_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) sprintf(res_attr_name, "resource%d_wc", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) res_attr->mmap = pci_mmap_resource_wc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) pdev->res_attr[num] = res_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) sprintf(res_attr_name, "resource%d", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) res_attr->read = pci_read_resource_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) res_attr->write = pci_write_resource_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (arch_can_pci_mmap_io())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) res_attr->mmap = pci_mmap_resource_uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) res_attr->mmap = pci_mmap_resource_uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) res_attr->attr.name = res_attr_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) res_attr->attr.mode = 0600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) res_attr->size = pci_resource_len(pdev, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) res_attr->private = (void *)(unsigned long)num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) kfree(res_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * pci_create_resource_files - create resource files in sysfs for @dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * @pdev: dev in question
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * Walk the resources in @pdev creating files for each resource available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static int pci_create_resource_files(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /* Expose the PCI resources from this device as files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) for (i = 0; i < PCI_STD_NUM_BARS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* skip empty resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (!pci_resource_len(pdev, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) retval = pci_create_attr(pdev, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* for prefetchable resources, create a WC mappable file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!retval && arch_can_pci_mmap_wc() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) pdev->resource[i].flags & IORESOURCE_PREFETCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) retval = pci_create_attr(pdev, i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) pci_remove_resource_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) #else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * pci_write_rom - used to enable access to the PCI ROM display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * @filp: sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * @kobj: kernel object handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * @bin_attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * @buf: user input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * @off: file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * @count: number of byte in input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * writing anything except 0 enables it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static ssize_t pci_write_rom(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if ((off == 0) && (*buf == '0') && (count == 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) pdev->rom_attr_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) pdev->rom_attr_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * pci_read_rom - read a PCI ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * @filp: sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * @kobj: kernel object handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * @bin_attr: struct bin_attribute for this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * @buf: where to put the data we read from the ROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * @off: file offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * @count: number of bytes to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * Put @count bytes starting at @off into @buf from the ROM in the PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * device corresponding to @kobj.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) void __iomem *rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (!pdev->rom_attr_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (!rom || !size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (off >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (off + count > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) count = size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) memcpy_fromio(buf, rom + off, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) pci_unmap_rom(pdev, rom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static const struct bin_attribute pci_config_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) .attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .name = "config",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .size = PCI_CFG_SPACE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .read = pci_read_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .write = pci_write_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static const struct bin_attribute pcie_config_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) .name = "config",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .size = PCI_CFG_SPACE_EXP_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .read = pci_read_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .write = pci_write_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ssize_t result = kstrtoul(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (val != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) result = pci_reset_function(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static DEVICE_ATTR(reset, 0200, NULL, reset_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static int pci_create_capabilities_sysfs(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) pcie_vpd_create_sysfs_dev_files(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (dev->reset_fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) retval = device_create_file(&dev->dev, &dev_attr_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) pcie_vpd_remove_sysfs_dev_files(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) int rom_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct bin_attribute *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (!sysfs_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) retval = pci_create_resource_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) goto err_config_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) /* If the device has a ROM, try to expose it in sysfs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (rom_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (!attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) goto err_resource_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) sysfs_bin_attr_init(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) attr->size = rom_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) attr->attr.name = "rom";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) attr->attr.mode = 0600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) attr->read = pci_read_rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) attr->write = pci_write_rom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) kfree(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) goto err_resource_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) pdev->rom_attr = attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* add sysfs entries for various capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) retval = pci_create_capabilities_sysfs(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) goto err_rom_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) pci_create_firmware_label_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) err_rom_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (pdev->rom_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) kfree(pdev->rom_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) pdev->rom_attr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) err_resource_files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) pci_remove_resource_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) err_config_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) pcie_vpd_remove_sysfs_dev_files(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (dev->reset_fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) device_remove_file(&dev->dev, &dev_attr_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) dev->reset_fn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) * @pdev: device whose entries we should free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * Cleanup when @pdev is removed from sysfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (!sysfs_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) pci_remove_capabilities_sysfs(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) pci_remove_resource_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (pdev->rom_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) kfree(pdev->rom_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pdev->rom_attr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) pci_remove_firmware_label_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) static int __init pci_sysfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct pci_dev *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) sysfs_initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) for_each_pci_dev(pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) retval = pci_create_sysfs_dev_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) late_initcall(pci_sysfs_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static struct attribute *pci_dev_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) &dev_attr_boot_vga.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct attribute *a, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (a == &dev_attr_boot_vga.attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static struct attribute *pci_dev_hp_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) &dev_attr_remove.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) &dev_attr_dev_rescan.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) struct attribute *a, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (pdev->is_virtfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static umode_t pci_bridge_attrs_are_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct attribute *a, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (pci_is_bridge(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static umode_t pcie_dev_attrs_are_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct attribute *a, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (pci_is_pcie(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return a->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) static const struct attribute_group pci_dev_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .attrs = pci_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) const struct attribute_group *pci_dev_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) &pci_dev_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static const struct attribute_group pci_dev_hp_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .attrs = pci_dev_hp_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .is_visible = pci_dev_hp_attrs_are_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static const struct attribute_group pci_dev_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) .attrs = pci_dev_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) .is_visible = pci_dev_attrs_are_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) static const struct attribute_group pci_bridge_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .attrs = pci_bridge_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) .is_visible = pci_bridge_attrs_are_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static const struct attribute_group pcie_dev_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) .attrs = pcie_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) .is_visible = pcie_dev_attrs_are_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static const struct attribute_group *pci_dev_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) &pci_dev_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) &pci_dev_hp_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) #ifdef CONFIG_PCI_IOV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) &sriov_dev_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) &pci_bridge_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) &pcie_dev_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) #ifdef CONFIG_PCIEAER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) &aer_stats_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) #ifdef CONFIG_PCIEASPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) &aspm_ctrl_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) const struct device_type pci_dev_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) .groups = pci_dev_attr_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) };