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
8 * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
9 * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
11 * File attributes for PCI devices
13 * Modeled after usb's driverfs.c
18 #include <linux/config.h>
19 #include <linux/kernel.h>
20 #include <linux/pci.h>
21 #include <linux/stat.h>
22 #include <linux/topology.h>
27 static int sysfs_initialized; /* = 0 */
29 /* show configuration fields */
30 #define pci_config_attr(field, format_string) \
32 field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
34 struct pci_dev *pdev; \
36 pdev = to_pci_dev (dev); \
37 return sprintf (buf, format_string, pdev->field); \
40 pci_config_attr(vendor, "0x%04x\n");
41 pci_config_attr(device, "0x%04x\n");
42 pci_config_attr(subsystem_vendor, "0x%04x\n");
43 pci_config_attr(subsystem_device, "0x%04x\n");
44 pci_config_attr(class, "0x%06x\n");
45 pci_config_attr(irq, "%u\n");
46 pci_config_attr(is_enabled, "%u\n");
48 static ssize_t local_cpus_show(struct device *dev,
49 struct device_attribute *attr, char *buf)
54 mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
55 len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
62 resource_show(struct device * dev, struct device_attribute *attr, char * buf)
64 struct pci_dev * pci_dev = to_pci_dev(dev);
70 if (pci_dev->subordinate)
71 max = DEVICE_COUNT_RESOURCE;
73 for (i = 0; i < max; i++) {
74 struct resource *res = &pci_dev->resource[i];
75 pci_resource_to_user(pci_dev, i, res, &start, &end);
76 str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
77 (unsigned long long)start,
78 (unsigned long long)end,
79 (unsigned long long)res->flags);
84 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
86 struct pci_dev *pci_dev = to_pci_dev(dev);
88 return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
89 pci_dev->vendor, pci_dev->device,
90 pci_dev->subsystem_vendor, pci_dev->subsystem_device,
91 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
92 (u8)(pci_dev->class));
95 is_enabled_store(struct device *dev, struct device_attribute *attr,
96 const char *buf, size_t count)
98 struct pci_dev *pdev = to_pci_dev(dev);
100 /* this can crash the machine when done on the "wrong" device */
101 if (!capable(CAP_SYS_ADMIN))
105 pci_disable_device(pdev);
108 pci_enable_device(pdev);
114 struct device_attribute pci_dev_attrs[] = {
118 __ATTR_RO(subsystem_vendor),
119 __ATTR_RO(subsystem_device),
122 __ATTR_RO(local_cpus),
124 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
129 pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
131 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
132 unsigned int size = 64;
133 loff_t init_off = off;
134 u8 *data = (u8*) buf;
136 /* Several chips lock up trying to read undefined config space */
137 if (capable(CAP_SYS_ADMIN)) {
138 size = dev->cfg_size;
139 } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
145 if (off + count > size) {
152 if ((off & 1) && size) {
154 pci_user_read_config_byte(dev, off, &val);
155 data[off - init_off] = val;
160 if ((off & 3) && size > 2) {
162 pci_user_read_config_word(dev, off, &val);
163 data[off - init_off] = val & 0xff;
164 data[off - init_off + 1] = (val >> 8) & 0xff;
171 pci_user_read_config_dword(dev, off, &val);
172 data[off - init_off] = val & 0xff;
173 data[off - init_off + 1] = (val >> 8) & 0xff;
174 data[off - init_off + 2] = (val >> 16) & 0xff;
175 data[off - init_off + 3] = (val >> 24) & 0xff;
182 pci_user_read_config_word(dev, off, &val);
183 data[off - init_off] = val & 0xff;
184 data[off - init_off + 1] = (val >> 8) & 0xff;
191 pci_user_read_config_byte(dev, off, &val);
192 data[off - init_off] = val;
201 pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
203 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
204 unsigned int size = count;
205 loff_t init_off = off;
206 u8 *data = (u8*) buf;
208 if (off > dev->cfg_size)
210 if (off + count > dev->cfg_size) {
211 size = dev->cfg_size - off;
215 if ((off & 1) && size) {
216 pci_user_write_config_byte(dev, off, data[off - init_off]);
221 if ((off & 3) && size > 2) {
222 u16 val = data[off - init_off];
223 val |= (u16) data[off - init_off + 1] << 8;
224 pci_user_write_config_word(dev, off, val);
230 u32 val = data[off - init_off];
231 val |= (u32) data[off - init_off + 1] << 8;
232 val |= (u32) data[off - init_off + 2] << 16;
233 val |= (u32) data[off - init_off + 3] << 24;
234 pci_user_write_config_dword(dev, off, val);
240 u16 val = data[off - init_off];
241 val |= (u16) data[off - init_off + 1] << 8;
242 pci_user_write_config_word(dev, off, val);
248 pci_user_write_config_byte(dev, off, data[off - init_off]);
256 #ifdef HAVE_PCI_LEGACY
258 * pci_read_legacy_io - read byte(s) from legacy I/O port space
259 * @kobj: kobject corresponding to file to read from
260 * @buf: buffer to store results
261 * @off: offset into legacy I/O port space
262 * @count: number of bytes to read
264 * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
265 * callback routine (pci_legacy_read).
268 pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
270 struct pci_bus *bus = to_pci_bus(container_of(kobj,
274 /* Only support 1, 2 or 4 byte accesses */
275 if (count != 1 && count != 2 && count != 4)
278 return pci_legacy_read(bus, off, (u32 *)buf, count);
282 * pci_write_legacy_io - write byte(s) to legacy I/O port space
283 * @kobj: kobject corresponding to file to read from
284 * @buf: buffer containing value to be written
285 * @off: offset into legacy I/O port space
286 * @count: number of bytes to write
288 * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
289 * callback routine (pci_legacy_write).
292 pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
294 struct pci_bus *bus = to_pci_bus(container_of(kobj,
297 /* Only support 1, 2 or 4 byte accesses */
298 if (count != 1 && count != 2 && count != 4)
301 return pci_legacy_write(bus, off, *(u32 *)buf, count);
305 * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
306 * @kobj: kobject corresponding to device to be mapped
307 * @attr: struct bin_attribute for this file
308 * @vma: struct vm_area_struct passed to mmap
310 * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
311 * legacy memory space (first meg of bus space) into application virtual
315 pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
316 struct vm_area_struct *vma)
318 struct pci_bus *bus = to_pci_bus(container_of(kobj,
322 return pci_mmap_legacy_page_range(bus, vma);
324 #endif /* HAVE_PCI_LEGACY */
328 * pci_mmap_resource - map a PCI resource into user memory space
329 * @kobj: kobject for mapping
330 * @attr: struct bin_attribute for the file being mapped
331 * @vma: struct vm_area_struct passed into the mmap
333 * Use the regular PCI mapping routines to map a PCI resource into userspace.
334 * FIXME: write combining? maybe automatic for prefetchable regions?
337 pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
338 struct vm_area_struct *vma)
340 struct pci_dev *pdev = to_pci_dev(container_of(kobj,
341 struct device, kobj));
342 struct resource *res = (struct resource *)attr->private;
343 enum pci_mmap_state mmap_type;
347 for (i = 0; i < PCI_ROM_RESOURCE; i++)
348 if (res == &pdev->resource[i])
350 if (i >= PCI_ROM_RESOURCE)
353 /* pci_mmap_page_range() expects the same kind of entry as coming
354 * from /proc/bus/pci/ which is a "user visible" value. If this is
355 * different from the resource itself, arch will do necessary fixup.
357 pci_resource_to_user(pdev, i, res, &start, &end);
358 vma->vm_pgoff += start >> PAGE_SHIFT;
359 mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
361 return pci_mmap_page_range(pdev, vma, mmap_type, 0);
365 * pci_create_resource_files - create resource files in sysfs for @dev
366 * @dev: dev in question
368 * Walk the resources in @dev creating files for each resource available.
371 pci_create_resource_files(struct pci_dev *pdev)
375 /* Expose the PCI resources from this device as files */
376 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
377 struct bin_attribute *res_attr;
379 /* skip empty resources */
380 if (!pci_resource_len(pdev, i))
383 /* allocate attribute structure, piggyback attribute name */
384 res_attr = kzalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
386 char *res_attr_name = (char *)(res_attr + 1);
388 pdev->res_attr[i] = res_attr;
389 sprintf(res_attr_name, "resource%d", i);
390 res_attr->attr.name = res_attr_name;
391 res_attr->attr.mode = S_IRUSR | S_IWUSR;
392 res_attr->attr.owner = THIS_MODULE;
393 res_attr->size = pci_resource_len(pdev, i);
394 res_attr->mmap = pci_mmap_resource;
395 res_attr->private = &pdev->resource[i];
396 sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
402 * pci_remove_resource_files - cleanup resource files
403 * @dev: dev to cleanup
405 * If we created resource files for @dev, remove them from sysfs and
406 * free their resources.
409 pci_remove_resource_files(struct pci_dev *pdev)
413 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
414 struct bin_attribute *res_attr;
416 res_attr = pdev->res_attr[i];
418 sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
423 #else /* !HAVE_PCI_MMAP */
424 static inline void pci_create_resource_files(struct pci_dev *dev) { return; }
425 static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
426 #endif /* HAVE_PCI_MMAP */
429 * pci_write_rom - used to enable access to the PCI ROM display
430 * @kobj: kernel object handle
433 * @count: number of byte in input
435 * writing anything except 0 enables it
438 pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
440 struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
442 if ((off == 0) && (*buf == '0') && (count == 2))
443 pdev->rom_attr_enabled = 0;
445 pdev->rom_attr_enabled = 1;
451 * pci_read_rom - read a PCI ROM
452 * @kobj: kernel object handle
453 * @buf: where to put the data we read from the ROM
455 * @count: number of bytes to read
457 * Put @count bytes starting at @off into @buf from the ROM in the PCI
458 * device corresponding to @kobj.
461 pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
463 struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
467 if (!pdev->rom_attr_enabled)
470 rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
477 if (off + count > size)
480 memcpy_fromio(buf, rom + off, count);
482 pci_unmap_rom(pdev, rom);
487 static struct bin_attribute pci_config_attr = {
490 .mode = S_IRUGO | S_IWUSR,
491 .owner = THIS_MODULE,
494 .read = pci_read_config,
495 .write = pci_write_config,
498 static struct bin_attribute pcie_config_attr = {
501 .mode = S_IRUGO | S_IWUSR,
502 .owner = THIS_MODULE,
505 .read = pci_read_config,
506 .write = pci_write_config,
509 int pci_create_sysfs_dev_files (struct pci_dev *pdev)
511 if (!sysfs_initialized)
514 if (pdev->cfg_size < 4096)
515 sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
517 sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
519 pci_create_resource_files(pdev);
521 /* If the device has a ROM, try to expose it in sysfs. */
522 if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
523 struct bin_attribute *rom_attr;
525 rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC);
527 pdev->rom_attr = rom_attr;
528 rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
529 rom_attr->attr.name = "rom";
530 rom_attr->attr.mode = S_IRUSR;
531 rom_attr->attr.owner = THIS_MODULE;
532 rom_attr->read = pci_read_rom;
533 rom_attr->write = pci_write_rom;
534 sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
537 /* add platform-specific attributes */
538 pcibios_add_platform_entries(pdev);
544 * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
545 * @pdev: device whose entries we should free
547 * Cleanup when @pdev is removed from sysfs.
549 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
551 if (pdev->cfg_size < 4096)
552 sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
554 sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
556 pci_remove_resource_files(pdev);
558 if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
559 if (pdev->rom_attr) {
560 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
561 kfree(pdev->rom_attr);
566 static int __init pci_sysfs_init(void)
568 struct pci_dev *pdev = NULL;
570 sysfs_initialized = 1;
571 for_each_pci_dev(pdev)
572 pci_create_sysfs_dev_files(pdev);
577 __initcall(pci_sysfs_init);