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 *slot; 107 struct hpc_ops *hpc_ops; 108 struct hotplug_slot *hotplug_slot; 109 struct hotplug_slot_info *hotplug_slot_info; 110 u8 number_of_slots; 111 u8 slot_device; 112 u32 slot_number; 113 int result = -ENOMEM; 114 115 number_of_slots = ctrl->num_slots; 116 slot_device = ctrl->slot_device_offset; 117 slot_number = ctrl->first_slot; 118 119 while (number_of_slots) { 120 slot = kmalloc(sizeof(*slot), GFP_KERNEL); 121 if (!slot) 122 goto error; 123 124 memset(slot, 0, sizeof(struct slot)); 125 slot->hotplug_slot = 126 kmalloc(sizeof(*(slot->hotplug_slot)), 127 GFP_KERNEL); 128 if (!slot->hotplug_slot) 129 goto error_slot; 130 hotplug_slot = slot->hotplug_slot; 131 memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); 132 133 hotplug_slot->info = 134 kmalloc(sizeof(*(hotplug_slot->info)), 135 GFP_KERNEL); 136 if (!hotplug_slot->info) 137 goto error_hpslot; 138 hotplug_slot_info = hotplug_slot->info; 139 memset(hotplug_slot_info, 0, 140 sizeof(struct hotplug_slot_info)); 141 hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); 142 if (!hotplug_slot->name) 143 goto error_info; 144 145 slot->ctrl = ctrl; 146 slot->bus = ctrl->slot_bus; 147 slot->device = slot_device; 148 slot->hpc_ops = hpc_ops = ctrl->hpc_ops; 149 150 slot->number = ctrl->first_slot; 151 slot->hp_slot = slot_device - ctrl->slot_device_offset; 152 153 /* register this slot with the hotplug pci core */ 154 hotplug_slot->private = slot; 155 hotplug_slot->release = &release_slot; 156 make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); 157 hotplug_slot->ops = &pciehp_hotplug_slot_ops; 158 159 hpc_ops->get_power_status(slot, 160 &(hotplug_slot_info->power_status)); 161 hpc_ops->get_attention_status(slot, 162 &(hotplug_slot_info->attention_status)); 163 hpc_ops->get_latch_status(slot, 164 &(hotplug_slot_info->latch_status)); 165 hpc_ops->get_adapter_status(slot, 166 &(hotplug_slot_info->adapter_status)); 167 168 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " 169 "slot_device_offset=%x\n", 170 slot->bus, slot->device, slot->hp_slot, slot->number, 171 ctrl->slot_device_offset); 172 result = pci_hp_register(hotplug_slot); 173 if (result) { 174 err ("pci_hp_register failed with error %d\n", result); 175 goto error_name; 176 } 177 178 slot->next = ctrl->slot; 179 ctrl->slot = slot; 180 181 number_of_slots--; 182 slot_device++; 183 slot_number += ctrl->slot_num_inc; 184 } 185 186 return 0; 187 188 error_name: 189 kfree(hotplug_slot->name); 190 error_info: 191 kfree(hotplug_slot_info); 192 error_hpslot: 193 kfree(hotplug_slot); 194 error_slot: 195 kfree(slot); 196 error: 197 return result; 198 } 199 200 201 static int cleanup_slots (struct controller * ctrl) 202 { 203 struct slot *old_slot, *next_slot; 204 205 old_slot = ctrl->slot; 206 ctrl->slot = NULL; 207 208 while (old_slot) { 209 next_slot = old_slot->next; 210 pci_hp_deregister (old_slot->hotplug_slot); 211 old_slot = next_slot; 212 } 213 214 215 return(0); 216 } 217 218 static int get_ctlr_slot_config(struct controller *ctrl) 219 { 220 int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/ 221 int first_device_num; /* Not needed */ 222 int physical_slot_num; 223 u8 ctrlcap; 224 int rc; 225 226 rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap); 227 if (rc) { 228 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); 229 return (-1); 230 } 231 232 ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */ 233 ctrl->slot_device_offset = first_device_num; 234 ctrl->first_slot = physical_slot_num; 235 ctrl->ctrlcap = ctrlcap; 236 237 dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n", 238 __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, 239 ctrl->bus, ctrl->device); 240 241 return (0); 242 } 243 244 245 /* 246 * set_attention_status - Turns the Amber LED for a slot on, off or blink 247 */ 248 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 249 { 250 struct slot *slot = hotplug_slot->private; 251 252 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 253 254 hotplug_slot->info->attention_status = status; 255 256 if (ATTN_LED(slot->ctrl->ctrlcap)) 257 slot->hpc_ops->set_attention_status(slot, status); 258 259 return 0; 260 } 261 262 263 static int enable_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_enable_slot(slot); 270 } 271 272 273 static int disable_slot(struct hotplug_slot *hotplug_slot) 274 { 275 struct slot *slot = hotplug_slot->private; 276 277 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 278 279 return pciehp_disable_slot(slot); 280 } 281 282 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 283 { 284 struct slot *slot = hotplug_slot->private; 285 int retval; 286 287 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 288 289 retval = slot->hpc_ops->get_power_status(slot, value); 290 if (retval < 0) 291 *value = hotplug_slot->info->power_status; 292 293 return 0; 294 } 295 296 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 297 { 298 struct slot *slot = hotplug_slot->private; 299 int retval; 300 301 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 302 303 retval = slot->hpc_ops->get_attention_status(slot, value); 304 if (retval < 0) 305 *value = hotplug_slot->info->attention_status; 306 307 return 0; 308 } 309 310 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 311 { 312 struct slot *slot = hotplug_slot->private; 313 int retval; 314 315 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 316 317 retval = slot->hpc_ops->get_latch_status(slot, value); 318 if (retval < 0) 319 *value = hotplug_slot->info->latch_status; 320 321 return 0; 322 } 323 324 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 325 { 326 struct slot *slot = hotplug_slot->private; 327 int retval; 328 329 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 330 331 retval = slot->hpc_ops->get_adapter_status(slot, value); 332 if (retval < 0) 333 *value = hotplug_slot->info->adapter_status; 334 335 return 0; 336 } 337 338 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 339 { 340 struct slot *slot = hotplug_slot->private; 341 int retval; 342 343 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 344 345 retval = slot->hpc_ops->get_max_bus_speed(slot, value); 346 if (retval < 0) 347 *value = PCI_SPEED_UNKNOWN; 348 349 return 0; 350 } 351 352 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 353 { 354 struct slot *slot = hotplug_slot->private; 355 int retval; 356 357 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 358 359 retval = slot->hpc_ops->get_cur_bus_speed(slot, value); 360 if (retval < 0) 361 *value = PCI_SPEED_UNKNOWN; 362 363 return 0; 364 } 365 366 static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id) 367 { 368 int rc; 369 struct controller *ctrl; 370 struct slot *t_slot; 371 int first_device_num = 0 ; /* first PCI device number supported by this PCIE */ 372 int num_ctlr_slots; /* number of slots supported by this HPC */ 373 u8 value; 374 struct pci_dev *pdev; 375 376 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); 377 if (!ctrl) { 378 err("%s : out of memory\n", __FUNCTION__); 379 goto err_out_none; 380 } 381 memset(ctrl, 0, sizeof(struct controller)); 382 383 pdev = dev->port; 384 ctrl->pci_dev = pdev; 385 386 rc = pcie_init(ctrl, dev); 387 if (rc) { 388 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); 389 goto err_out_free_ctrl; 390 } 391 392 pci_set_drvdata(pdev, ctrl); 393 394 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 395 if (!ctrl->pci_bus) { 396 err("%s: out of memory\n", __FUNCTION__); 397 rc = -ENOMEM; 398 goto err_out_unmap_mmio_region; 399 } 400 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); 401 ctrl->bus = pdev->bus->number; /* ctrl bus */ 402 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ 403 404 ctrl->device = PCI_SLOT(pdev->devfn); 405 ctrl->function = PCI_FUNC(pdev->devfn); 406 dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, 407 ctrl->bus, ctrl->device, ctrl->function, pdev->irq); 408 409 /* 410 * Save configuration headers for this and subordinate PCI buses 411 */ 412 413 rc = get_ctlr_slot_config(ctrl); 414 if (rc) { 415 err(msg_initialization_err, rc); 416 goto err_out_free_ctrl_bus; 417 } 418 first_device_num = ctrl->slot_device_offset; 419 num_ctlr_slots = ctrl->num_slots; 420 421 /* Setup the slot information structures */ 422 rc = init_slots(ctrl); 423 if (rc) { 424 err(msg_initialization_err, 6); 425 goto err_out_free_ctrl_slot; 426 } 427 428 t_slot = pciehp_find_slot(ctrl, first_device_num); 429 430 /* Finish setting up the hot plug ctrl device */ 431 ctrl->next_event = 0; 432 433 if (!pciehp_ctrl_list) { 434 pciehp_ctrl_list = ctrl; 435 ctrl->next = NULL; 436 } else { 437 ctrl->next = pciehp_ctrl_list; 438 pciehp_ctrl_list = ctrl; 439 } 440 441 /* Wait for exclusive access to hardware */ 442 down(&ctrl->crit_sect); 443 444 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ 445 446 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 447 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 448 if (rc) { 449 /* Done with exclusive hardware access */ 450 up(&ctrl->crit_sect); 451 goto err_out_free_ctrl_slot; 452 } else 453 /* Wait for the command to complete */ 454 wait_for_ctrl_irq (ctrl); 455 } 456 457 /* Done with exclusive hardware access */ 458 up(&ctrl->crit_sect); 459 460 return 0; 461 462 err_out_free_ctrl_slot: 463 cleanup_slots(ctrl); 464 err_out_free_ctrl_bus: 465 kfree(ctrl->pci_bus); 466 err_out_unmap_mmio_region: 467 ctrl->hpc_ops->release_ctlr(ctrl); 468 err_out_free_ctrl: 469 kfree(ctrl); 470 err_out_none: 471 return -ENODEV; 472 } 473 474 475 static int pcie_start_thread(void) 476 { 477 int retval = 0; 478 479 dbg("Initialize + Start the notification/polling mechanism \n"); 480 481 retval = pciehp_event_start_thread(); 482 if (retval) { 483 dbg("pciehp_event_start_thread() failed\n"); 484 return retval; 485 } 486 487 return retval; 488 } 489 490 static void __exit unload_pciehpd(void) 491 { 492 struct controller *ctrl; 493 struct controller *tctrl; 494 495 ctrl = pciehp_ctrl_list; 496 497 while (ctrl) { 498 cleanup_slots(ctrl); 499 500 kfree (ctrl->pci_bus); 501 502 ctrl->hpc_ops->release_ctlr(ctrl); 503 504 tctrl = ctrl; 505 ctrl = ctrl->next; 506 507 kfree(tctrl); 508 } 509 510 /* Stop the notification mechanism */ 511 pciehp_event_stop_thread(); 512 513 } 514 515 static int hpdriver_context = 0; 516 517 static void pciehp_remove (struct pcie_device *device) 518 { 519 printk("%s ENTRY\n", __FUNCTION__); 520 printk("%s -> Call free_irq for irq = %d\n", 521 __FUNCTION__, device->irq); 522 free_irq(device->irq, &hpdriver_context); 523 } 524 525 #ifdef CONFIG_PM 526 static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) 527 { 528 printk("%s ENTRY\n", __FUNCTION__); 529 return 0; 530 } 531 532 static int pciehp_resume (struct pcie_device *dev) 533 { 534 printk("%s ENTRY\n", __FUNCTION__); 535 return 0; 536 } 537 #endif 538 539 static struct pcie_port_service_id port_pci_ids[] = { { 540 .vendor = PCI_ANY_ID, 541 .device = PCI_ANY_ID, 542 .port_type = PCIE_ANY_PORT, 543 .service_type = PCIE_PORT_SERVICE_HP, 544 .driver_data = 0, 545 }, { /* end: all zeroes */ } 546 }; 547 static const char device_name[] = "hpdriver"; 548 549 static struct pcie_port_service_driver hpdriver_portdrv = { 550 .name = (char *)device_name, 551 .id_table = &port_pci_ids[0], 552 553 .probe = pciehp_probe, 554 .remove = pciehp_remove, 555 556 #ifdef CONFIG_PM 557 .suspend = pciehp_suspend, 558 .resume = pciehp_resume, 559 #endif /* PM */ 560 }; 561 562 static int __init pcied_init(void) 563 { 564 int retval = 0; 565 566 #ifdef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 567 pciehp_poll_mode = 1; 568 #endif 569 570 retval = pcie_start_thread(); 571 if (retval) 572 goto error_hpc_init; 573 574 retval = pcie_port_service_register(&hpdriver_portdrv); 575 dbg("pcie_port_service_register = %d\n", retval); 576 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 577 if (retval) 578 dbg("%s: Failure to register service\n", __FUNCTION__); 579 580 error_hpc_init: 581 if (retval) { 582 pciehp_event_stop_thread(); 583 }; 584 585 return retval; 586 } 587 588 static void __exit pcied_cleanup(void) 589 { 590 dbg("unload_pciehpd()\n"); 591 unload_pciehpd(); 592 593 pcie_port_service_unregister(&hpdriver_portdrv); 594 595 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); 596 } 597 598 module_init(pcied_init); 599 module_exit(pcied_cleanup); 600