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