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