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        int cap_mask = 0;
 259
 260        if (pcie_ports_disabled)
 261                return 0;
 262
 263        cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
 264                        | PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_DPC;
 265        if (pci_aer_available())
 266                cap_mask |= PCIE_PORT_SERVICE_AER;
 267
 268        if (pcie_ports_auto)
 269                pcie_port_platform_notify(dev, &cap_mask);
 270
 271        /* Hot-Plug Capable */
 272        if ((cap_mask & PCIE_PORT_SERVICE_HP) && dev->is_hotplug_bridge) {
 273                services |= PCIE_PORT_SERVICE_HP;
 274                /*
 275                 * Disable hot-plug interrupts in case they have been enabled
 276                 * by the BIOS and the hot-plug service driver is not loaded.
 277                 */
 278                pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
 279                          PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
 280        }
 281        /* AER capable */
 282        if ((cap_mask & PCIE_PORT_SERVICE_AER)
 283            && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
 284                services |= PCIE_PORT_SERVICE_AER;
 285                /*
 286                 * Disable AER on this port in case it's been enabled by the
 287                 * BIOS (the AER service driver will enable it when necessary).
 288                 */
 289                pci_disable_pcie_error_reporting(dev);
 290        }
 291        /* VC support */
 292        if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
 293                services |= PCIE_PORT_SERVICE_VC;
 294        /* Root ports are capable of generating PME too */
 295        if ((cap_mask & PCIE_PORT_SERVICE_PME)
 296            && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
 297                services |= PCIE_PORT_SERVICE_PME;
 298                /*
 299                 * Disable PME interrupt on this port in case it's been enabled
 300                 * by the BIOS (the PME service driver will enable it when
 301                 * necessary).
 302                 */
 303                pcie_pme_interrupt_enable(dev, false);
 304        }
 305        if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC))
 306                services |= PCIE_PORT_SERVICE_DPC;
 307
 308        return services;
 309}
 310
 311/**
 312 * pcie_device_init - allocate and initialize PCI Express port service device
 313 * @pdev: PCI Express port to associate the service device with
 314 * @service: Type of service to associate with the service device
 315 * @irq: Interrupt vector to associate with the service device
 316 */
 317static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
 318{
 319        int retval;
 320        struct pcie_device *pcie;
 321        struct device *device;
 322
 323        pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
 324        if (!pcie)
 325                return -ENOMEM;
 326        pcie->port = pdev;
 327        pcie->irq = irq;
 328        pcie->service = service;
 329
 330        /* Initialize generic device interface */
 331        device = &pcie->device;
 332        device->bus = &pcie_port_bus_type;
 333        device->release = release_pcie_device;  /* callback to free pcie dev */
 334        dev_set_name(device, "%s:pcie%03x",
 335                     pci_name(pdev),
 336                     get_descriptor_id(pci_pcie_type(pdev), service));
 337        device->parent = &pdev->dev;
 338        device_enable_async_suspend(device);
 339
 340        retval = device_register(device);
 341        if (retval) {
 342                put_device(device);
 343                return retval;
 344        }
 345
 346        pm_runtime_no_callbacks(device);
 347
 348        return 0;
 349}
 350
 351/**
 352 * pcie_port_device_register - register PCI Express port
 353 * @dev: PCI Express port to register
 354 *
 355 * Allocate the port extension structure and register services associated with
 356 * the port.
 357 */
 358int pcie_port_device_register(struct pci_dev *dev)
 359{
 360        int status, capabilities, i, nr_service;
 361        int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
 362
 363        /* Enable PCI Express port device */
 364        status = pci_enable_device(dev);
 365        if (status)
 366                return status;
 367
 368        /* Get and check PCI Express port services */
 369        capabilities = get_port_device_capability(dev);
 370        if (!capabilities)
 371                return 0;
 372
 373        pci_set_master(dev);
 374        /*
 375         * Initialize service irqs. Don't use service devices that
 376         * require interrupts if there is no way to generate them.
 377         * However, some drivers may have a polling mode (e.g. pciehp_poll_mode)
 378         * that can be used in the absence of irqs.  Allow them to determine
 379         * if that is to be used.
 380         */
 381        status = init_service_irqs(dev, irqs, capabilities);
 382        if (status) {
 383                capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP;
 384                if (!capabilities)
 385                        goto error_disable;
 386        }
 387
 388        /* Allocate child services if any */
 389        status = -ENODEV;
 390        nr_service = 0;
 391        for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 392                int service = 1 << i;
 393                if (!(capabilities & service))
 394                        continue;
 395                if (!pcie_device_init(dev, service, irqs[i]))
 396                        nr_service++;
 397        }
 398        if (!nr_service)
 399                goto error_cleanup_irqs;
 400
 401        return 0;
 402
 403error_cleanup_irqs:
 404        cleanup_service_irqs(dev);
 405error_disable:
 406        pci_disable_device(dev);
 407        return status;
 408}
 409
 410#ifdef CONFIG_PM
 411static int suspend_iter(struct device *dev, void *data)
 412{
 413        struct pcie_port_service_driver *service_driver;
 414
 415        if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
 416                service_driver = to_service_driver(dev->driver);
 417                if (service_driver->suspend)
 418                        service_driver->suspend(to_pcie_device(dev));
 419        }
 420        return 0;
 421}
 422
 423/**
 424 * pcie_port_device_suspend - suspend port services associated with a PCIe port
 425 * @dev: PCI Express port to handle
 426 */
 427int pcie_port_device_suspend(struct device *dev)
 428{
 429        return device_for_each_child(dev, NULL, suspend_iter);
 430}
 431
 432static int resume_iter(struct device *dev, void *data)
 433{
 434        struct pcie_port_service_driver *service_driver;
 435
 436        if ((dev->bus == &pcie_port_bus_type) &&
 437            (dev->driver)) {
 438                service_driver = to_service_driver(dev->driver);
 439                if (service_driver->resume)
 440                        service_driver->resume(to_pcie_device(dev));
 441        }
 442        return 0;
 443}
 444
 445/**
 446 * pcie_port_device_resume - resume port services associated with a PCIe port
 447 * @dev: PCI Express port to handle
 448 */
 449int pcie_port_device_resume(struct device *dev)
 450{
 451        return device_for_each_child(dev, NULL, resume_iter);
 452}
 453#endif /* PM */
 454
 455static int remove_iter(struct device *dev, void *data)
 456{
 457        if (dev->bus == &pcie_port_bus_type)
 458                device_unregister(dev);
 459        return 0;
 460}
 461
 462/**
 463 * pcie_port_device_remove - unregister PCI Express port service devices
 464 * @dev: PCI Express port the service devices to unregister are associated with
 465 *
 466 * Remove PCI Express port service devices associated with given port and
 467 * disable MSI-X or MSI for the port.
 468 */
 469void pcie_port_device_remove(struct pci_dev *dev)
 470{
 471        device_for_each_child(&dev->dev, NULL, remove_iter);
 472        cleanup_service_irqs(dev);
 473        pci_disable_device(dev);
 474}
 475
 476/**
 477 * pcie_port_probe_service - probe driver for given PCI Express port service
 478 * @dev: PCI Express port service device to probe against
 479 *
 480 * If PCI Express port service driver is registered with
 481 * pcie_port_service_register(), this function will be called by the driver core
 482 * whenever match is found between the driver and a port service device.
 483 */
 484static int pcie_port_probe_service(struct device *dev)
 485{
 486        struct pcie_device *pciedev;
 487        struct pcie_port_service_driver *driver;
 488        int status;
 489
 490        if (!dev || !dev->driver)
 491                return -ENODEV;
 492
 493        driver = to_service_driver(dev->driver);
 494        if (!driver || !driver->probe)
 495                return -ENODEV;
 496
 497        pciedev = to_pcie_device(dev);
 498        status = driver->probe(pciedev);
 499        if (status)
 500                return status;
 501
 502        dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", driver->name);
 503        get_device(dev);
 504        return 0;
 505}
 506
 507/**
 508 * pcie_port_remove_service - detach driver from given PCI Express port service
 509 * @dev: PCI Express port service device to handle
 510 *
 511 * If PCI Express port service driver is registered with
 512 * pcie_port_service_register(), this function will be called by the driver core
 513 * when device_unregister() is called for the port service device associated
 514 * with the driver.
 515 */
 516static int pcie_port_remove_service(struct device *dev)
 517{
 518        struct pcie_device *pciedev;
 519        struct pcie_port_service_driver *driver;
 520
 521        if (!dev || !dev->driver)
 522                return 0;
 523
 524        pciedev = to_pcie_device(dev);
 525        driver = to_service_driver(dev->driver);
 526        if (driver && driver->remove) {
 527                dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
 528                        driver->name);
 529                driver->remove(pciedev);
 530                put_device(dev);
 531        }
 532        return 0;
 533}
 534
 535/**
 536 * pcie_port_shutdown_service - shut down given PCI Express port service
 537 * @dev: PCI Express port service device to handle
 538 *
 539 * If PCI Express port service driver is registered with
 540 * pcie_port_service_register(), this function will be called by the driver core
 541 * when device_shutdown() is called for the port service device associated
 542 * with the driver.
 543 */
 544static void pcie_port_shutdown_service(struct device *dev) {}
 545
 546/**
 547 * pcie_port_service_register - register PCI Express port service driver
 548 * @new: PCI Express port service driver to register
 549 */
 550int pcie_port_service_register(struct pcie_port_service_driver *new)
 551{
 552        if (pcie_ports_disabled)
 553                return -ENODEV;
 554
 555        new->driver.name = new->name;
 556        new->driver.bus = &pcie_port_bus_type;
 557        new->driver.probe = pcie_port_probe_service;
 558        new->driver.remove = pcie_port_remove_service;
 559        new->driver.shutdown = pcie_port_shutdown_service;
 560
 561        return driver_register(&new->driver);
 562}
 563EXPORT_SYMBOL(pcie_port_service_register);
 564
 565/**
 566 * pcie_port_service_unregister - unregister PCI Express port service driver
 567 * @drv: PCI Express port service driver to unregister
 568 */
 569void pcie_port_service_unregister(struct pcie_port_service_driver *drv)
 570{
 571        driver_unregister(&drv->driver);
 572}
 573EXPORT_SYMBOL(pcie_port_service_unregister);
 574