linux/drivers/pci/pcie/portdrv_core.c
<<
>>
Prefs
   1/*
   2 * File:        portdrv_core.c
   3 * Purpose:     PCI Express Port Bus Driver's Core Functions
   4 *
   5 * Copyright (C) 2004 Intel
   6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/pci.h>
  11#include <linux/kernel.h>
  12#include <linux/errno.h>
  13#include <linux/pm.h>
  14#include <linux/pm_runtime.h>
  15#include <linux/string.h>
  16#include <linux/slab.h>
  17#include <linux/pcieport_if.h>
  18#include <linux/aer.h>
  19
  20#include "../pci.h"
  21#include "portdrv.h"
  22
  23bool pciehp_msi_disabled;
  24
  25static int __init pciehp_setup(char *str)
  26{
  27        if (!strncmp(str, "nomsi", 5))
  28                pciehp_msi_disabled = true;
  29
  30        return 1;
  31}
  32__setup("pcie_hp=", pciehp_setup);
  33
  34/**
  35 * release_pcie_device - free PCI Express port service device structure
  36 * @dev: Port service device to release
  37 *
  38 * Invoked automatically when device is being removed in response to
  39 * device_unregister(dev).  Release all resources being claimed.
  40 */
  41static void release_pcie_device(struct device *dev)
  42{
  43        kfree(to_pcie_device(dev));
  44}
  45
  46/**
  47 * pcie_port_msix_add_entry - add entry to given array of MSI-X entries
  48 * @entries: Array of MSI-X entries
  49 * @new_entry: Index of the entry to add to the array
  50 * @nr_entries: Number of entries already in the array
  51 *
  52 * Return value: Position of the added entry in the array
  53 */
  54static int pcie_port_msix_add_entry(
  55        struct msix_entry *entries, int new_entry, int nr_entries)
  56{
  57        int j;
  58
  59        for (j = 0; j < nr_entries; j++)
  60                if (entries[j].entry == new_entry)
  61                        return j;
  62
  63        entries[j].entry = new_entry;
  64        return j;
  65}
  66
  67/**
  68 * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port
  69 * @dev: PCI Express port to handle
  70 * @vectors: Array of interrupt vectors to populate
  71 * @mask: Bitmask of port capabilities returned by get_port_device_capability()
  72 *
  73 * Return value: 0 on success, error code on failure
  74 */
  75static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
  76{
  77        struct msix_entry *msix_entries;
  78        int idx[PCIE_PORT_DEVICE_MAXSERVICES];
  79        int nr_entries, status, pos, i, nvec;
  80        u16 reg16;
  81        u32 reg32;
  82
  83        nr_entries = pci_msix_vec_count(dev);
  84        if (nr_entries < 0)
  85                return nr_entries;
  86        BUG_ON(!nr_entries);
  87        if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
  88                nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
  89
  90        msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL);
  91        if (!msix_entries)
  92                return -ENOMEM;
  93
  94        /*
  95         * Allocate as many entries as the port wants, so that we can check
  96         * which of them will be useful.  Moreover, if nr_entries is correctly
  97         * equal to the number of entries this port actually uses, we'll happily
  98         * go through without any tricks.
  99         */
 100        for (i = 0; i < nr_entries; i++)
 101                msix_entries[i].entry = i;
 102
 103        status = pci_enable_msix_exact(dev, msix_entries, nr_entries);
 104        if (status)
 105                goto Exit;
 106
 107        for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
 108                idx[i] = -1;
 109        status = -EIO;
 110        nvec = 0;
 111
 112        if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) {
 113                int entry;
 114
 115                /*
 116                 * The code below follows the PCI Express Base Specification 2.0
 117                 * stating in Section 6.1.6 that "PME and Hot-Plug Event
 118                 * interrupts (when both are implemented) always share the same
 119                 * MSI or MSI-X vector, as indicated by the Interrupt Message
 120                 * Number field in the PCI Express Capabilities register", where
 121                 * according to Section 7.8.2 of the specification "For MSI-X,
 122                 * the value in this field indicates which MSI-X Table entry is
 123                 * used to generate the interrupt message."
 124                 */
 125                pcie_capability_read_word(dev, PCI_EXP_FLAGS, &reg16);
 126                entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9;
 127                if (entry >= nr_entries)
 128                        goto Error;
 129
 130                i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
 131                if (i == nvec)
 132                        nvec++;
 133
 134                idx[PCIE_PORT_SERVICE_PME_SHIFT] = i;
 135                idx[PCIE_PORT_SERVICE_HP_SHIFT] = i;
 136        }
 137
 138        if (mask & PCIE_PORT_SERVICE_AER) {
 139                int entry;
 140
 141                /*
 142                 * The code below follows Section 7.10.10 of the PCI Express
 143                 * Base Specification 2.0 stating that bits 31-27 of the Root
 144                 * Error Status Register contain a value indicating which of the
 145                 * MSI/MSI-X vectors assigned to the port is going to be used
 146                 * for AER, where "For MSI-X, the value in this register
 147                 * indicates which MSI-X Table entry is used to generate the
 148                 * interrupt message."
 149                 */
 150                pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 151                pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
 152                entry = reg32 >> 27;
 153                if (entry >= nr_entries)
 154                        goto Error;
 155
 156                i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
 157                if (i == nvec)
 158                        nvec++;
 159
 160                idx[PCIE_PORT_SERVICE_AER_SHIFT] = i;
 161        }
 162
 163        /*
 164         * If nvec is equal to the allocated number of entries, we can just use
 165         * what we have.  Otherwise, the port has some extra entries not for the
 166         * services we know and we need to work around that.
 167         */
 168        if (nvec == nr_entries) {
 169                status = 0;
 170        } else {
 171                /* Drop the temporary MSI-X setup */
 172                pci_disable_msix(dev);
 173
 174                /* Now allocate the MSI-X vectors for real */
 175                status = pci_enable_msix_exact(dev, msix_entries, nvec);
 176                if (status)
 177                        goto Exit;
 178        }
 179
 180        for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
 181                vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1;
 182
 183 Exit:
 184        kfree(msix_entries);
 185        return status;
 186
 187 Error:
 188        pci_disable_msix(dev);
 189        goto Exit;
 190}
 191
 192/**
 193 * init_service_irqs - initialize irqs for PCI Express port services
 194 * @dev: PCI Express port to handle
 195 * @irqs: Array of irqs to populate
 196 * @mask: Bitmask of port capabilities returned by get_port_device_capability()
 197 *
 198 * Return value: Interrupt mode associated with the port
 199 */
 200static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 201{
 202        int i, irq = -1;
 203
 204        /*
 205         * If MSI cannot be used for PCIe PME or hotplug, we have to use
 206         * INTx or other interrupts, e.g. system shared interrupt.
 207         */
 208        if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) ||
 209            ((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) {
 210                if (dev->irq)
 211                        irq = dev->irq;
 212                goto no_msi;
 213        }
 214
 215        /* Try to use MSI-X if supported */
 216        if (!pcie_port_enable_msix(dev, irqs, mask))
 217                return 0;
 218
 219        /*
 220         * We're not going to use MSI-X, so try MSI and fall back to INTx.
 221         * If neither MSI/MSI-X nor INTx available, try other interrupt.  On
 222         * some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
 223         */
 224        if (!pci_enable_msi(dev) || dev->irq)
 225                irq = dev->irq;
 226
 227 no_msi:
 228        for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
 229                irqs[i] = irq;
 230        irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
 231
 232        if (irq < 0)
 233                return -ENODEV;
 234        return 0;
 235}
 236
 237static void cleanup_service_irqs(struct pci_dev *dev)
 238{
 239        if (dev->msix_enabled)
 240                pci_disable_msix(dev);
 241        else if (dev->msi_enabled)
 242                pci_disable_msi(dev);
 243}
 244
 245/**
 246 * get_port_device_capability - discover capabilities of a PCI Express port
 247 * @dev: PCI Express port to examine
 248 *
 249 * The capabilities are read from the port's PCI Express configuration registers
 250 * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and
 251 * 7.9 - 7.11.
 252 *
 253 * Return value: Bitmask of discovered port capabilities
 254 */
 255static int get_port_device_capability(struct pci_dev *dev)
 256{
 257        int services = 0;
 258        u32 reg32;
 259        int cap_mask = 0;
 260
 261        if (pcie_ports_disabled)
 262                return 0;
 263
 264        cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
 265                        | PCIE_PORT_SERVICE_VC;
 266        if (pci_aer_available())
 267                cap_mask |= PCIE_PORT_SERVICE_AER;
 268
 269        if (pcie_ports_auto)
 270                pcie_port_platform_notify(dev, &cap_mask);
 271
 272        /* Hot-Plug Capable */
 273        if ((cap_mask & PCIE_PORT_SERVICE_HP) &&
 274            pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT) {
 275                pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32);
 276                if (reg32 & PCI_EXP_SLTCAP_HPC) {
 277                        services |= PCIE_PORT_SERVICE_HP;
 278                        /*
 279                         * Disable hot-plug interrupts in case they have been
 280                         * enabled by the BIOS and the hot-plug service driver
 281                         * is not loaded.
 282                         */
 283                        pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
 284                                PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
 285                }
 286        }
 287        /* AER capable */
 288        if ((cap_mask & PCIE_PORT_SERVICE_AER)
 289            && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
 290                services |= PCIE_PORT_SERVICE_AER;
 291                /*
 292                 * Disable AER on this port in case it's been enabled by the
 293                 * BIOS (the AER service driver will enable it when necessary).
 294                 */
 295                pci_disable_pcie_error_reporting(dev);
 296        }
 297        /* VC support */
 298        if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
 299                services |= PCIE_PORT_SERVICE_VC;
 300        /* Root ports are capable of generating PME too */
 301        if ((cap_mask & PCIE_PORT_SERVICE_PME)
 302            && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
 303                services |= PCIE_PORT_SERVICE_PME;
 304                /*
 305                 * Disable PME interrupt on this port in case it's been enabled
 306                 * by the BIOS (the PME service driver will enable it when
 307                 * necessary).
 308                 */
 309                pcie_pme_interrupt_enable(dev, false);
 310        }
 311
 312        return services;
 313}
 314
 315/**
 316 * pcie_device_init - allocate and initialize PCI Express port service device
 317 * @pdev: PCI Express port to associate the service device with
 318 * @service: Type of service to associate with the service device
 319 * @irq: Interrupt vector to associate with the service device
 320 */
 321static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
 322{
 323        int retval;
 324        struct pcie_device *pcie;
 325        struct device *device;
 326
 327        pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
 328        if (!pcie)
 329                return -ENOMEM;
 330        pcie->port = pdev;
 331        pcie->irq = irq;
 332        pcie->service = service;
 333
 334        /* Initialize generic device interface */
 335        device = &pcie->device;
 336        device->bus = &pcie_port_bus_type;
 337        device->release = release_pcie_device;  /* callback to free pcie dev */
 338        dev_set_name(device, "%s:pcie%02x",
 339                     pci_name(pdev),
 340                     get_descriptor_id(pci_pcie_type(pdev), service));
 341        device->parent = &pdev->dev;
 342        device_enable_async_suspend(device);
 343
 344        retval = device_register(device);
 345        if (retval) {
 346                put_device(device);
 347                return retval;
 348        }
 349
 350        pm_runtime_no_callbacks(device);
 351
 352        return 0;
 353}
 354
 355/**
 356 * pcie_port_device_register - register PCI Express port
 357 * @dev: PCI Express port to register
 358 *
 359 * Allocate the port extension structure and register services associated with
 360 * the port.
 361 */
 362int pcie_port_device_register(struct pci_dev *dev)
 363{
 364        int status, capabilities, i, nr_service;
 365        int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
 366
 367        /* Enable PCI Express port device */
 368        status = pci_enable_device(dev);
 369        if (status)
 370                return status;
 371
 372        /* Get and check PCI Express port services */
 373        capabilities = get_port_device_capability(dev);
 374        if (!capabilities)
 375                return 0;
 376
 377        pci_set_master(dev);
 378        /*
 379         * Initialize service irqs. Don't use service devices that
 380         * require interrupts if there is no way to generate them.
 381         * However, some drivers may have a polling mode (e.g. pciehp_poll_mode)
 382         * that can be used in the absence of irqs.  Allow them to determine
 383         * if that is to be used.
 384         */
 385        status = init_service_irqs(dev, irqs, capabilities);
 386        if (status) {
 387                capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP;
 388                if (!capabilities)
 389                        goto error_disable;
 390        }
 391
 392        /* Allocate child services if any */
 393        status = -ENODEV;
 394        nr_service = 0;
 395        for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 396                int service = 1 << i;
 397                if (!(capabilities & service))
 398                        continue;
 399                if (!pcie_device_init(dev, service, irqs[i]))
 400                        nr_service++;
 401        }
 402        if (!nr_service)
 403                goto error_cleanup_irqs;
 404
 405        return 0;
 406
 407error_cleanup_irqs:
 408        cleanup_service_irqs(dev);
 409error_disable:
 410        pci_disable_device(dev);
 411        return status;
 412}
 413
 414#ifdef CONFIG_PM
 415static int suspend_iter(struct device *dev, void *data)
 416{
 417        struct pcie_port_service_driver *service_driver;
 418
 419        if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
 420                service_driver = to_service_driver(dev->driver);
 421                if (service_driver->suspend)
 422                        service_driver->suspend(to_pcie_device(dev));
 423        }
 424        return 0;
 425}
 426
 427/**
 428 * pcie_port_device_suspend - suspend port services associated with a PCIe port
 429 * @dev: PCI Express port to handle
 430 */
 431int pcie_port_device_suspend(struct device *dev)
 432{
 433        return device_for_each_child(dev, NULL, suspend_iter);
 434}
 435
 436static int resume_iter(struct device *dev, void *data)
 437{
 438        struct pcie_port_service_driver *service_driver;
 439
 440        if ((dev->bus == &pcie_port_bus_type) &&
 441            (dev->driver)) {
 442                service_driver = to_service_driver(dev->driver);
 443                if (service_driver->resume)
 444                        service_driver->resume(to_pcie_device(dev));
 445        }
 446        return 0;
 447}
 448
 449/**
 450 * pcie_port_device_resume - resume port services associated with a PCIe port
 451 * @dev: PCI Express port to handle
 452 */
 453int pcie_port_device_resume(struct device *dev)
 454{
 455        return device_for_each_child(dev, NULL, resume_iter);
 456}
 457#endif /* PM */
 458
 459static int remove_iter(struct device *dev, void *data)
 460{
 461        if (dev->bus == &pcie_port_bus_type)
 462                device_unregister(dev);
 463        return 0;
 464}
 465
 466/**
 467 * pcie_port_device_remove - unregister PCI Express port service devices
 468 * @dev: PCI Express port the service devices to unregister are associated with
 469 *
 470 * Remove PCI Express port service devices associated with given port and
 471 * disable MSI-X or MSI for the port.
 472 */
 473void pcie_port_device_remove(struct pci_dev *dev)
 474{
 475        device_for_each_child(&dev->dev, NULL, remove_iter);
 476        cleanup_service_irqs(dev);
 477        pci_disable_device(dev);
 478}
 479
 480/**
 481 * pcie_port_probe_service - probe driver for given PCI Express port service
 482 * @dev: PCI Express port service device to probe against
 483 *
 484 * If PCI Express port service driver is registered with
 485 * pcie_port_service_register(), this function will be called by the driver core
 486 * whenever match is found between the driver and a port service device.
 487 */
 488static int pcie_port_probe_service(struct device *dev)
 489{
 490        struct pcie_device *pciedev;
 491        struct pcie_port_service_driver *driver;
 492        int status;
 493
 494        if (!dev || !dev->driver)
 495                return -ENODEV;
 496
 497        driver = to_service_driver(dev->driver);
 498        if (!driver || !driver->probe)
 499                return -ENODEV;
 500
 501        pciedev = to_pcie_device(dev);
 502        status = driver->probe(pciedev);
 503        if (status)
 504                return status;
 505
 506        dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", driver->name);
 507        get_device(dev);
 508        return 0;
 509}
 510
 511/**
 512 * pcie_port_remove_service - detach driver from given PCI Express port service
 513 * @dev: PCI Express port service device to handle
 514 *
 515 * If PCI Express port service driver is registered with
 516 * pcie_port_service_register(), this function will be called by the driver core
 517 * when device_unregister() is called for the port service device associated
 518 * with the driver.
 519 */
 520static int pcie_port_remove_service(struct device *dev)
 521{
 522        struct pcie_device *pciedev;
 523        struct pcie_port_service_driver *driver;
 524
 525        if (!dev || !dev->driver)
 526                return 0;
 527
 528        pciedev = to_pcie_device(dev);
 529        driver = to_service_driver(dev->driver);
 530        if (driver && driver->remove) {
 531                dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
 532                        driver->name);
 533                driver->remove(pciedev);
 534                put_device(dev);
 535        }
 536        return 0;
 537}
 538
 539/**
 540 * pcie_port_shutdown_service - shut down given PCI Express port service
 541 * @dev: PCI Express port service device to handle
 542 *
 543 * If PCI Express port service driver is registered with
 544 * pcie_port_service_register(), this function will be called by the driver core
 545 * when device_shutdown() is called for the port service device associated
 546 * with the driver.
 547 */
 548static void pcie_port_shutdown_service(struct device *dev) {}
 549
 550/**
 551 * pcie_port_service_register - register PCI Express port service driver
 552 * @new: PCI Express port service driver to register
 553 */
 554int pcie_port_service_register(struct pcie_port_service_driver *new)
 555{
 556        if (pcie_ports_disabled)
 557                return -ENODEV;
 558
 559        new->driver.name = new->name;
 560        new->driver.bus = &pcie_port_bus_type;
 561        new->driver.probe = pcie_port_probe_service;
 562        new->driver.remove = pcie_port_remove_service;
 563        new->driver.shutdown = pcie_port_shutdown_service;
 564
 565        return driver_register(&new->driver);
 566}
 567EXPORT_SYMBOL(pcie_port_service_register);
 568
 569/**
 570 * pcie_port_service_unregister - unregister PCI Express port service driver
 571 * @drv: PCI Express port service driver to unregister
 572 */
 573void pcie_port_service_unregister(struct pcie_port_service_driver *drv)
 574{
 575        driver_unregister(&drv->driver);
 576}
 577EXPORT_SYMBOL(pcie_port_service_unregister);
 578