linux/drivers/pci/pci-sysfs.c
<<
>>
Prefs
   1/*
   2 * drivers/pci/pci-sysfs.c
   3 *
   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>
  10 *
  11 * File attributes for PCI devices
  12 *
  13 * Modeled after usb's driverfs.c 
  14 *
  15 */
  16
  17
  18#include <linux/kernel.h>
  19#include <linux/sched.h>
  20#include <linux/pci.h>
  21#include <linux/stat.h>
  22#include <linux/topology.h>
  23#include <linux/mm.h>
  24#include <linux/fs.h>
  25#include <linux/capability.h>
  26#include <linux/security.h>
  27#include <linux/pci-aspm.h>
  28#include <linux/slab.h>
  29#include "pci.h"
  30
  31static int sysfs_initialized;   /* = 0 */
  32
  33/* show configuration fields */
  34#define pci_config_attr(field, format_string)                           \
  35static ssize_t                                                          \
  36field##_show(struct device *dev, struct device_attribute *attr, char *buf)                              \
  37{                                                                       \
  38        struct pci_dev *pdev;                                           \
  39                                                                        \
  40        pdev = to_pci_dev (dev);                                        \
  41        return sprintf (buf, format_string, pdev->field);               \
  42}
  43
  44pci_config_attr(vendor, "0x%04x\n");
  45pci_config_attr(device, "0x%04x\n");
  46pci_config_attr(subsystem_vendor, "0x%04x\n");
  47pci_config_attr(subsystem_device, "0x%04x\n");
  48pci_config_attr(class, "0x%06x\n");
  49pci_config_attr(irq, "%u\n");
  50
  51static ssize_t broken_parity_status_show(struct device *dev,
  52                                         struct device_attribute *attr,
  53                                         char *buf)
  54{
  55        struct pci_dev *pdev = to_pci_dev(dev);
  56        return sprintf (buf, "%u\n", pdev->broken_parity_status);
  57}
  58
  59static ssize_t broken_parity_status_store(struct device *dev,
  60                                          struct device_attribute *attr,
  61                                          const char *buf, size_t count)
  62{
  63        struct pci_dev *pdev = to_pci_dev(dev);
  64        unsigned long val;
  65
  66        if (strict_strtoul(buf, 0, &val) < 0)
  67                return -EINVAL;
  68
  69        pdev->broken_parity_status = !!val;
  70
  71        return count;
  72}
  73
  74static ssize_t local_cpus_show(struct device *dev,
  75                        struct device_attribute *attr, char *buf)
  76{               
  77        const struct cpumask *mask;
  78        int len;
  79
  80#ifdef CONFIG_NUMA
  81        mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
  82                                          cpumask_of_node(dev_to_node(dev));
  83#else
  84        mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
  85#endif
  86        len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
  87        buf[len++] = '\n';
  88        buf[len] = '\0';
  89        return len;
  90}
  91
  92
  93static ssize_t local_cpulist_show(struct device *dev,
  94                        struct device_attribute *attr, char *buf)
  95{
  96        const struct cpumask *mask;
  97        int len;
  98
  99#ifdef CONFIG_NUMA
 100        mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
 101                                          cpumask_of_node(dev_to_node(dev));
 102#else
 103        mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
 104#endif
 105        len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask);
 106        buf[len++] = '\n';
 107        buf[len] = '\0';
 108        return len;
 109}
 110
 111/* show resources */
 112static ssize_t
 113resource_show(struct device * dev, struct device_attribute *attr, char * buf)
 114{
 115        struct pci_dev * pci_dev = to_pci_dev(dev);
 116        char * str = buf;
 117        int i;
 118        int max;
 119        resource_size_t start, end;
 120
 121        if (pci_dev->subordinate)
 122                max = DEVICE_COUNT_RESOURCE;
 123        else
 124                max = PCI_BRIDGE_RESOURCES;
 125
 126        for (i = 0; i < max; i++) {
 127                struct resource *res =  &pci_dev->resource[i];
 128                pci_resource_to_user(pci_dev, i, res, &start, &end);
 129                str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
 130                               (unsigned long long)start,
 131                               (unsigned long long)end,
 132                               (unsigned long long)res->flags);
 133        }
 134        return (str - buf);
 135}
 136
 137static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 138{
 139        struct pci_dev *pci_dev = to_pci_dev(dev);
 140
 141        return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
 142                       pci_dev->vendor, pci_dev->device,
 143                       pci_dev->subsystem_vendor, pci_dev->subsystem_device,
 144                       (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
 145                       (u8)(pci_dev->class));
 146}
 147
 148static ssize_t is_enabled_store(struct device *dev,
 149                                struct device_attribute *attr, const char *buf,
 150                                size_t count)
 151{
 152        struct pci_dev *pdev = to_pci_dev(dev);
 153        unsigned long val;
 154        ssize_t result = strict_strtoul(buf, 0, &val);
 155
 156        if (result < 0)
 157                return result;
 158
 159        /* this can crash the machine when done on the "wrong" device */
 160        if (!capable(CAP_SYS_ADMIN))
 161                return -EPERM;
 162
 163        if (!val) {
 164                if (pci_is_enabled(pdev))
 165                        pci_disable_device(pdev);
 166                else
 167                        result = -EIO;
 168        } else
 169                result = pci_enable_device(pdev);
 170
 171        return result < 0 ? result : count;
 172}
 173
 174static ssize_t is_enabled_show(struct device *dev,
 175                               struct device_attribute *attr, char *buf)
 176{
 177        struct pci_dev *pdev;
 178
 179        pdev = to_pci_dev (dev);
 180        return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt));
 181}
 182
 183#ifdef CONFIG_NUMA
 184static ssize_t
 185numa_node_show(struct device *dev, struct device_attribute *attr, char *buf)
 186{
 187        return sprintf (buf, "%d\n", dev->numa_node);
 188}
 189#endif
 190
 191static ssize_t
 192dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf)
 193{
 194        struct pci_dev *pdev = to_pci_dev(dev);
 195
 196        return sprintf (buf, "%d\n", fls64(pdev->dma_mask));
 197}
 198
 199static ssize_t
 200consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr,
 201                                 char *buf)
 202{
 203        return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask));
 204}
 205
 206static ssize_t
 207msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
 208{
 209        struct pci_dev *pdev = to_pci_dev(dev);
 210
 211        if (!pdev->subordinate)
 212                return 0;
 213
 214        return sprintf (buf, "%u\n",
 215                        !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI));
 216}
 217
 218static ssize_t
 219msi_bus_store(struct device *dev, struct device_attribute *attr,
 220              const char *buf, size_t count)
 221{
 222        struct pci_dev *pdev = to_pci_dev(dev);
 223        unsigned long val;
 224
 225        if (strict_strtoul(buf, 0, &val) < 0)
 226                return -EINVAL;
 227
 228        /* bad things may happen if the no_msi flag is changed
 229         * while some drivers are loaded */
 230        if (!capable(CAP_SYS_ADMIN))
 231                return -EPERM;
 232
 233        /* Maybe pci devices without subordinate busses shouldn't even have this
 234         * attribute in the first place?  */
 235        if (!pdev->subordinate)
 236                return count;
 237
 238        /* Is the flag going to change, or keep the value it already had? */
 239        if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^
 240            !!val) {
 241                pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI;
 242
 243                dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI,"
 244                         " bad things could happen\n", val ? "" : " not");
 245        }
 246
 247        return count;
 248}
 249
 250#ifdef CONFIG_HOTPLUG
 251static DEFINE_MUTEX(pci_remove_rescan_mutex);
 252static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
 253                                size_t count)
 254{
 255        unsigned long val;
 256        struct pci_bus *b = NULL;
 257
 258        if (strict_strtoul(buf, 0, &val) < 0)
 259                return -EINVAL;
 260
 261        if (val) {
 262                mutex_lock(&pci_remove_rescan_mutex);
 263                while ((b = pci_find_next_bus(b)) != NULL)
 264                        pci_rescan_bus(b);
 265                mutex_unlock(&pci_remove_rescan_mutex);
 266        }
 267        return count;
 268}
 269
 270struct bus_attribute pci_bus_attrs[] = {
 271        __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
 272        __ATTR_NULL
 273};
 274
 275static ssize_t
 276dev_rescan_store(struct device *dev, struct device_attribute *attr,
 277                 const char *buf, size_t count)
 278{
 279        unsigned long val;
 280        struct pci_dev *pdev = to_pci_dev(dev);
 281
 282        if (strict_strtoul(buf, 0, &val) < 0)
 283                return -EINVAL;
 284
 285        if (val) {
 286                mutex_lock(&pci_remove_rescan_mutex);
 287                pci_rescan_bus(pdev->bus);
 288                mutex_unlock(&pci_remove_rescan_mutex);
 289        }
 290        return count;
 291}
 292
 293static void remove_callback(struct device *dev)
 294{
 295        struct pci_dev *pdev = to_pci_dev(dev);
 296
 297        mutex_lock(&pci_remove_rescan_mutex);
 298        pci_remove_bus_device(pdev);
 299        mutex_unlock(&pci_remove_rescan_mutex);
 300}
 301
 302static ssize_t
 303remove_store(struct device *dev, struct device_attribute *dummy,
 304             const char *buf, size_t count)
 305{
 306        int ret = 0;
 307        unsigned long val;
 308
 309        if (strict_strtoul(buf, 0, &val) < 0)
 310                return -EINVAL;
 311
 312        /* An attribute cannot be unregistered by one of its own methods,
 313         * so we have to use this roundabout approach.
 314         */
 315        if (val)
 316                ret = device_schedule_callback(dev, remove_callback);
 317        if (ret)
 318                count = ret;
 319        return count;
 320}
 321#endif
 322
 323struct device_attribute pci_dev_attrs[] = {
 324        __ATTR_RO(resource),
 325        __ATTR_RO(vendor),
 326        __ATTR_RO(device),
 327        __ATTR_RO(subsystem_vendor),
 328        __ATTR_RO(subsystem_device),
 329        __ATTR_RO(class),
 330        __ATTR_RO(irq),
 331        __ATTR_RO(local_cpus),
 332        __ATTR_RO(local_cpulist),
 333        __ATTR_RO(modalias),
 334#ifdef CONFIG_NUMA
 335        __ATTR_RO(numa_node),
 336#endif
 337        __ATTR_RO(dma_mask_bits),
 338        __ATTR_RO(consistent_dma_mask_bits),
 339        __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
 340        __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 341                broken_parity_status_show,broken_parity_status_store),
 342        __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
 343#ifdef CONFIG_HOTPLUG
 344        __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
 345        __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
 346#endif
 347        __ATTR_NULL,
 348};
 349
 350static ssize_t
 351boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
 352{
 353        struct pci_dev *pdev = to_pci_dev(dev);
 354
 355        return sprintf(buf, "%u\n",
 356                !!(pdev->resource[PCI_ROM_RESOURCE].flags &
 357                   IORESOURCE_ROM_SHADOW));
 358}
 359struct device_attribute vga_attr = __ATTR_RO(boot_vga);
 360
 361static ssize_t
 362pci_read_config(struct file *filp, struct kobject *kobj,
 363                struct bin_attribute *bin_attr,
 364                char *buf, loff_t off, size_t count)
 365{
 366        struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 367        unsigned int size = 64;
 368        loff_t init_off = off;
 369        u8 *data = (u8*) buf;
 370
 371        /* Several chips lock up trying to read undefined config space */
 372        if (security_capable(&init_user_ns, filp->f_cred, CAP_SYS_ADMIN) == 0) {
 373                size = dev->cfg_size;
 374        } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
 375                size = 128;
 376        }
 377
 378        if (off > size)
 379                return 0;
 380        if (off + count > size) {
 381                size -= off;
 382                count = size;
 383        } else {
 384                size = count;
 385        }
 386
 387        if ((off & 1) && size) {
 388                u8 val;
 389                pci_user_read_config_byte(dev, off, &val);
 390                data[off - init_off] = val;
 391                off++;
 392                size--;
 393        }
 394
 395        if ((off & 3) && size > 2) {
 396                u16 val;
 397                pci_user_read_config_word(dev, off, &val);
 398                data[off - init_off] = val & 0xff;
 399                data[off - init_off + 1] = (val >> 8) & 0xff;
 400                off += 2;
 401                size -= 2;
 402        }
 403
 404        while (size > 3) {
 405                u32 val;
 406                pci_user_read_config_dword(dev, off, &val);
 407                data[off - init_off] = val & 0xff;
 408                data[off - init_off + 1] = (val >> 8) & 0xff;
 409                data[off - init_off + 2] = (val >> 16) & 0xff;
 410                data[off - init_off + 3] = (val >> 24) & 0xff;
 411                off += 4;
 412                size -= 4;
 413        }
 414
 415        if (size >= 2) {
 416                u16 val;
 417                pci_user_read_config_word(dev, off, &val);
 418                data[off - init_off] = val & 0xff;
 419                data[off - init_off + 1] = (val >> 8) & 0xff;
 420                off += 2;
 421                size -= 2;
 422        }
 423
 424        if (size > 0) {
 425                u8 val;
 426                pci_user_read_config_byte(dev, off, &val);
 427                data[off - init_off] = val;
 428                off++;
 429                --size;
 430        }
 431
 432        return count;
 433}
 434
 435static ssize_t
 436pci_write_config(struct file* filp, struct kobject *kobj,
 437                 struct bin_attribute *bin_attr,
 438                 char *buf, loff_t off, size_t count)
 439{
 440        struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 441        unsigned int size = count;
 442        loff_t init_off = off;
 443        u8 *data = (u8*) buf;
 444
 445        if (off > dev->cfg_size)
 446                return 0;
 447        if (off + count > dev->cfg_size) {
 448                size = dev->cfg_size - off;
 449                count = size;
 450        }
 451        
 452        if ((off & 1) && size) {
 453                pci_user_write_config_byte(dev, off, data[off - init_off]);
 454                off++;
 455                size--;
 456        }
 457        
 458        if ((off & 3) && size > 2) {
 459                u16 val = data[off - init_off];
 460                val |= (u16) data[off - init_off + 1] << 8;
 461                pci_user_write_config_word(dev, off, val);
 462                off += 2;
 463                size -= 2;
 464        }
 465
 466        while (size > 3) {
 467                u32 val = data[off - init_off];
 468                val |= (u32) data[off - init_off + 1] << 8;
 469                val |= (u32) data[off - init_off + 2] << 16;
 470                val |= (u32) data[off - init_off + 3] << 24;
 471                pci_user_write_config_dword(dev, off, val);
 472                off += 4;
 473                size -= 4;
 474        }
 475        
 476        if (size >= 2) {
 477                u16 val = data[off - init_off];
 478                val |= (u16) data[off - init_off + 1] << 8;
 479                pci_user_write_config_word(dev, off, val);
 480                off += 2;
 481                size -= 2;
 482        }
 483
 484        if (size) {
 485                pci_user_write_config_byte(dev, off, data[off - init_off]);
 486                off++;
 487                --size;
 488        }
 489
 490        return count;
 491}
 492
 493static ssize_t
 494read_vpd_attr(struct file *filp, struct kobject *kobj,
 495              struct bin_attribute *bin_attr,
 496              char *buf, loff_t off, size_t count)
 497{
 498        struct pci_dev *dev =
 499                to_pci_dev(container_of(kobj, struct device, kobj));
 500
 501        if (off > bin_attr->size)
 502                count = 0;
 503        else if (count > bin_attr->size - off)
 504                count = bin_attr->size - off;
 505
 506        return pci_read_vpd(dev, off, count, buf);
 507}
 508
 509static ssize_t
 510write_vpd_attr(struct file *filp, struct kobject *kobj,
 511               struct bin_attribute *bin_attr,
 512               char *buf, loff_t off, size_t count)
 513{
 514        struct pci_dev *dev =
 515                to_pci_dev(container_of(kobj, struct device, kobj));
 516
 517        if (off > bin_attr->size)
 518                count = 0;
 519        else if (count > bin_attr->size - off)
 520                count = bin_attr->size - off;
 521
 522        return pci_write_vpd(dev, off, count, buf);
 523}
 524
 525#ifdef HAVE_PCI_LEGACY
 526/**
 527 * pci_read_legacy_io - read byte(s) from legacy I/O port space
 528 * @filp: open sysfs file
 529 * @kobj: kobject corresponding to file to read from
 530 * @bin_attr: struct bin_attribute for this file
 531 * @buf: buffer to store results
 532 * @off: offset into legacy I/O port space
 533 * @count: number of bytes to read
 534 *
 535 * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
 536 * callback routine (pci_legacy_read).
 537 */
 538static ssize_t
 539pci_read_legacy_io(struct file *filp, struct kobject *kobj,
 540                   struct bin_attribute *bin_attr,
 541                   char *buf, loff_t off, size_t count)
 542{
 543        struct pci_bus *bus = to_pci_bus(container_of(kobj,
 544                                                      struct device,
 545                                                      kobj));
 546
 547        /* Only support 1, 2 or 4 byte accesses */
 548        if (count != 1 && count != 2 && count != 4)
 549                return -EINVAL;
 550
 551        return pci_legacy_read(bus, off, (u32 *)buf, count);
 552}
 553
 554/**
 555 * pci_write_legacy_io - write byte(s) to legacy I/O port space
 556 * @filp: open sysfs file
 557 * @kobj: kobject corresponding to file to read from
 558 * @bin_attr: struct bin_attribute for this file
 559 * @buf: buffer containing value to be written
 560 * @off: offset into legacy I/O port space
 561 * @count: number of bytes to write
 562 *
 563 * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
 564 * callback routine (pci_legacy_write).
 565 */
 566static ssize_t
 567pci_write_legacy_io(struct file *filp, struct kobject *kobj,
 568                    struct bin_attribute *bin_attr,
 569                    char *buf, loff_t off, size_t count)
 570{
 571        struct pci_bus *bus = to_pci_bus(container_of(kobj,
 572                                                      struct device,
 573                                                      kobj));
 574        /* Only support 1, 2 or 4 byte accesses */
 575        if (count != 1 && count != 2 && count != 4)
 576                return -EINVAL;
 577
 578        return pci_legacy_write(bus, off, *(u32 *)buf, count);
 579}
 580
 581/**
 582 * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
 583 * @filp: open sysfs file
 584 * @kobj: kobject corresponding to device to be mapped
 585 * @attr: struct bin_attribute for this file
 586 * @vma: struct vm_area_struct passed to mmap
 587 *
 588 * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap
 589 * legacy memory space (first meg of bus space) into application virtual
 590 * memory space.
 591 */
 592static int
 593pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj,
 594                    struct bin_attribute *attr,
 595                    struct vm_area_struct *vma)
 596{
 597        struct pci_bus *bus = to_pci_bus(container_of(kobj,
 598                                                      struct device,
 599                                                      kobj));
 600
 601        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
 602}
 603
 604/**
 605 * pci_mmap_legacy_io - map legacy PCI IO into user memory space
 606 * @filp: open sysfs file
 607 * @kobj: kobject corresponding to device to be mapped
 608 * @attr: struct bin_attribute for this file
 609 * @vma: struct vm_area_struct passed to mmap
 610 *
 611 * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap
 612 * legacy IO space (first meg of bus space) into application virtual
 613 * memory space. Returns -ENOSYS if the operation isn't supported
 614 */
 615static int
 616pci_mmap_legacy_io(struct file *filp, struct kobject *kobj,
 617                   struct bin_attribute *attr,
 618                   struct vm_area_struct *vma)
 619{
 620        struct pci_bus *bus = to_pci_bus(container_of(kobj,
 621                                                      struct device,
 622                                                      kobj));
 623
 624        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
 625}
 626
 627/**
 628 * pci_adjust_legacy_attr - adjustment of legacy file attributes
 629 * @b: bus to create files under
 630 * @mmap_type: I/O port or memory
 631 *
 632 * Stub implementation. Can be overridden by arch if necessary.
 633 */
 634void __weak
 635pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type)
 636{
 637        return;
 638}
 639
 640/**
 641 * pci_create_legacy_files - create legacy I/O port and memory files
 642 * @b: bus to create files under
 643 *
 644 * Some platforms allow access to legacy I/O port and ISA memory space on
 645 * a per-bus basis.  This routine creates the files and ties them into
 646 * their associated read, write and mmap files from pci-sysfs.c
 647 *
 648 * On error unwind, but don't propagate the error to the caller
 649 * as it is ok to set up the PCI bus without these files.
 650 */
 651void pci_create_legacy_files(struct pci_bus *b)
 652{
 653        int error;
 654
 655        b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
 656                               GFP_ATOMIC);
 657        if (!b->legacy_io)
 658                goto kzalloc_err;
 659
 660        sysfs_bin_attr_init(b->legacy_io);
 661        b->legacy_io->attr.name = "legacy_io";
 662        b->legacy_io->size = 0xffff;
 663        b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
 664        b->legacy_io->read = pci_read_legacy_io;
 665        b->legacy_io->write = pci_write_legacy_io;
 666        b->legacy_io->mmap = pci_mmap_legacy_io;
 667        pci_adjust_legacy_attr(b, pci_mmap_io);
 668        error = device_create_bin_file(&b->dev, b->legacy_io);
 669        if (error)
 670                goto legacy_io_err;
 671
 672        /* Allocated above after the legacy_io struct */
 673        b->legacy_mem = b->legacy_io + 1;
 674        sysfs_bin_attr_init(b->legacy_mem);
 675        b->legacy_mem->attr.name = "legacy_mem";
 676        b->legacy_mem->size = 1024*1024;
 677        b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
 678        b->legacy_mem->mmap = pci_mmap_legacy_mem;
 679        pci_adjust_legacy_attr(b, pci_mmap_mem);
 680        error = device_create_bin_file(&b->dev, b->legacy_mem);
 681        if (error)
 682                goto legacy_mem_err;
 683
 684        return;
 685
 686legacy_mem_err:
 687        device_remove_bin_file(&b->dev, b->legacy_io);
 688legacy_io_err:
 689        kfree(b->legacy_io);
 690        b->legacy_io = NULL;
 691kzalloc_err:
 692        printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
 693               "and ISA memory resources to sysfs\n");
 694        return;
 695}
 696
 697void pci_remove_legacy_files(struct pci_bus *b)
 698{
 699        if (b->legacy_io) {
 700                device_remove_bin_file(&b->dev, b->legacy_io);
 701                device_remove_bin_file(&b->dev, b->legacy_mem);
 702                kfree(b->legacy_io); /* both are allocated here */
 703        }
 704}
 705#endif /* HAVE_PCI_LEGACY */
 706
 707#ifdef HAVE_PCI_MMAP
 708
 709int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 710                  enum pci_mmap_api mmap_api)
 711{
 712        unsigned long nr, start, size, pci_start;
 713
 714        if (pci_resource_len(pdev, resno) == 0)
 715                return 0;
 716        nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 717        start = vma->vm_pgoff;
 718        size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
 719        pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
 720                        pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
 721        if (start >= pci_start && start < pci_start + size &&
 722                        start + nr <= pci_start + size)
 723                return 1;
 724        return 0;
 725}
 726
 727/**
 728 * pci_mmap_resource - map a PCI resource into user memory space
 729 * @kobj: kobject for mapping
 730 * @attr: struct bin_attribute for the file being mapped
 731 * @vma: struct vm_area_struct passed into the mmap
 732 * @write_combine: 1 for write_combine mapping
 733 *
 734 * Use the regular PCI mapping routines to map a PCI resource into userspace.
 735 */
 736static int
 737pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 738                  struct vm_area_struct *vma, int write_combine)
 739{
 740        struct pci_dev *pdev = to_pci_dev(container_of(kobj,
 741                                                       struct device, kobj));
 742        struct resource *res = attr->private;
 743        enum pci_mmap_state mmap_type;
 744        resource_size_t start, end;
 745        int i;
 746
 747        for (i = 0; i < PCI_ROM_RESOURCE; i++)
 748                if (res == &pdev->resource[i])
 749                        break;
 750        if (i >= PCI_ROM_RESOURCE)
 751                return -ENODEV;
 752
 753        if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
 754                WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
 755                        "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
 756                        current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
 757                        pci_name(pdev), i,
 758                        (u64)pci_resource_start(pdev, i),
 759                        (u64)pci_resource_len(pdev, i));
 760                return -EINVAL;
 761        }
 762
 763        /* pci_mmap_page_range() expects the same kind of entry as coming
 764         * from /proc/bus/pci/ which is a "user visible" value. If this is
 765         * different from the resource itself, arch will do necessary fixup.
 766         */
 767        pci_resource_to_user(pdev, i, res, &start, &end);
 768        vma->vm_pgoff += start >> PAGE_SHIFT;
 769        mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
 770
 771        if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(start))
 772                return -EINVAL;
 773
 774        return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
 775}
 776
 777static int
 778pci_mmap_resource_uc(struct file *filp, struct kobject *kobj,
 779                     struct bin_attribute *attr,
 780                     struct vm_area_struct *vma)
 781{
 782        return pci_mmap_resource(kobj, attr, vma, 0);
 783}
 784
 785static int
 786pci_mmap_resource_wc(struct file *filp, struct kobject *kobj,
 787                     struct bin_attribute *attr,
 788                     struct vm_area_struct *vma)
 789{
 790        return pci_mmap_resource(kobj, attr, vma, 1);
 791}
 792
 793static ssize_t
 794pci_resource_io(struct file *filp, struct kobject *kobj,
 795                struct bin_attribute *attr, char *buf,
 796                loff_t off, size_t count, bool write)
 797{
 798        struct pci_dev *pdev = to_pci_dev(container_of(kobj,
 799                                                       struct device, kobj));
 800        struct resource *res = attr->private;
 801        unsigned long port = off;
 802        int i;
 803
 804        for (i = 0; i < PCI_ROM_RESOURCE; i++)
 805                if (res == &pdev->resource[i])
 806                        break;
 807        if (i >= PCI_ROM_RESOURCE)
 808                return -ENODEV;
 809
 810        port += pci_resource_start(pdev, i);
 811
 812        if (port > pci_resource_end(pdev, i))
 813                return 0;
 814
 815        if (port + count - 1 > pci_resource_end(pdev, i))
 816                return -EINVAL;
 817
 818        switch (count) {
 819        case 1:
 820                if (write)
 821                        outb(*(u8 *)buf, port);
 822                else
 823                        *(u8 *)buf = inb(port);
 824                return 1;
 825        case 2:
 826                if (write)
 827                        outw(*(u16 *)buf, port);
 828                else
 829                        *(u16 *)buf = inw(port);
 830                return 2;
 831        case 4:
 832                if (write)
 833                        outl(*(u32 *)buf, port);
 834                else
 835                        *(u32 *)buf = inl(port);
 836                return 4;
 837        }
 838        return -EINVAL;
 839}
 840
 841static ssize_t
 842pci_read_resource_io(struct file *filp, struct kobject *kobj,
 843                     struct bin_attribute *attr, char *buf,
 844                     loff_t off, size_t count)
 845{
 846        return pci_resource_io(filp, kobj, attr, buf, off, count, false);
 847}
 848
 849static ssize_t
 850pci_write_resource_io(struct file *filp, struct kobject *kobj,
 851                      struct bin_attribute *attr, char *buf,
 852                      loff_t off, size_t count)
 853{
 854        return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 855}
 856
 857/**
 858 * pci_remove_resource_files - cleanup resource files
 859 * @pdev: dev to cleanup
 860 *
 861 * If we created resource files for @pdev, remove them from sysfs and
 862 * free their resources.
 863 */
 864static void
 865pci_remove_resource_files(struct pci_dev *pdev)
 866{
 867        int i;
 868
 869        for (i = 0; i < PCI_ROM_RESOURCE; i++) {
 870                struct bin_attribute *res_attr;
 871
 872                res_attr = pdev->res_attr[i];
 873                if (res_attr) {
 874                        sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
 875                        kfree(res_attr);
 876                }
 877
 878                res_attr = pdev->res_attr_wc[i];
 879                if (res_attr) {
 880                        sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
 881                        kfree(res_attr);
 882                }
 883        }
 884}
 885
 886static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 887{
 888        /* allocate attribute structure, piggyback attribute name */
 889        int name_len = write_combine ? 13 : 10;
 890        struct bin_attribute *res_attr;
 891        int retval;
 892
 893        res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
 894        if (res_attr) {
 895                char *res_attr_name = (char *)(res_attr + 1);
 896
 897                sysfs_bin_attr_init(res_attr);
 898                if (write_combine) {
 899                        pdev->res_attr_wc[num] = res_attr;
 900                        sprintf(res_attr_name, "resource%d_wc", num);
 901                        res_attr->mmap = pci_mmap_resource_wc;
 902                } else {
 903                        pdev->res_attr[num] = res_attr;
 904                        sprintf(res_attr_name, "resource%d", num);
 905                        res_attr->mmap = pci_mmap_resource_uc;
 906                }
 907                if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
 908                        res_attr->read = pci_read_resource_io;
 909                        res_attr->write = pci_write_resource_io;
 910                }
 911                res_attr->attr.name = res_attr_name;
 912                res_attr->attr.mode = S_IRUSR | S_IWUSR;
 913                res_attr->size = pci_resource_len(pdev, num);
 914                res_attr->private = &pdev->resource[num];
 915                retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
 916        } else
 917                retval = -ENOMEM;
 918
 919        return retval;
 920}
 921
 922/**
 923 * pci_create_resource_files - create resource files in sysfs for @dev
 924 * @pdev: dev in question
 925 *
 926 * Walk the resources in @pdev creating files for each resource available.
 927 */
 928static int pci_create_resource_files(struct pci_dev *pdev)
 929{
 930        int i;
 931        int retval;
 932
 933        /* Expose the PCI resources from this device as files */
 934        for (i = 0; i < PCI_ROM_RESOURCE; i++) {
 935
 936                /* skip empty resources */
 937                if (!pci_resource_len(pdev, i))
 938                        continue;
 939
 940                retval = pci_create_attr(pdev, i, 0);
 941                /* for prefetchable resources, create a WC mappable file */
 942                if (!retval && pdev->resource[i].flags & IORESOURCE_PREFETCH)
 943                        retval = pci_create_attr(pdev, i, 1);
 944
 945                if (retval) {
 946                        pci_remove_resource_files(pdev);
 947                        return retval;
 948                }
 949        }
 950        return 0;
 951}
 952#else /* !HAVE_PCI_MMAP */
 953int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
 954void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
 955#endif /* HAVE_PCI_MMAP */
 956
 957/**
 958 * pci_write_rom - used to enable access to the PCI ROM display
 959 * @filp: sysfs file
 960 * @kobj: kernel object handle
 961 * @bin_attr: struct bin_attribute for this file
 962 * @buf: user input
 963 * @off: file offset
 964 * @count: number of byte in input
 965 *
 966 * writing anything except 0 enables it
 967 */
 968static ssize_t
 969pci_write_rom(struct file *filp, struct kobject *kobj,
 970              struct bin_attribute *bin_attr,
 971              char *buf, loff_t off, size_t count)
 972{
 973        struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
 974
 975        if ((off ==  0) && (*buf == '0') && (count == 2))
 976                pdev->rom_attr_enabled = 0;
 977        else
 978                pdev->rom_attr_enabled = 1;
 979
 980        return count;
 981}
 982
 983/**
 984 * pci_read_rom - read a PCI ROM
 985 * @filp: sysfs file
 986 * @kobj: kernel object handle
 987 * @bin_attr: struct bin_attribute for this file
 988 * @buf: where to put the data we read from the ROM
 989 * @off: file offset
 990 * @count: number of bytes to read
 991 *
 992 * Put @count bytes starting at @off into @buf from the ROM in the PCI
 993 * device corresponding to @kobj.
 994 */
 995static ssize_t
 996pci_read_rom(struct file *filp, struct kobject *kobj,
 997             struct bin_attribute *bin_attr,
 998             char *buf, loff_t off, size_t count)
 999{
1000        struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
1001        void __iomem *rom;
1002        size_t size;
1003
1004        if (!pdev->rom_attr_enabled)
1005                return -EINVAL;
1006        
1007        rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
1008        if (!rom || !size)
1009                return -EIO;
1010                
1011        if (off >= size)
1012                count = 0;
1013        else {
1014                if (off + count > size)
1015                        count = size - off;
1016                
1017                memcpy_fromio(buf, rom + off, count);
1018        }
1019        pci_unmap_rom(pdev, rom);
1020                
1021        return count;
1022}
1023
1024static struct bin_attribute pci_config_attr = {
1025        .attr = {
1026                .name = "config",
1027                .mode = S_IRUGO | S_IWUSR,
1028        },
1029        .size = PCI_CFG_SPACE_SIZE,
1030        .read = pci_read_config,
1031        .write = pci_write_config,
1032};
1033
1034static struct bin_attribute pcie_config_attr = {
1035        .attr = {
1036                .name = "config",
1037                .mode = S_IRUGO | S_IWUSR,
1038        },
1039        .size = PCI_CFG_SPACE_EXP_SIZE,
1040        .read = pci_read_config,
1041        .write = pci_write_config,
1042};
1043
1044int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
1045{
1046        return 0;
1047}
1048
1049static ssize_t reset_store(struct device *dev,
1050                           struct device_attribute *attr, const char *buf,
1051                           size_t count)
1052{
1053        struct pci_dev *pdev = to_pci_dev(dev);
1054        unsigned long val;
1055        ssize_t result = strict_strtoul(buf, 0, &val);
1056
1057        if (result < 0)
1058                return result;
1059
1060        if (val != 1)
1061                return -EINVAL;
1062
1063        result = pci_reset_function(pdev);
1064        if (result < 0)
1065                return result;
1066
1067        return count;
1068}
1069
1070static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store);
1071
1072static int pci_create_capabilities_sysfs(struct pci_dev *dev)
1073{
1074        int retval;
1075        struct bin_attribute *attr;
1076
1077        /* If the device has VPD, try to expose it in sysfs. */
1078        if (dev->vpd) {
1079                attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
1080                if (!attr)
1081                        return -ENOMEM;
1082
1083                sysfs_bin_attr_init(attr);
1084                attr->size = dev->vpd->len;
1085                attr->attr.name = "vpd";
1086                attr->attr.mode = S_IRUSR | S_IWUSR;
1087                attr->read = read_vpd_attr;
1088                attr->write = write_vpd_attr;
1089                retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
1090                if (retval) {
1091                        kfree(attr);
1092                        return retval;
1093                }
1094                dev->vpd->attr = attr;
1095        }
1096
1097        /* Active State Power Management */
1098        pcie_aspm_create_sysfs_dev_files(dev);
1099
1100        if (!pci_probe_reset_function(dev)) {
1101                retval = device_create_file(&dev->dev, &reset_attr);
1102                if (retval)
1103                        goto error;
1104                dev->reset_fn = 1;
1105        }
1106        return 0;
1107
1108error:
1109        pcie_aspm_remove_sysfs_dev_files(dev);
1110        if (dev->vpd && dev->vpd->attr) {
1111                sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
1112                kfree(dev->vpd->attr);
1113        }
1114
1115        return retval;
1116}
1117
1118int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
1119{
1120        int retval;
1121        int rom_size = 0;
1122        struct bin_attribute *attr;
1123
1124        if (!sysfs_initialized)
1125                return -EACCES;
1126
1127        if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
1128                retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
1129        else
1130                retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
1131        if (retval)
1132                goto err;
1133
1134        retval = pci_create_resource_files(pdev);
1135        if (retval)
1136                goto err_config_file;
1137
1138        if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
1139                rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
1140        else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
1141                rom_size = 0x20000;
1142
1143        /* If the device has a ROM, try to expose it in sysfs. */
1144        if (rom_size) {
1145                attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
1146                if (!attr) {
1147                        retval = -ENOMEM;
1148                        goto err_resource_files;
1149                }
1150                sysfs_bin_attr_init(attr);
1151                attr->size = rom_size;
1152                attr->attr.name = "rom";
1153                attr->attr.mode = S_IRUSR | S_IWUSR;
1154                attr->read = pci_read_rom;
1155                attr->write = pci_write_rom;
1156                retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
1157                if (retval) {
1158                        kfree(attr);
1159                        goto err_resource_files;
1160                }
1161                pdev->rom_attr = attr;
1162        }
1163
1164        if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
1165                retval = device_create_file(&pdev->dev, &vga_attr);
1166                if (retval)
1167                        goto err_rom_file;
1168        }
1169
1170        /* add platform-specific attributes */
1171        retval = pcibios_add_platform_entries(pdev);
1172        if (retval)
1173                goto err_vga_file;
1174
1175        /* add sysfs entries for various capabilities */
1176        retval = pci_create_capabilities_sysfs(pdev);
1177        if (retval)
1178                goto err_vga_file;
1179
1180        pci_create_firmware_label_files(pdev);
1181
1182        return 0;
1183
1184err_vga_file:
1185        if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
1186                device_remove_file(&pdev->dev, &vga_attr);
1187err_rom_file:
1188        if (rom_size) {
1189                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
1190                kfree(pdev->rom_attr);
1191                pdev->rom_attr = NULL;
1192        }
1193err_resource_files:
1194        pci_remove_resource_files(pdev);
1195err_config_file:
1196        if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
1197                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
1198        else
1199                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
1200err:
1201        return retval;
1202}
1203
1204static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
1205{
1206        if (dev->vpd && dev->vpd->attr) {
1207                sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
1208                kfree(dev->vpd->attr);
1209        }
1210
1211        pcie_aspm_remove_sysfs_dev_files(dev);
1212        if (dev->reset_fn) {
1213                device_remove_file(&dev->dev, &reset_attr);
1214                dev->reset_fn = 0;
1215        }
1216}
1217
1218/**
1219 * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
1220 * @pdev: device whose entries we should free
1221 *
1222 * Cleanup when @pdev is removed from sysfs.
1223 */
1224void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
1225{
1226        int rom_size = 0;
1227
1228        if (!sysfs_initialized)
1229                return;
1230
1231        pci_remove_capabilities_sysfs(pdev);
1232
1233        if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
1234                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
1235        else
1236                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
1237
1238        pci_remove_resource_files(pdev);
1239
1240        if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
1241                rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
1242        else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
1243                rom_size = 0x20000;
1244
1245        if (rom_size && pdev->rom_attr) {
1246                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
1247                kfree(pdev->rom_attr);
1248        }
1249
1250        pci_remove_firmware_label_files(pdev);
1251
1252}
1253
1254static int __init pci_sysfs_init(void)
1255{
1256        struct pci_dev *pdev = NULL;
1257        int retval;
1258
1259        sysfs_initialized = 1;
1260        for_each_pci_dev(pdev) {
1261                retval = pci_create_sysfs_dev_files(pdev);
1262                if (retval) {
1263                        pci_dev_put(pdev);
1264                        return retval;
1265                }
1266        }
1267
1268        return 0;
1269}
1270
1271late_initcall(pci_sysfs_init);
1272
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.