2 * drivers/pci/pci-sysfs.c
4 * (C) Copyright 2002-2004 Greg Kroah-Hartman <greg@kroah.com>
5 * (C) Copyright 2002-2004 IBM Corp.
6 * (C) Copyright 2003 Matthew Wilcox
7 * (C) Copyright 2003 Hewlett-Packard
9 * File attributes for PCI devices
11 * Modeled after usb's driverfs.c
16 #include <linux/config.h>
17 #include <linux/kernel.h>
18 #include <linux/pci.h>
19 #include <linux/stat.h>
23 /* show configuration fields */
24 #define pci_config_attr(field, format_string) \
26 show_##field (struct device *dev, char *buf) \
28 struct pci_dev *pdev; \
30 pdev = to_pci_dev (dev); \
31 return sprintf (buf, format_string, pdev->field); \
33 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
35 pci_config_attr(vendor, "0x%04x\n");
36 pci_config_attr(device, "0x%04x\n");
37 pci_config_attr(subsystem_vendor, "0x%04x\n");
38 pci_config_attr(subsystem_device, "0x%04x\n");
39 pci_config_attr(class, "0x%06x\n");
40 pci_config_attr(irq, "%u\n");
44 pci_show_resources(struct device * dev, char * buf)
46 struct pci_dev * pci_dev = to_pci_dev(dev);
51 if (pci_dev->subordinate)
52 max = DEVICE_COUNT_RESOURCE;
54 for (i = 0; i < max; i++) {
55 str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
56 pci_resource_start(pci_dev,i),
57 pci_resource_end(pci_dev,i),
58 pci_resource_flags(pci_dev,i));
63 static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
66 pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
68 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
69 unsigned int size = 64;
70 loff_t init_off = off;
72 /* Several chips lock up trying to read undefined config space */
73 if (capable(CAP_SYS_ADMIN)) {
75 } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
81 if (off + count > size) {
90 pci_read_config_byte(dev, off, &val);
91 buf[off - init_off] = val;
99 pci_read_config_dword(dev, off, &val);
100 buf[off - init_off] = val & 0xff;
101 buf[off - init_off + 1] = (val >> 8) & 0xff;
102 buf[off - init_off + 2] = (val >> 16) & 0xff;
103 buf[off - init_off + 3] = (val >> 24) & 0xff;
110 pci_read_config_byte(dev, off, &val);
111 buf[off - init_off] = val;
120 pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
122 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
123 unsigned int size = count;
124 loff_t init_off = off;
126 if (off > dev->cfg_size)
128 if (off + count > dev->cfg_size) {
129 size = dev->cfg_size - off;
134 pci_write_config_byte(dev, off, buf[off - init_off]);
141 unsigned int val = buf[off - init_off];
142 val |= (unsigned int) buf[off - init_off + 1] << 8;
143 val |= (unsigned int) buf[off - init_off + 2] << 16;
144 val |= (unsigned int) buf[off - init_off + 3] << 24;
145 pci_write_config_dword(dev, off, val);
151 pci_write_config_byte(dev, off, buf[off - init_off]);
159 static struct bin_attribute pci_config_attr = {
162 .mode = S_IRUGO | S_IWUSR,
163 .owner = THIS_MODULE,
166 .read = pci_read_config,
167 .write = pci_write_config,
170 static struct bin_attribute pcie_config_attr = {
173 .mode = S_IRUGO | S_IWUSR,
174 .owner = THIS_MODULE,
177 .read = pci_read_config,
178 .write = pci_write_config,
181 void pci_create_sysfs_dev_files (struct pci_dev *pdev)
183 struct device *dev = &pdev->dev;
185 /* current configuration's attributes */
186 device_create_file (dev, &dev_attr_vendor);
187 device_create_file (dev, &dev_attr_device);
188 device_create_file (dev, &dev_attr_subsystem_vendor);
189 device_create_file (dev, &dev_attr_subsystem_device);
190 device_create_file (dev, &dev_attr_class);
191 device_create_file (dev, &dev_attr_irq);
192 device_create_file (dev, &dev_attr_resource);
194 if (pdev->cfg_size < 4096)
195 sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
197 sysfs_create_bin_file(&dev->kobj, &pcie_config_attr);
199 /* add platform-specific attributes */
200 pcibios_add_platform_entries(pdev);