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