845 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Purpose: PCI Express Port Bus Driver4 *5 * Copyright (C) 2004 Intel6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)7 */8 9#include <linux/bitfield.h>10#include <linux/dmi.h>11#include <linux/init.h>12#include <linux/module.h>13#include <linux/pci.h>14#include <linux/kernel.h>15#include <linux/errno.h>16#include <linux/pm.h>17#include <linux/pm_runtime.h>18#include <linux/string.h>19#include <linux/slab.h>20#include <linux/aer.h>21 22#include "../pci.h"23#include "portdrv.h"24 25/*26 * The PCIe Capability Interrupt Message Number (PCIe r3.1, sec 7.8.2) must27 * be one of the first 32 MSI-X entries. Per PCI r3.0, sec 6.8.3.1, MSI28 * supports a maximum of 32 vectors per function.29 */30#define PCIE_PORT_MAX_MSI_ENTRIES 3231 32#define get_descriptor_id(type, service) (((type - 4) << 8) | service)33 34struct portdrv_service_data {35 struct pcie_port_service_driver *drv;36 struct device *dev;37 u32 service;38};39 40/**41 * release_pcie_device - free PCI Express port service device structure42 * @dev: Port service device to release43 *44 * Invoked automatically when device is being removed in response to45 * device_unregister(dev). Release all resources being claimed.46 */47static void release_pcie_device(struct device *dev)48{49 kfree(to_pcie_device(dev));50}51 52/*53 * Fill in *pme, *aer, *dpc with the relevant Interrupt Message Numbers if54 * services are enabled in "mask". Return the number of MSI/MSI-X vectors55 * required to accommodate the largest Message Number.56 */57static int pcie_message_numbers(struct pci_dev *dev, int mask,58 u32 *pme, u32 *aer, u32 *dpc)59{60 u32 nvec = 0, pos;61 u16 reg16;62 63 /*64 * The Interrupt Message Number indicates which vector is used, i.e.,65 * the MSI-X table entry or the MSI offset between the base Message66 * Data and the generated interrupt message. See PCIe r3.1, sec67 * 7.8.2, 7.10.10, 7.31.2.68 */69 70 if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |71 PCIE_PORT_SERVICE_BWNOTIF)) {72 pcie_capability_read_word(dev, PCI_EXP_FLAGS, ®16);73 *pme = FIELD_GET(PCI_EXP_FLAGS_IRQ, reg16);74 nvec = *pme + 1;75 }76 77#ifdef CONFIG_PCIEAER78 if (mask & PCIE_PORT_SERVICE_AER) {79 u32 reg32;80 81 pos = dev->aer_cap;82 if (pos) {83 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS,84 ®32);85 *aer = FIELD_GET(PCI_ERR_ROOT_AER_IRQ, reg32);86 nvec = max(nvec, *aer + 1);87 }88 }89#endif90 91 if (mask & PCIE_PORT_SERVICE_DPC) {92 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC);93 if (pos) {94 pci_read_config_word(dev, pos + PCI_EXP_DPC_CAP,95 ®16);96 *dpc = FIELD_GET(PCI_EXP_DPC_IRQ, reg16);97 nvec = max(nvec, *dpc + 1);98 }99 }100 101 return nvec;102}103 104/**105 * pcie_port_enable_irq_vec - try to set up MSI-X or MSI as interrupt mode106 * for given port107 * @dev: PCI Express port to handle108 * @irqs: Array of interrupt vectors to populate109 * @mask: Bitmask of port capabilities returned by get_port_device_capability()110 *111 * Return value: 0 on success, error code on failure112 */113static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask)114{115 int nr_entries, nvec, pcie_irq;116 u32 pme = 0, aer = 0, dpc = 0;117 118 /* Allocate the maximum possible number of MSI/MSI-X vectors */119 nr_entries = pci_alloc_irq_vectors(dev, 1, PCIE_PORT_MAX_MSI_ENTRIES,120 PCI_IRQ_MSIX | PCI_IRQ_MSI);121 if (nr_entries < 0)122 return nr_entries;123 124 /* See how many and which Interrupt Message Numbers we actually use */125 nvec = pcie_message_numbers(dev, mask, &pme, &aer, &dpc);126 if (nvec > nr_entries) {127 pci_free_irq_vectors(dev);128 return -EIO;129 }130 131 /*132 * If we allocated more than we need, free them and reallocate fewer.133 *134 * Reallocating may change the specific vectors we get, so135 * pci_irq_vector() must be done *after* the reallocation.136 *137 * If we're using MSI, hardware is *allowed* to change the Interrupt138 * Message Numbers when we free and reallocate the vectors, but we139 * assume it won't because we allocate enough vectors for the140 * biggest Message Number we found.141 */142 if (nvec != nr_entries) {143 pci_free_irq_vectors(dev);144 145 nr_entries = pci_alloc_irq_vectors(dev, nvec, nvec,146 PCI_IRQ_MSIX | PCI_IRQ_MSI);147 if (nr_entries < 0)148 return nr_entries;149 }150 151 /* PME, hotplug and bandwidth notification share an MSI/MSI-X vector */152 if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |153 PCIE_PORT_SERVICE_BWNOTIF)) {154 pcie_irq = pci_irq_vector(dev, pme);155 irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pcie_irq;156 irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pcie_irq;157 irqs[PCIE_PORT_SERVICE_BWNOTIF_SHIFT] = pcie_irq;158 }159 160 if (mask & PCIE_PORT_SERVICE_AER)161 irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pci_irq_vector(dev, aer);162 163 if (mask & PCIE_PORT_SERVICE_DPC)164 irqs[PCIE_PORT_SERVICE_DPC_SHIFT] = pci_irq_vector(dev, dpc);165 166 return 0;167}168 169/**170 * pcie_init_service_irqs - initialize irqs for PCI Express port services171 * @dev: PCI Express port to handle172 * @irqs: Array of irqs to populate173 * @mask: Bitmask of port capabilities returned by get_port_device_capability()174 *175 * Return value: Interrupt mode associated with the port176 */177static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)178{179 int ret, i;180 181 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)182 irqs[i] = -1;183 184 /*185 * If we support PME but can't use MSI/MSI-X for it, we have to186 * fall back to INTx or other interrupts, e.g., a system shared187 * interrupt.188 */189 if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi())190 goto intx_irq;191 192 /* Try to use MSI-X or MSI if supported */193 if (pcie_port_enable_irq_vec(dev, irqs, mask) == 0)194 return 0;195 196intx_irq:197 /* fall back to INTX IRQ */198 ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX);199 if (ret < 0)200 return -ENODEV;201 202 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)203 irqs[i] = pci_irq_vector(dev, 0);204 205 return 0;206}207 208/**209 * get_port_device_capability - discover capabilities of a PCI Express port210 * @dev: PCI Express port to examine211 *212 * The capabilities are read from the port's PCI Express configuration registers213 * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and214 * 7.9 - 7.11.215 *216 * Return value: Bitmask of discovered port capabilities217 */218static int get_port_device_capability(struct pci_dev *dev)219{220 struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);221 int services = 0;222 223 if (dev->is_hotplug_bridge &&224 (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||225 pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) &&226 (pcie_ports_native || host->native_pcie_hotplug)) {227 services |= PCIE_PORT_SERVICE_HP;228 229 /*230 * Disable hot-plug interrupts in case they have been enabled231 * by the BIOS and the hot-plug service driver is not loaded.232 */233 pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,234 PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);235 }236 237#ifdef CONFIG_PCIEAER238 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||239 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&240 dev->aer_cap && pci_aer_available() &&241 (pcie_ports_native || host->native_aer))242 services |= PCIE_PORT_SERVICE_AER;243#endif244 245 /* Root Ports and Root Complex Event Collectors may generate PMEs */246 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||247 pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) &&248 (pcie_ports_native || host->native_pme)) {249 services |= PCIE_PORT_SERVICE_PME;250 251 /*252 * Disable PME interrupt on this port in case it's been enabled253 * by the BIOS (the PME service driver will enable it when254 * necessary).255 */256 pcie_pme_interrupt_enable(dev, false);257 }258 259 /*260 * With dpc-native, allow Linux to use DPC even if it doesn't have261 * permission to use AER.262 */263 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&264 pci_aer_available() &&265 (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER)))266 services |= PCIE_PORT_SERVICE_DPC;267 268 if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||269 pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {270 u32 linkcap;271 272 pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &linkcap);273 if (linkcap & PCI_EXP_LNKCAP_LBNC)274 services |= PCIE_PORT_SERVICE_BWNOTIF;275 }276 277 return services;278}279 280/**281 * pcie_device_init - allocate and initialize PCI Express port service device282 * @pdev: PCI Express port to associate the service device with283 * @service: Type of service to associate with the service device284 * @irq: Interrupt vector to associate with the service device285 */286static int pcie_device_init(struct pci_dev *pdev, int service, int irq)287{288 int retval;289 struct pcie_device *pcie;290 struct device *device;291 292 pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);293 if (!pcie)294 return -ENOMEM;295 pcie->port = pdev;296 pcie->irq = irq;297 pcie->service = service;298 299 /* Initialize generic device interface */300 device = &pcie->device;301 device->bus = &pcie_port_bus_type;302 device->release = release_pcie_device; /* callback to free pcie dev */303 dev_set_name(device, "%s:pcie%03x",304 pci_name(pdev),305 get_descriptor_id(pci_pcie_type(pdev), service));306 device->parent = &pdev->dev;307 device_enable_async_suspend(device);308 309 retval = device_register(device);310 if (retval) {311 put_device(device);312 return retval;313 }314 315 pm_runtime_no_callbacks(device);316 317 return 0;318}319 320/**321 * pcie_port_device_register - register PCI Express port322 * @dev: PCI Express port to register323 *324 * Allocate the port extension structure and register services associated with325 * the port.326 */327static int pcie_port_device_register(struct pci_dev *dev)328{329 int status, capabilities, i, nr_service;330 int irqs[PCIE_PORT_DEVICE_MAXSERVICES];331 332 /* Enable PCI Express port device */333 status = pci_enable_device(dev);334 if (status)335 return status;336 337 /* Get and check PCI Express port services */338 capabilities = get_port_device_capability(dev);339 if (!capabilities)340 return 0;341 342 pci_set_master(dev);343 /*344 * Initialize service irqs. Don't use service devices that345 * require interrupts if there is no way to generate them.346 * However, some drivers may have a polling mode (e.g. pciehp_poll_mode)347 * that can be used in the absence of irqs. Allow them to determine348 * if that is to be used.349 */350 status = pcie_init_service_irqs(dev, irqs, capabilities);351 if (status) {352 capabilities &= PCIE_PORT_SERVICE_HP;353 if (!capabilities)354 goto error_disable;355 }356 357 /* Allocate child services if any */358 status = -ENODEV;359 nr_service = 0;360 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {361 int service = 1 << i;362 if (!(capabilities & service))363 continue;364 if (!pcie_device_init(dev, service, irqs[i]))365 nr_service++;366 }367 if (!nr_service)368 goto error_cleanup_irqs;369 370 return 0;371 372error_cleanup_irqs:373 pci_free_irq_vectors(dev);374error_disable:375 pci_disable_device(dev);376 return status;377}378 379typedef int (*pcie_callback_t)(struct pcie_device *);380 381static int pcie_port_device_iter(struct device *dev, void *data)382{383 struct pcie_port_service_driver *service_driver;384 size_t offset = *(size_t *)data;385 pcie_callback_t cb;386 387 if ((dev->bus == &pcie_port_bus_type) && dev->driver) {388 service_driver = to_service_driver(dev->driver);389 cb = *(pcie_callback_t *)((void *)service_driver + offset);390 if (cb)391 return cb(to_pcie_device(dev));392 }393 return 0;394}395 396#ifdef CONFIG_PM397/**398 * pcie_port_device_suspend - suspend port services associated with a PCIe port399 * @dev: PCI Express port to handle400 */401static int pcie_port_device_suspend(struct device *dev)402{403 size_t off = offsetof(struct pcie_port_service_driver, suspend);404 return device_for_each_child(dev, &off, pcie_port_device_iter);405}406 407static int pcie_port_device_resume_noirq(struct device *dev)408{409 size_t off = offsetof(struct pcie_port_service_driver, resume_noirq);410 return device_for_each_child(dev, &off, pcie_port_device_iter);411}412 413/**414 * pcie_port_device_resume - resume port services associated with a PCIe port415 * @dev: PCI Express port to handle416 */417static int pcie_port_device_resume(struct device *dev)418{419 size_t off = offsetof(struct pcie_port_service_driver, resume);420 return device_for_each_child(dev, &off, pcie_port_device_iter);421}422 423/**424 * pcie_port_device_runtime_suspend - runtime suspend port services425 * @dev: PCI Express port to handle426 */427static int pcie_port_device_runtime_suspend(struct device *dev)428{429 size_t off = offsetof(struct pcie_port_service_driver, runtime_suspend);430 return device_for_each_child(dev, &off, pcie_port_device_iter);431}432 433/**434 * pcie_port_device_runtime_resume - runtime resume port services435 * @dev: PCI Express port to handle436 */437static int pcie_port_device_runtime_resume(struct device *dev)438{439 size_t off = offsetof(struct pcie_port_service_driver, runtime_resume);440 return device_for_each_child(dev, &off, pcie_port_device_iter);441}442#endif /* PM */443 444static int remove_iter(struct device *dev, void *data)445{446 if (dev->bus == &pcie_port_bus_type)447 device_unregister(dev);448 return 0;449}450 451static int find_service_iter(struct device *device, void *data)452{453 struct pcie_port_service_driver *service_driver;454 struct portdrv_service_data *pdrvs;455 u32 service;456 457 pdrvs = (struct portdrv_service_data *) data;458 service = pdrvs->service;459 460 if (device->bus == &pcie_port_bus_type && device->driver) {461 service_driver = to_service_driver(device->driver);462 if (service_driver->service == service) {463 pdrvs->drv = service_driver;464 pdrvs->dev = device;465 return 1;466 }467 }468 469 return 0;470}471 472/**473 * pcie_port_find_device - find the struct device474 * @dev: PCI Express port the service is associated with475 * @service: For the service to find476 *477 * Find the struct device associated with given service on a pci_dev478 */479struct device *pcie_port_find_device(struct pci_dev *dev,480 u32 service)481{482 struct device *device;483 struct portdrv_service_data pdrvs;484 485 pdrvs.dev = NULL;486 pdrvs.service = service;487 device_for_each_child(&dev->dev, &pdrvs, find_service_iter);488 489 device = pdrvs.dev;490 return device;491}492EXPORT_SYMBOL_GPL(pcie_port_find_device);493 494/**495 * pcie_port_device_remove - unregister PCI Express port service devices496 * @dev: PCI Express port the service devices to unregister are associated with497 *498 * Remove PCI Express port service devices associated with given port and499 * disable MSI-X or MSI for the port.500 */501static void pcie_port_device_remove(struct pci_dev *dev)502{503 device_for_each_child(&dev->dev, NULL, remove_iter);504 pci_free_irq_vectors(dev);505}506 507/**508 * pcie_port_probe_service - probe driver for given PCI Express port service509 * @dev: PCI Express port service device to probe against510 *511 * If PCI Express port service driver is registered with512 * pcie_port_service_register(), this function will be called by the driver core513 * whenever match is found between the driver and a port service device.514 */515static int pcie_port_probe_service(struct device *dev)516{517 struct pcie_device *pciedev;518 struct pcie_port_service_driver *driver;519 int status;520 521 if (!dev || !dev->driver)522 return -ENODEV;523 524 driver = to_service_driver(dev->driver);525 if (!driver || !driver->probe)526 return -ENODEV;527 528 pciedev = to_pcie_device(dev);529 status = driver->probe(pciedev);530 if (status)531 return status;532 533 get_device(dev);534 return 0;535}536 537/**538 * pcie_port_remove_service - detach driver from given PCI Express port service539 * @dev: PCI Express port service device to handle540 *541 * If PCI Express port service driver is registered with542 * pcie_port_service_register(), this function will be called by the driver core543 * when device_unregister() is called for the port service device associated544 * with the driver.545 */546static int pcie_port_remove_service(struct device *dev)547{548 struct pcie_device *pciedev;549 struct pcie_port_service_driver *driver;550 551 if (!dev || !dev->driver)552 return 0;553 554 pciedev = to_pcie_device(dev);555 driver = to_service_driver(dev->driver);556 if (driver && driver->remove) {557 driver->remove(pciedev);558 put_device(dev);559 }560 return 0;561}562 563/**564 * pcie_port_shutdown_service - shut down given PCI Express port service565 * @dev: PCI Express port service device to handle566 *567 * If PCI Express port service driver is registered with568 * pcie_port_service_register(), this function will be called by the driver core569 * when device_shutdown() is called for the port service device associated570 * with the driver.571 */572static void pcie_port_shutdown_service(struct device *dev) {}573 574/**575 * pcie_port_service_register - register PCI Express port service driver576 * @new: PCI Express port service driver to register577 */578int pcie_port_service_register(struct pcie_port_service_driver *new)579{580 if (pcie_ports_disabled)581 return -ENODEV;582 583 new->driver.name = new->name;584 new->driver.bus = &pcie_port_bus_type;585 new->driver.probe = pcie_port_probe_service;586 new->driver.remove = pcie_port_remove_service;587 new->driver.shutdown = pcie_port_shutdown_service;588 589 return driver_register(&new->driver);590}591 592/**593 * pcie_port_service_unregister - unregister PCI Express port service driver594 * @drv: PCI Express port service driver to unregister595 */596void pcie_port_service_unregister(struct pcie_port_service_driver *drv)597{598 driver_unregister(&drv->driver);599}600 601/* If this switch is set, PCIe port native services should not be enabled. */602bool pcie_ports_disabled;603 604/*605 * If the user specified "pcie_ports=native", use the PCIe services regardless606 * of whether the platform has given us permission. On ACPI systems, this607 * means we ignore _OSC.608 */609bool pcie_ports_native;610 611/*612 * If the user specified "pcie_ports=dpc-native", use the Linux DPC PCIe613 * service even if the platform hasn't given us permission.614 */615bool pcie_ports_dpc_native;616 617static int __init pcie_port_setup(char *str)618{619 if (!strncmp(str, "compat", 6))620 pcie_ports_disabled = true;621 else if (!strncmp(str, "native", 6))622 pcie_ports_native = true;623 else if (!strncmp(str, "dpc-native", 10))624 pcie_ports_dpc_native = true;625 626 return 1;627}628__setup("pcie_ports=", pcie_port_setup);629 630/* global data */631 632#ifdef CONFIG_PM633static int pcie_port_runtime_suspend(struct device *dev)634{635 if (!to_pci_dev(dev)->bridge_d3)636 return -EBUSY;637 638 return pcie_port_device_runtime_suspend(dev);639}640 641static int pcie_port_runtime_idle(struct device *dev)642{643 /*644 * Assume the PCI core has set bridge_d3 whenever it thinks the port645 * should be good to go to D3. Everything else, including moving646 * the port to D3, is handled by the PCI core.647 */648 return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY;649}650 651static const struct dev_pm_ops pcie_portdrv_pm_ops = {652 .suspend = pcie_port_device_suspend,653 .resume_noirq = pcie_port_device_resume_noirq,654 .resume = pcie_port_device_resume,655 .freeze = pcie_port_device_suspend,656 .thaw = pcie_port_device_resume,657 .poweroff = pcie_port_device_suspend,658 .restore_noirq = pcie_port_device_resume_noirq,659 .restore = pcie_port_device_resume,660 .runtime_suspend = pcie_port_runtime_suspend,661 .runtime_resume = pcie_port_device_runtime_resume,662 .runtime_idle = pcie_port_runtime_idle,663};664 665#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)666 667#else /* !PM */668 669#define PCIE_PORTDRV_PM_OPS NULL670#endif /* !PM */671 672/*673 * pcie_portdrv_probe - Probe PCI-Express port devices674 * @dev: PCI-Express port device being probed675 *676 * If detected invokes the pcie_port_device_register() method for677 * this port device.678 *679 */680static int pcie_portdrv_probe(struct pci_dev *dev,681 const struct pci_device_id *id)682{683 int type = pci_pcie_type(dev);684 int status;685 686 if (!pci_is_pcie(dev) ||687 ((type != PCI_EXP_TYPE_ROOT_PORT) &&688 (type != PCI_EXP_TYPE_UPSTREAM) &&689 (type != PCI_EXP_TYPE_DOWNSTREAM) &&690 (type != PCI_EXP_TYPE_RC_EC)))691 return -ENODEV;692 693 if (type == PCI_EXP_TYPE_RC_EC)694 pcie_link_rcec(dev);695 696 status = pcie_port_device_register(dev);697 if (status)698 return status;699 700 pci_save_state(dev);701 702 dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE |703 DPM_FLAG_SMART_SUSPEND);704 705 if (pci_bridge_d3_possible(dev)) {706 /*707 * Keep the port resumed 100ms to make sure things like708 * config space accesses from userspace (lspci) will not709 * cause the port to repeatedly suspend and resume.710 */711 pm_runtime_set_autosuspend_delay(&dev->dev, 100);712 pm_runtime_use_autosuspend(&dev->dev);713 pm_runtime_mark_last_busy(&dev->dev);714 pm_runtime_put_autosuspend(&dev->dev);715 pm_runtime_allow(&dev->dev);716 }717 718 return 0;719}720 721static void pcie_portdrv_remove(struct pci_dev *dev)722{723 if (pci_bridge_d3_possible(dev)) {724 pm_runtime_forbid(&dev->dev);725 pm_runtime_get_noresume(&dev->dev);726 pm_runtime_dont_use_autosuspend(&dev->dev);727 }728 729 pcie_port_device_remove(dev);730 731 pci_disable_device(dev);732}733 734static void pcie_portdrv_shutdown(struct pci_dev *dev)735{736 if (pci_bridge_d3_possible(dev)) {737 pm_runtime_forbid(&dev->dev);738 pm_runtime_get_noresume(&dev->dev);739 pm_runtime_dont_use_autosuspend(&dev->dev);740 }741 742 pcie_port_device_remove(dev);743}744 745static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,746 pci_channel_state_t error)747{748 if (error == pci_channel_io_frozen)749 return PCI_ERS_RESULT_NEED_RESET;750 return PCI_ERS_RESULT_CAN_RECOVER;751}752 753static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)754{755 size_t off = offsetof(struct pcie_port_service_driver, slot_reset);756 device_for_each_child(&dev->dev, &off, pcie_port_device_iter);757 758 pci_restore_state(dev);759 pci_save_state(dev);760 return PCI_ERS_RESULT_RECOVERED;761}762 763static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev)764{765 return PCI_ERS_RESULT_RECOVERED;766}767 768/*769 * LINUX Device Driver Model770 */771static const struct pci_device_id port_pci_ids[] = {772 /* handle any PCI-Express port */773 { PCI_DEVICE_CLASS(PCI_CLASS_BRIDGE_PCI_NORMAL, ~0) },774 /* subtractive decode PCI-to-PCI bridge, class type is 060401h */775 { PCI_DEVICE_CLASS(PCI_CLASS_BRIDGE_PCI_SUBTRACTIVE, ~0) },776 /* handle any Root Complex Event Collector */777 { PCI_DEVICE_CLASS(((PCI_CLASS_SYSTEM_RCEC << 8) | 0x00), ~0) },778 { },779};780 781static const struct pci_error_handlers pcie_portdrv_err_handler = {782 .error_detected = pcie_portdrv_error_detected,783 .slot_reset = pcie_portdrv_slot_reset,784 .mmio_enabled = pcie_portdrv_mmio_enabled,785};786 787static struct pci_driver pcie_portdriver = {788 .name = "pcieport",789 .id_table = port_pci_ids,790 791 .probe = pcie_portdrv_probe,792 .remove = pcie_portdrv_remove,793 .shutdown = pcie_portdrv_shutdown,794 795 .err_handler = &pcie_portdrv_err_handler,796 797 .driver_managed_dma = true,798 799 .driver.pm = PCIE_PORTDRV_PM_OPS,800};801 802static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d)803{804 pr_notice("%s detected: will not use MSI for PCIe PME signaling\n",805 d->ident);806 pcie_pme_disable_msi();807 return 0;808}809 810static const struct dmi_system_id pcie_portdrv_dmi_table[] __initconst = {811 /*812 * Boxes that should not use MSI for PCIe PME signaling.813 */814 {815 .callback = dmi_pcie_pme_disable_msi,816 .ident = "MSI Wind U-100",817 .matches = {818 DMI_MATCH(DMI_SYS_VENDOR,819 "MICRO-STAR INTERNATIONAL CO., LTD"),820 DMI_MATCH(DMI_PRODUCT_NAME, "U-100"),821 },822 },823 {}824};825 826static void __init pcie_init_services(void)827{828 pcie_aer_init();829 pcie_pme_init();830 pcie_dpc_init();831 pcie_hp_init();832}833 834static int __init pcie_portdrv_init(void)835{836 if (pcie_ports_disabled)837 return -EACCES;838 839 pcie_init_services();840 dmi_check_system(pcie_portdrv_dmi_table);841 842 return pci_register_driver(&pcie_portdriver);843}844device_initcall(pcie_portdrv_init);845