1/* 2 * File: portdrv_pci.c 3 * Purpose: PCI Express Port Bus Driver 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/init.h> 16#include <linux/pcieport_if.h> 17#include <linux/aer.h> 18#include <linux/dmi.h> 19#include <linux/pci-aspm.h> 20 21#include "portdrv.h" 22#include "aer/aerdrv.h" 23 24/* 25 * Version Information 26 */ 27#define DRIVER_VERSION "v1.0" 28#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" 29#define DRIVER_DESC "PCIe Port Bus Driver" 30MODULE_AUTHOR(DRIVER_AUTHOR); 31MODULE_DESCRIPTION(DRIVER_DESC); 32MODULE_LICENSE("GPL"); 33 34/* If this switch is set, PCIe port native services should not be enabled. */ 35bool pcie_ports_disabled; 36 37/* 38 * If this switch is set, ACPI _OSC will be used to determine whether or not to 39 * enable PCIe port native services. 40 */ 41bool pcie_ports_auto = true; 42 43static int __init pcie_port_setup(char *str) 44{ 45 if (!strncmp(str, "compat", 6)) { 46 pcie_ports_disabled = true; 47 } else if (!strncmp(str, "native", 6)) { 48 pcie_ports_disabled = false; 49 pcie_ports_auto = false; 50 } else if (!strncmp(str, "auto", 4)) { 51 pcie_ports_disabled = false; 52 pcie_ports_auto = true; 53 } 54 55 return 1; 56} 57__setup("pcie_ports=", pcie_port_setup); 58 59/* global data */ 60 61/** 62 * pcie_clear_root_pme_status - Clear root port PME interrupt status. 63 * @dev: PCIe root port or event collector. 64 */ 65void pcie_clear_root_pme_status(struct pci_dev *dev) 66{ 67 pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME); 68} 69 70static int pcie_portdrv_restore_config(struct pci_dev *dev) 71{ 72 int retval; 73 74 retval = pci_enable_device(dev); 75 if (retval) 76 return retval; 77 pci_set_master(dev); 78 return 0; 79} 80 81#ifdef CONFIG_PM 82static int pcie_port_resume_noirq(struct device *dev) 83{ 84 struct pci_dev *pdev = to_pci_dev(dev); 85 86 /* 87 * Some BIOSes forget to clear Root PME Status bits after system wakeup 88 * which breaks ACPI-based runtime wakeup on PCI Express, so clear those 89 * bits now just in case (shouldn't hurt). 90 */ 91 if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) 92 pcie_clear_root_pme_status(pdev); 93 return 0; 94} 95 96static const struct dev_pm_ops pcie_portdrv_pm_ops = { 97 .suspend = pcie_port_device_suspend, 98 .resume = pcie_port_device_resume, 99 .freeze = pcie_port_device_suspend, 100 .thaw = pcie_port_device_resume, 101 .poweroff = pcie_port_device_suspend, 102 .restore = pcie_port_device_resume, 103 .resume_noirq = pcie_port_resume_noirq, 104}; 105 106#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) 107 108#else /* !PM */ 109 110#define PCIE_PORTDRV_PM_OPS NULL 111#endif /* !PM */ 112 113/* 114 * pcie_portdrv_probe - Probe PCI-Express port devices 115 * @dev: PCI-Express port device being probed 116 * 117 * If detected invokes the pcie_port_device_register() method for 118 * this port device. 119 * 120 */ 121static int pcie_portdrv_probe(struct pci_dev *dev, 122 const struct pci_device_id *id) 123{ 124 int status; 125 126 if (!pci_is_pcie(dev) || 127 ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && 128 (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) && 129 (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) 130 return -ENODEV; 131 132 status = pcie_port_device_register(dev); 133 if (status) 134 return status; 135 136 pci_save_state(dev); 137 /* 138 * D3cold may not work properly on some PCIe port, so disable 139 * it by default. 140 */ 141 dev->d3cold_allowed = false; 142 return 0; 143} 144 145static void pcie_portdrv_remove(struct pci_dev *dev) 146{ 147 pcie_port_device_remove(dev); 148} 149 150static int error_detected_iter(struct device *device, void *data) 151{ 152 struct pcie_device *pcie_device; 153 struct pcie_port_service_driver *driver; 154 struct aer_broadcast_data *result_data; 155 pci_ers_result_t status; 156 157 result_data = (struct aer_broadcast_data *) data; 158 159 if (device->bus == &pcie_port_bus_type && device->driver) { 160 driver = to_service_driver(device->driver); 161 if (!driver || 162 !driver->err_handler || 163 !driver->err_handler->error_detected) 164 return 0; 165 166 pcie_device = to_pcie_device(device); 167 168 /* Forward error detected message to service drivers */ 169 status = driver->err_handler->error_detected( 170 pcie_device->port, 171 result_data->state); 172 result_data->result = 173 merge_result(result_data->result, status); 174 } 175 176 return 0; 177} 178 179static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, 180 enum pci_channel_state error) 181{ 182 struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; 183 184 /* get true return value from &data */ 185 device_for_each_child(&dev->dev, &data, error_detected_iter); 186 return data.result; 187} 188 189static int mmio_enabled_iter(struct device *device, void *data) 190{ 191 struct pcie_device *pcie_device; 192 struct pcie_port_service_driver *driver; 193 pci_ers_result_t status, *result; 194 195 result = (pci_ers_result_t *) data; 196 197 if (device->bus == &pcie_port_bus_type && device->driver) { 198 driver = to_service_driver(device->driver); 199 if (driver && 200 driver->err_handler && 201 driver->err_handler->mmio_enabled) { 202 pcie_device = to_pcie_device(device); 203 204 /* Forward error message to service drivers */ 205 status = driver->err_handler->mmio_enabled( 206 pcie_device->port); 207 *result = merge_result(*result, status); 208 } 209 } 210 211 return 0; 212} 213 214static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) 215{ 216 pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; 217 218 /* get true return value from &status */ 219 device_for_each_child(&dev->dev, &status, mmio_enabled_iter); 220 return status; 221} 222 223static int slot_reset_iter(struct device *device, void *data) 224{ 225 struct pcie_device *pcie_device; 226 struct pcie_port_service_driver *driver; 227 pci_ers_result_t status, *result; 228 229 result = (pci_ers_result_t *) data; 230 231 if (device->bus == &pcie_port_bus_type && device->driver) { 232 driver = to_service_driver(device->driver); 233 if (driver && 234 driver->err_handler && 235 driver->err_handler->slot_reset) { 236 pcie_device = to_pcie_device(device); 237 238 /* Forward error message to service drivers */ 239 status = driver->err_handler->slot_reset( 240 pcie_device->port); 241 *result = merge_result(*result, status); 242 } 243 } 244 245 return 0; 246} 247 248static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) 249{ 250 pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; 251 252 /* If fatal, restore cfg space for possible link reset at upstream */ 253 if (dev->error_state == pci_channel_io_frozen) { 254 dev->state_saved = true; 255 pci_restore_state(dev); 256 pcie_portdrv_restore_config(dev); 257 pci_enable_pcie_error_reporting(dev); 258 } 259 260 /* get true return value from &status */ 261 device_for_each_child(&dev->dev, &status, slot_reset_iter); 262 return status; 263} 264 265static int resume_iter(struct device *device, void *data) 266{ 267 struct pcie_device *pcie_device; 268 struct pcie_port_service_driver *driver; 269 270 if (device->bus == &pcie_port_bus_type && device->driver) { 271 driver = to_service_driver(device->driver); 272 if (driver && 273 driver->err_handler && 274 driver->err_handler->resume) { 275 pcie_device = to_pcie_device(device); 276 277 /* Forward error message to service drivers */ 278 driver->err_handler->resume(pcie_device->port); 279 } 280 } 281 282 return 0; 283} 284 285static void pcie_portdrv_err_resume(struct pci_dev *dev) 286{ 287 device_for_each_child(&dev->dev, NULL, resume_iter); 288} 289 290/* 291 * LINUX Device Driver Model 292 */ 293static const struct pci_device_id port_pci_ids[] = { { 294 /* handle any PCI-Express port */ 295 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), 296 }, { /* end: all zeroes */ } 297}; 298MODULE_DEVICE_TABLE(pci, port_pci_ids); 299 300static const struct pci_error_handlers pcie_portdrv_err_handler = { 301 .error_detected = pcie_portdrv_error_detected, 302 .mmio_enabled = pcie_portdrv_mmio_enabled, 303 .slot_reset = pcie_portdrv_slot_reset, 304 .resume = pcie_portdrv_err_resume, 305}; 306 307static struct pci_driver pcie_portdriver = { 308 .name = "pcieport", 309 .id_table = &port_pci_ids[0], 310 311 .probe = pcie_portdrv_probe, 312 .remove = pcie_portdrv_remove, 313 314 .err_handler = &pcie_portdrv_err_handler, 315 316 .driver.pm = PCIE_PORTDRV_PM_OPS, 317}; 318 319static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d) 320{ 321 pr_notice("%s detected: will not use MSI for PCIe PME signaling\n", 322 d->ident); 323 pcie_pme_disable_msi(); 324 return 0; 325} 326 327static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = { 328 /* 329 * Boxes that should not use MSI for PCIe PME signaling. 330 */ 331 { 332 .callback = dmi_pcie_pme_disable_msi, 333 .ident = "MSI Wind U-100", 334 .matches = { 335 DMI_MATCH(DMI_SYS_VENDOR, 336 "MICRO-STAR INTERNATIONAL CO., LTD"), 337 DMI_MATCH(DMI_PRODUCT_NAME, "U-100"), 338 }, 339 }, 340 {} 341}; 342 343static int __init pcie_portdrv_init(void) 344{ 345 int retval; 346 347 if (pcie_ports_disabled) 348 return pci_register_driver(&pcie_portdriver); 349 350 dmi_check_system(pcie_portdrv_dmi_table); 351 352 retval = pcie_port_bus_register(); 353 if (retval) { 354 printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); 355 goto out; 356 } 357 retval = pci_register_driver(&pcie_portdriver); 358 if (retval) 359 pcie_port_bus_unregister(); 360 out: 361 return retval; 362} 363 364module_init(pcie_portdrv_init); 365