1 /* 2 * PCI Express Hot Plug Controller Driver 3 * 4 * Copyright (C) 1995,2001 Compaq Computer Corporation 5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 * Copyright (C) 2001 IBM Corp. 7 * Copyright (C) 2003-2004 Intel Corporation 8 * 9 * All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or (at 14 * your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 * NON INFRINGEMENT. See the GNU General Public License for more 20 * details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 27 * 28 */ 29 30 #include <linux/module.h> 31 #include <linux/moduleparam.h> 32 #include <linux/kernel.h> 33 #include <linux/types.h> 34 #include <linux/pci.h> 35 #include "pciehp.h" 36 #include <linux/interrupt.h> 37 38 /* Global variables */ 39 int pciehp_debug; 40 int pciehp_poll_mode; 41 int pciehp_poll_time; 42 int pciehp_force; 43 struct controller *pciehp_ctrl_list; 44 45 #define DRIVER_VERSION "0.4" 46 #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" 47 #define DRIVER_DESC "PCI Express Hot Plug Controller Driver" 48 49 MODULE_AUTHOR(DRIVER_AUTHOR); 50 MODULE_DESCRIPTION(DRIVER_DESC); 51 MODULE_LICENSE("GPL"); 52 53 module_param(pciehp_debug, bool, 0644); 54 module_param(pciehp_poll_mode, bool, 0644); 55 module_param(pciehp_poll_time, int, 0644); 56 module_param(pciehp_force, bool, 0644); 57 MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 58 MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 59 MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 60 MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); 61 62 #define PCIE_MODULE_NAME "pciehp" 63 64 static int pcie_start_thread (void); 65 static int set_attention_status (struct hotplug_slot *slot, u8 value); 66 static int enable_slot (struct hotplug_slot *slot); 67 static int disable_slot (struct hotplug_slot *slot); 68 static int get_power_status (struct hotplug_slot *slot, u8 *value); 69 static int get_attention_status (struct hotplug_slot *slot, u8 *value); 70 static int get_latch_status (struct hotplug_slot *slot, u8 *value); 71 static int get_adapter_status (struct hotplug_slot *slot, u8 *value); 72 static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); 73 static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); 74 75 static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { 76 .owner = THIS_MODULE, 77 .set_attention_status = set_attention_status, 78 .enable_slot = enable_slot, 79 .disable_slot = disable_slot, 80 .get_power_status = get_power_status, 81 .get_attention_status = get_attention_status, 82 .get_latch_status = get_latch_status, 83 .get_adapter_status = get_adapter_status, 84 .get_max_bus_speed = get_max_bus_speed, 85 .get_cur_bus_speed = get_cur_bus_speed, 86 }; 87 88 /** 89 * release_slot - free up the memory used by a slot 90 * @hotplug_slot: slot to free 91 */ 92 static void release_slot(struct hotplug_slot *hotplug_slot) 93 { 94 struct slot *slot = hotplug_slot->private; 95 96 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 97 98 kfree(slot->hotplug_slot->info); 99 kfree(slot->hotplug_slot->name); 100 kfree(slot->hotplug_slot); 101 kfree(slot); 102 } 103 104 static int init_slots(struct controller *ctrl) 105 { 106 struct slot *new_slot; 107 u8 number_of_slots; 108 u8 slot_device; 109 u32 slot_number; 110 int result = -ENOMEM; 111 112 number_of_slots = ctrl->num_slots; 113 slot_device = ctrl->slot_device_offset; 114 slot_number = ctrl->first_slot; 115 116 while (number_of_slots) { 117 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL); 118 if (!new_slot) 119 goto error; 120 121 memset(new_slot, 0, sizeof(struct slot)); 122 new_slot->hotplug_slot = 123 kmalloc(sizeof(*(new_slot->hotplug_slot)), 124 GFP_KERNEL); 125 if (!new_slot->hotplug_slot) 126 goto error_slot; 127 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot)); 128 129 new_slot->hotplug_slot->info = 130 kmalloc(sizeof(*(new_slot->hotplug_slot->info)), 131 GFP_KERNEL); 132 if (!new_slot->hotplug_slot->info) 133 goto error_hpslot; 134 memset(new_slot->hotplug_slot->info, 0, 135 sizeof(struct hotplug_slot_info)); 136 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, 137 GFP_KERNEL); 138 if (!new_slot->hotplug_slot->name) 139 goto error_info; 140 141 new_slot->ctrl = ctrl; 142 new_slot->bus = ctrl->slot_bus; 143 new_slot->device = slot_device; 144 new_slot->hpc_ops = ctrl->hpc_ops; 145 146 new_slot->number = ctrl->first_slot; 147 new_slot->hp_slot = slot_device - ctrl->slot_device_offset; 148 149 /* register this slot with the hotplug pci core */ 150 new_slot->hotplug_slot->private = new_slot; 151 new_slot->hotplug_slot->release = &release_slot; 152 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); 153 new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops; 154 155 new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status)); 156 new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status)); 157 new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status)); 158 new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status)); 159 160 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", 161 new_slot->bus, new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset); 162 result = pci_hp_register (new_slot->hotplug_slot); 163 if (result) { 164 err ("pci_hp_register failed with error %d\n", result); 165 goto error_name; 166 } 167 168 new_slot->next = ctrl->slot; 169 ctrl->slot = new_slot; 170 171 number_of_slots--; 172 slot_device++; 173 slot_number += ctrl->slot_num_inc; 174 } 175 176 return 0; 177 178 error_name: 179 kfree(new_slot->hotplug_slot->name); 180 error_info: 181 kfree(new_slot->hotplug_slot->info); 182 error_hpslot: 183 kfree(new_slot->hotplug_slot); 184 error_slot: 185 kfree(new_slot); 186 error: 187 return result; 188 } 189 190 191 static int cleanup_slots (struct controller * ctrl) 192 { 193 struct slot *old_slot, *next_slot; 194 195 old_slot = ctrl->slot; 196 ctrl->slot = NULL; 197 198 while (old_slot) { 199 next_slot = old_slot->next; 200 pci_hp_deregister (old_slot->hotplug_slot); 201 old_slot = next_slot; 202 } 203 204 205 return(0); 206 } 207 208 static int get_ctlr_slot_config(struct controller *ctrl) 209 { 210 int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/ 211 int first_device_num; /* Not needed */ 212 int physical_slot_num; 213 u8 ctrlcap; 214 int rc; 215 216 rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap); 217 if (rc) { 218 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); 219 return (-1); 220 } 221 222 ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */ 223 ctrl->slot_device_offset = first_device_num; 224 ctrl->first_slot = physical_slot_num; 225 ctrl->ctrlcap = ctrlcap; 226 227 dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n", 228 __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, 229 ctrl->bus, ctrl->device); 230 231 return (0); 232 } 233 234 235 /* 236 * set_attention_status - Turns the Amber LED for a slot on, off or blink 237 */ 238 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 239 { 240 struct slot *slot = hotplug_slot->private; 241 242 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 243 244 hotplug_slot->info->attention_status = status; 245 246 if (ATTN_LED(slot->ctrl->ctrlcap)) 247 slot->hpc_ops->set_attention_status(slot, status); 248 249 return 0; 250 } 251 252 253 static int enable_slot(struct hotplug_slot *hotplug_slot) 254 { 255 struct slot *slot = hotplug_slot->private; 256 257 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 258 259 return pciehp_enable_slot(slot); 260 } 261 262 263 static int disable_slot(struct hotplug_slot *hotplug_slot) 264 { 265 struct slot *slot = hotplug_slot->private; 266 267 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 268 269 return pciehp_disable_slot(slot); 270 } 271 272 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 273 { 274 struct slot *slot = hotplug_slot->private; 275 int retval; 276 277 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 278 279 retval = slot->hpc_ops->get_power_status(slot, value); 280 if (retval < 0) 281 *value = hotplug_slot->info->power_status; 282 283 return 0; 284 } 285 286 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 287 { 288 struct slot *slot = hotplug_slot->private; 289 int retval; 290 291 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 292 293 retval = slot->hpc_ops->get_attention_status(slot, value); 294 if (retval < 0) 295 *value = hotplug_slot->info->attention_status; 296 297 return 0; 298 } 299 300 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 301 { 302 struct slot *slot = hotplug_slot->private; 303 int retval; 304 305 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 306 307 retval = slot->hpc_ops->get_latch_status(slot, value); 308 if (retval < 0) 309 *value = hotplug_slot->info->latch_status; 310 311 return 0; 312 } 313 314 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 315 { 316 struct slot *slot = hotplug_slot->private; 317 int retval; 318 319 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 320 321 retval = slot->hpc_ops->get_adapter_status(slot, value); 322 if (retval < 0) 323 *value = hotplug_slot->info->adapter_status; 324 325 return 0; 326 } 327 328 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 329 { 330 struct slot *slot = hotplug_slot->private; 331 int retval; 332 333 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 334 335 retval = slot->hpc_ops->get_max_bus_speed(slot, value); 336 if (retval < 0) 337 *value = PCI_SPEED_UNKNOWN; 338 339 return 0; 340 } 341 342 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 343 { 344 struct slot *slot = hotplug_slot->private; 345 int retval; 346 347 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 348 349 retval = slot->hpc_ops->get_cur_bus_speed(slot, value); 350 if (retval < 0) 351 *value = PCI_SPEED_UNKNOWN; 352 353 return 0; 354 } 355 356 static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id) 357 { 358 int rc; 359 struct controller *ctrl; 360 struct slot *t_slot; 361 int first_device_num = 0 ; /* first PCI device number supported by this PCIE */ 362 int num_ctlr_slots; /* number of slots supported by this HPC */ 363 u8 value; 364 struct pci_dev *pdev; 365 366 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); 367 if (!ctrl) { 368 err("%s : out of memory\n", __FUNCTION__); 369 goto err_out_none; 370 } 371 memset(ctrl, 0, sizeof(struct controller)); 372 373 pdev = dev->port; 374 ctrl->pci_dev = pdev; 375 376 rc = pcie_init(ctrl, dev); 377 if (rc) { 378 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); 379 goto err_out_free_ctrl; 380 } 381 382 pci_set_drvdata(pdev, ctrl); 383 384 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 385 if (!ctrl->pci_bus) { 386 err("%s: out of memory\n", __FUNCTION__); 387 rc = -ENOMEM; 388 goto err_out_unmap_mmio_region; 389 } 390 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); 391 ctrl->bus = pdev->bus->number; /* ctrl bus */ 392 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ 393 394 ctrl->device = PCI_SLOT(pdev->devfn); 395 ctrl->function = PCI_FUNC(pdev->devfn); 396 dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, 397 ctrl->bus, ctrl->device, ctrl->function, pdev->irq); 398 399 /* 400 * Save configuration headers for this and subordinate PCI buses 401 */ 402 403 rc = get_ctlr_slot_config(ctrl); 404 if (rc) { 405 err(msg_initialization_err, rc); 406 goto err_out_free_ctrl_bus; 407 } 408 first_device_num = ctrl->slot_device_offset; 409 num_ctlr_slots = ctrl->num_slots; 410 411 /* Setup the slot information structures */ 412 rc = init_slots(ctrl); 413 if (rc) { 414 err(msg_initialization_err, 6); 415 goto err_out_free_ctrl_slot; 416 } 417 418 t_slot = pciehp_find_slot(ctrl, first_device_num); 419 420 /* Finish setting up the hot plug ctrl device */ 421 ctrl->next_event = 0; 422 423 if (!pciehp_ctrl_list) { 424 pciehp_ctrl_list = ctrl; 425 ctrl->next = NULL; 426 } else { 427 ctrl->next = pciehp_ctrl_list; 428 pciehp_ctrl_list = ctrl; 429 } 430 431 /* Wait for exclusive access to hardware */ 432 down(&ctrl->crit_sect); 433 434 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ 435 436 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 437 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 438 if (rc) { 439 /* Done with exclusive hardware access */ 440 up(&ctrl->crit_sect); 441 goto err_out_free_ctrl_slot; 442 } else 443 /* Wait for the command to complete */ 444 wait_for_ctrl_irq (ctrl); 445 } 446 447 /* Done with exclusive hardware access */ 448 up(&ctrl->crit_sect); 449 450 return 0; 451 452 err_out_free_ctrl_slot: 453 cleanup_slots(ctrl); 454 err_out_free_ctrl_bus: 455 kfree(ctrl->pci_bus); 456 err_out_unmap_mmio_region: 457 ctrl->hpc_ops->release_ctlr(ctrl); 458 err_out_free_ctrl: 459 kfree(ctrl); 460 err_out_none: 461 return -ENODEV; 462 } 463 464 465 static int pcie_start_thread(void) 466 { 467 int retval = 0; 468 469 dbg("Initialize + Start the notification/polling mechanism \n"); 470 471 retval = pciehp_event_start_thread(); 472 if (retval) { 473 dbg("pciehp_event_start_thread() failed\n"); 474 return retval; 475 } 476 477 return retval; 478 } 479 480 static void __exit unload_pciehpd(void) 481 { 482 struct controller *ctrl; 483 struct controller *tctrl; 484 485 ctrl = pciehp_ctrl_list; 486 487 while (ctrl) { 488 cleanup_slots(ctrl); 489 490 kfree (ctrl->pci_bus); 491 492 ctrl->hpc_ops->release_ctlr(ctrl); 493 494 tctrl = ctrl; 495 ctrl = ctrl->next; 496 497 kfree(tctrl); 498 } 499 500 /* Stop the notification mechanism */ 501 pciehp_event_stop_thread(); 502 503 } 504 505 int hpdriver_context = 0; 506 507 static void pciehp_remove (struct pcie_device *device) 508 { 509 printk("%s ENTRY\n", __FUNCTION__); 510 printk("%s -> Call free_irq for irq = %d\n", 511 __FUNCTION__, device->irq); 512 free_irq(device->irq, &hpdriver_context); 513 } 514 515 #ifdef CONFIG_PM 516 static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) 517 { 518 printk("%s ENTRY\n", __FUNCTION__); 519 return 0; 520 } 521 522 static int pciehp_resume (struct pcie_device *dev) 523 { 524 printk("%s ENTRY\n", __FUNCTION__); 525 return 0; 526 } 527 #endif 528 529 static struct pcie_port_service_id port_pci_ids[] = { { 530 .vendor = PCI_ANY_ID, 531 .device = PCI_ANY_ID, 532 .port_type = PCIE_ANY_PORT, 533 .service_type = PCIE_PORT_SERVICE_HP, 534 .driver_data = 0, 535 }, { /* end: all zeroes */ } 536 }; 537 static const char device_name[] = "hpdriver"; 538 539 static struct pcie_port_service_driver hpdriver_portdrv = { 540 .name = (char *)device_name, 541 .id_table = &port_pci_ids[0], 542 543 .probe = pciehp_probe, 544 .remove = pciehp_remove, 545 546 #ifdef CONFIG_PM 547 .suspend = pciehp_suspend, 548 .resume = pciehp_resume, 549 #endif /* PM */ 550 }; 551 552 static int __init pcied_init(void) 553 { 554 int retval = 0; 555 556 #ifdef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 557 pciehp_poll_mode = 1; 558 #endif 559 560 retval = pcie_start_thread(); 561 if (retval) 562 goto error_hpc_init; 563 564 retval = pcie_port_service_register(&hpdriver_portdrv); 565 dbg("pcie_port_service_register = %d\n", retval); 566 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 567 if (retval) 568 dbg("%s: Failure to register service\n", __FUNCTION__); 569 570 error_hpc_init: 571 if (retval) { 572 pciehp_event_stop_thread(); 573 }; 574 575 return retval; 576 } 577 578 static void __exit pcied_cleanup(void) 579 { 580 dbg("unload_pciehpd()\n"); 581 unload_pciehpd(); 582 583 pcie_port_service_unregister(&hpdriver_portdrv); 584 585 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); 586 } 587 588 module_init(pcied_init); 589 module_exit(pcied_cleanup); 590