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/kernel.h> 32 #include <linux/types.h> 33 #include <linux/slab.h> 34 #include <linux/pci.h> 35 #include "../pci.h" 36 #include "pciehp.h" 37 38 static void interrupt_event_handler(struct work_struct *work); 39 40 static int queue_interrupt_event(struct slot *p_slot, u32 event_type) 41 { 42 struct event_info *info; 43 44 info = kmalloc(sizeof(*info), GFP_ATOMIC); 45 if (!info) 46 return -ENOMEM; 47 48 info->event_type = event_type; 49 info->p_slot = p_slot; 50 INIT_WORK(&info->work, interrupt_event_handler); 51 52 queue_work(p_slot->wq, &info->work); 53 54 return 0; 55 } 56 57 u8 pciehp_handle_attention_button(struct slot *p_slot) 58 { 59 u32 event_type; 60 struct controller *ctrl = p_slot->ctrl; 61 62 /* Attention Button Change */ 63 ctrl_dbg(ctrl, "Attention button interrupt received\n"); 64 65 /* 66 * Button pressed - See if need to TAKE ACTION!!! 67 */ 68 ctrl_info(ctrl, "Button pressed on Slot(%s)\n", slot_name(p_slot)); 69 event_type = INT_BUTTON_PRESS; 70 71 queue_interrupt_event(p_slot, event_type); 72 73 return 0; 74 } 75 76 u8 pciehp_handle_switch_change(struct slot *p_slot) 77 { 78 u8 getstatus; 79 u32 event_type; 80 struct controller *ctrl = p_slot->ctrl; 81 82 /* Switch Change */ 83 ctrl_dbg(ctrl, "Switch interrupt received\n"); 84 85 pciehp_get_latch_status(p_slot, &getstatus); 86 if (getstatus) { 87 /* 88 * Switch opened 89 */ 90 ctrl_info(ctrl, "Latch open on Slot(%s)\n", slot_name(p_slot)); 91 event_type = INT_SWITCH_OPEN; 92 } else { 93 /* 94 * Switch closed 95 */ 96 ctrl_info(ctrl, "Latch close on Slot(%s)\n", slot_name(p_slot)); 97 event_type = INT_SWITCH_CLOSE; 98 } 99 100 queue_interrupt_event(p_slot, event_type); 101 102 return 1; 103 } 104 105 u8 pciehp_handle_presence_change(struct slot *p_slot) 106 { 107 u32 event_type; 108 u8 presence_save; 109 struct controller *ctrl = p_slot->ctrl; 110 111 /* Presence Change */ 112 ctrl_dbg(ctrl, "Presence/Notify input change\n"); 113 114 /* Switch is open, assume a presence change 115 * Save the presence state 116 */ 117 pciehp_get_adapter_status(p_slot, &presence_save); 118 if (presence_save) { 119 /* 120 * Card Present 121 */ 122 ctrl_info(ctrl, "Card present on Slot(%s)\n", slot_name(p_slot)); 123 event_type = INT_PRESENCE_ON; 124 } else { 125 /* 126 * Not Present 127 */ 128 ctrl_info(ctrl, "Card not present on Slot(%s)\n", 129 slot_name(p_slot)); 130 event_type = INT_PRESENCE_OFF; 131 } 132 133 queue_interrupt_event(p_slot, event_type); 134 135 return 1; 136 } 137 138 u8 pciehp_handle_power_fault(struct slot *p_slot) 139 { 140 u32 event_type; 141 struct controller *ctrl = p_slot->ctrl; 142 143 /* power fault */ 144 ctrl_dbg(ctrl, "Power fault interrupt received\n"); 145 ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); 146 event_type = INT_POWER_FAULT; 147 ctrl_info(ctrl, "Power fault bit %x set\n", 0); 148 queue_interrupt_event(p_slot, event_type); 149 150 return 1; 151 } 152 153 void pciehp_handle_linkstate_change(struct slot *p_slot) 154 { 155 u32 event_type; 156 struct controller *ctrl = p_slot->ctrl; 157 158 /* Link Status Change */ 159 ctrl_dbg(ctrl, "Data Link Layer State change\n"); 160 161 if (pciehp_check_link_active(ctrl)) { 162 ctrl_info(ctrl, "slot(%s): Link Up event\n", 163 slot_name(p_slot)); 164 event_type = INT_LINK_UP; 165 } else { 166 ctrl_info(ctrl, "slot(%s): Link Down event\n", 167 slot_name(p_slot)); 168 event_type = INT_LINK_DOWN; 169 } 170 171 queue_interrupt_event(p_slot, event_type); 172 } 173 174 /* The following routines constitute the bulk of the 175 hotplug controller logic 176 */ 177 178 static void set_slot_off(struct controller *ctrl, struct slot * pslot) 179 { 180 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ 181 if (POWER_CTRL(ctrl)) { 182 pciehp_power_off_slot(pslot); 183 184 /* 185 * After turning power off, we must wait for at least 1 second 186 * before taking any action that relies on power having been 187 * removed from the slot/adapter. 188 */ 189 msleep(1000); 190 } 191 192 pciehp_green_led_off(pslot); 193 pciehp_set_attention_status(pslot, 1); 194 } 195 196 /** 197 * board_added - Called after a board has been added to the system. 198 * @p_slot: &slot where board is added 199 * 200 * Turns power on for the board. 201 * Configures board. 202 */ 203 static int board_added(struct slot *p_slot) 204 { 205 int retval = 0; 206 struct controller *ctrl = p_slot->ctrl; 207 struct pci_bus *parent = ctrl->pcie->port->subordinate; 208 209 if (POWER_CTRL(ctrl)) { 210 /* Power on slot */ 211 retval = pciehp_power_on_slot(p_slot); 212 if (retval) 213 return retval; 214 } 215 216 pciehp_green_led_blink(p_slot); 217 218 /* Check link training status */ 219 retval = pciehp_check_link_status(ctrl); 220 if (retval) { 221 ctrl_err(ctrl, "Failed to check link status\n"); 222 goto err_exit; 223 } 224 225 /* Check for a power fault */ 226 if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { 227 ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); 228 retval = -EIO; 229 goto err_exit; 230 } 231 232 retval = pciehp_configure_device(p_slot); 233 if (retval) { 234 ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", 235 pci_domain_nr(parent), parent->number); 236 if (retval != -EEXIST) 237 goto err_exit; 238 } 239 240 pciehp_green_led_on(p_slot); 241 return 0; 242 243 err_exit: 244 set_slot_off(ctrl, p_slot); 245 return retval; 246 } 247 248 /** 249 * remove_board - Turns off slot and LEDs 250 * @p_slot: slot where board is being removed 251 */ 252 static int remove_board(struct slot *p_slot) 253 { 254 int retval; 255 struct controller *ctrl = p_slot->ctrl; 256 257 retval = pciehp_unconfigure_device(p_slot); 258 if (retval) 259 return retval; 260 261 if (POWER_CTRL(ctrl)) { 262 pciehp_power_off_slot(p_slot); 263 264 /* 265 * After turning power off, we must wait for at least 1 second 266 * before taking any action that relies on power having been 267 * removed from the slot/adapter. 268 */ 269 msleep(1000); 270 } 271 272 /* turn off Green LED */ 273 pciehp_green_led_off(p_slot); 274 return 0; 275 } 276 277 struct power_work_info { 278 struct slot *p_slot; 279 struct work_struct work; 280 unsigned int req; 281 #define DISABLE_REQ 0 282 #define ENABLE_REQ 1 283 }; 284 285 /** 286 * pciehp_power_thread - handle pushbutton events 287 * @work: &struct work_struct describing work to be done 288 * 289 * Scheduled procedure to handle blocking stuff for the pushbuttons. 290 * Handles all pending events and exits. 291 */ 292 static void pciehp_power_thread(struct work_struct *work) 293 { 294 struct power_work_info *info = 295 container_of(work, struct power_work_info, work); 296 struct slot *p_slot = info->p_slot; 297 int ret; 298 299 switch (info->req) { 300 case DISABLE_REQ: 301 ctrl_dbg(p_slot->ctrl, 302 "Disabling domain:bus:device=%04x:%02x:00\n", 303 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), 304 p_slot->ctrl->pcie->port->subordinate->number); 305 mutex_lock(&p_slot->hotplug_lock); 306 pciehp_disable_slot(p_slot); 307 mutex_unlock(&p_slot->hotplug_lock); 308 mutex_lock(&p_slot->lock); 309 p_slot->state = STATIC_STATE; 310 mutex_unlock(&p_slot->lock); 311 break; 312 case ENABLE_REQ: 313 ctrl_dbg(p_slot->ctrl, 314 "Enabling domain:bus:device=%04x:%02x:00\n", 315 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), 316 p_slot->ctrl->pcie->port->subordinate->number); 317 mutex_lock(&p_slot->hotplug_lock); 318 ret = pciehp_enable_slot(p_slot); 319 mutex_unlock(&p_slot->hotplug_lock); 320 if (ret) 321 pciehp_green_led_off(p_slot); 322 mutex_lock(&p_slot->lock); 323 p_slot->state = STATIC_STATE; 324 mutex_unlock(&p_slot->lock); 325 break; 326 default: 327 break; 328 } 329 330 kfree(info); 331 } 332 333 void pciehp_queue_pushbutton_work(struct work_struct *work) 334 { 335 struct slot *p_slot = container_of(work, struct slot, work.work); 336 struct power_work_info *info; 337 338 info = kmalloc(sizeof(*info), GFP_KERNEL); 339 if (!info) { 340 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 341 __func__); 342 return; 343 } 344 info->p_slot = p_slot; 345 INIT_WORK(&info->work, pciehp_power_thread); 346 347 mutex_lock(&p_slot->lock); 348 switch (p_slot->state) { 349 case BLINKINGOFF_STATE: 350 p_slot->state = POWEROFF_STATE; 351 info->req = DISABLE_REQ; 352 break; 353 case BLINKINGON_STATE: 354 p_slot->state = POWERON_STATE; 355 info->req = ENABLE_REQ; 356 break; 357 default: 358 kfree(info); 359 goto out; 360 } 361 queue_work(p_slot->wq, &info->work); 362 out: 363 mutex_unlock(&p_slot->lock); 364 } 365 366 /* 367 * Note: This function must be called with slot->lock held 368 */ 369 static void handle_button_press_event(struct slot *p_slot) 370 { 371 struct controller *ctrl = p_slot->ctrl; 372 u8 getstatus; 373 374 switch (p_slot->state) { 375 case STATIC_STATE: 376 pciehp_get_power_status(p_slot, &getstatus); 377 if (getstatus) { 378 p_slot->state = BLINKINGOFF_STATE; 379 ctrl_info(ctrl, 380 "PCI slot #%s - powering off due to button " 381 "press.\n", slot_name(p_slot)); 382 } else { 383 p_slot->state = BLINKINGON_STATE; 384 ctrl_info(ctrl, 385 "PCI slot #%s - powering on due to button " 386 "press.\n", slot_name(p_slot)); 387 } 388 /* blink green LED and turn off amber */ 389 pciehp_green_led_blink(p_slot); 390 pciehp_set_attention_status(p_slot, 0); 391 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 392 break; 393 case BLINKINGOFF_STATE: 394 case BLINKINGON_STATE: 395 /* 396 * Cancel if we are still blinking; this means that we 397 * press the attention again before the 5 sec. limit 398 * expires to cancel hot-add or hot-remove 399 */ 400 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); 401 cancel_delayed_work(&p_slot->work); 402 if (p_slot->state == BLINKINGOFF_STATE) 403 pciehp_green_led_on(p_slot); 404 else 405 pciehp_green_led_off(p_slot); 406 pciehp_set_attention_status(p_slot, 0); 407 ctrl_info(ctrl, "PCI slot #%s - action canceled " 408 "due to button press\n", slot_name(p_slot)); 409 p_slot->state = STATIC_STATE; 410 break; 411 case POWEROFF_STATE: 412 case POWERON_STATE: 413 /* 414 * Ignore if the slot is on power-on or power-off state; 415 * this means that the previous attention button action 416 * to hot-add or hot-remove is undergoing 417 */ 418 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); 419 break; 420 default: 421 ctrl_warn(ctrl, "Not a valid state\n"); 422 break; 423 } 424 } 425 426 /* 427 * Note: This function must be called with slot->lock held 428 */ 429 static void handle_surprise_event(struct slot *p_slot) 430 { 431 u8 getstatus; 432 struct power_work_info *info; 433 434 info = kmalloc(sizeof(*info), GFP_KERNEL); 435 if (!info) { 436 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 437 __func__); 438 return; 439 } 440 info->p_slot = p_slot; 441 INIT_WORK(&info->work, pciehp_power_thread); 442 443 pciehp_get_adapter_status(p_slot, &getstatus); 444 if (!getstatus) { 445 p_slot->state = POWEROFF_STATE; 446 info->req = DISABLE_REQ; 447 } else { 448 p_slot->state = POWERON_STATE; 449 info->req = ENABLE_REQ; 450 } 451 452 queue_work(p_slot->wq, &info->work); 453 } 454 455 /* 456 * Note: This function must be called with slot->lock held 457 */ 458 static void handle_link_event(struct slot *p_slot, u32 event) 459 { 460 struct controller *ctrl = p_slot->ctrl; 461 struct power_work_info *info; 462 463 info = kmalloc(sizeof(*info), GFP_KERNEL); 464 if (!info) { 465 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 466 __func__); 467 return; 468 } 469 info->p_slot = p_slot; 470 info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ; 471 INIT_WORK(&info->work, pciehp_power_thread); 472 473 switch (p_slot->state) { 474 case BLINKINGON_STATE: 475 case BLINKINGOFF_STATE: 476 cancel_delayed_work(&p_slot->work); 477 /* Fall through */ 478 case STATIC_STATE: 479 p_slot->state = event == INT_LINK_UP ? 480 POWERON_STATE : POWEROFF_STATE; 481 queue_work(p_slot->wq, &info->work); 482 break; 483 case POWERON_STATE: 484 if (event == INT_LINK_UP) { 485 ctrl_info(ctrl, 486 "Link Up event ignored on slot(%s): already powering on\n", 487 slot_name(p_slot)); 488 kfree(info); 489 } else { 490 ctrl_info(ctrl, 491 "Link Down event queued on slot(%s): currently getting powered on\n", 492 slot_name(p_slot)); 493 p_slot->state = POWEROFF_STATE; 494 queue_work(p_slot->wq, &info->work); 495 } 496 break; 497 case POWEROFF_STATE: 498 if (event == INT_LINK_UP) { 499 ctrl_info(ctrl, 500 "Link Up event queued on slot(%s): currently getting powered off\n", 501 slot_name(p_slot)); 502 p_slot->state = POWERON_STATE; 503 queue_work(p_slot->wq, &info->work); 504 } else { 505 ctrl_info(ctrl, 506 "Link Down event ignored on slot(%s): already powering off\n", 507 slot_name(p_slot)); 508 kfree(info); 509 } 510 break; 511 default: 512 ctrl_err(ctrl, "Not a valid state on slot(%s)\n", 513 slot_name(p_slot)); 514 kfree(info); 515 break; 516 } 517 } 518 519 static void interrupt_event_handler(struct work_struct *work) 520 { 521 struct event_info *info = container_of(work, struct event_info, work); 522 struct slot *p_slot = info->p_slot; 523 struct controller *ctrl = p_slot->ctrl; 524 525 mutex_lock(&p_slot->lock); 526 switch (info->event_type) { 527 case INT_BUTTON_PRESS: 528 handle_button_press_event(p_slot); 529 break; 530 case INT_POWER_FAULT: 531 if (!POWER_CTRL(ctrl)) 532 break; 533 pciehp_set_attention_status(p_slot, 1); 534 pciehp_green_led_off(p_slot); 535 break; 536 case INT_PRESENCE_ON: 537 if (!HP_SUPR_RM(ctrl)) 538 break; 539 ctrl_dbg(ctrl, "Surprise Insertion\n"); 540 handle_surprise_event(p_slot); 541 break; 542 case INT_PRESENCE_OFF: 543 /* 544 * Regardless of surprise capability, we need to 545 * definitely remove a card that has been pulled out! 546 */ 547 ctrl_dbg(ctrl, "Surprise Removal\n"); 548 handle_surprise_event(p_slot); 549 break; 550 case INT_LINK_UP: 551 case INT_LINK_DOWN: 552 handle_link_event(p_slot, info->event_type); 553 break; 554 default: 555 break; 556 } 557 mutex_unlock(&p_slot->lock); 558 559 kfree(info); 560 } 561 562 /* 563 * Note: This function must be called with slot->hotplug_lock held 564 */ 565 int pciehp_enable_slot(struct slot *p_slot) 566 { 567 u8 getstatus = 0; 568 int rc; 569 struct controller *ctrl = p_slot->ctrl; 570 571 pciehp_get_adapter_status(p_slot, &getstatus); 572 if (!getstatus) { 573 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 574 return -ENODEV; 575 } 576 if (MRL_SENS(p_slot->ctrl)) { 577 pciehp_get_latch_status(p_slot, &getstatus); 578 if (getstatus) { 579 ctrl_info(ctrl, "Latch open on slot(%s)\n", 580 slot_name(p_slot)); 581 return -ENODEV; 582 } 583 } 584 585 if (POWER_CTRL(p_slot->ctrl)) { 586 pciehp_get_power_status(p_slot, &getstatus); 587 if (getstatus) { 588 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 589 slot_name(p_slot)); 590 return -EINVAL; 591 } 592 } 593 594 pciehp_get_latch_status(p_slot, &getstatus); 595 596 rc = board_added(p_slot); 597 if (rc) 598 pciehp_get_latch_status(p_slot, &getstatus); 599 600 return rc; 601 } 602 603 /* 604 * Note: This function must be called with slot->hotplug_lock held 605 */ 606 int pciehp_disable_slot(struct slot *p_slot) 607 { 608 u8 getstatus = 0; 609 struct controller *ctrl = p_slot->ctrl; 610 611 if (!p_slot->ctrl) 612 return 1; 613 614 if (POWER_CTRL(p_slot->ctrl)) { 615 pciehp_get_power_status(p_slot, &getstatus); 616 if (!getstatus) { 617 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 618 slot_name(p_slot)); 619 return -EINVAL; 620 } 621 } 622 623 return remove_board(p_slot); 624 } 625 626 int pciehp_sysfs_enable_slot(struct slot *p_slot) 627 { 628 int retval = -ENODEV; 629 struct controller *ctrl = p_slot->ctrl; 630 631 mutex_lock(&p_slot->lock); 632 switch (p_slot->state) { 633 case BLINKINGON_STATE: 634 cancel_delayed_work(&p_slot->work); 635 case STATIC_STATE: 636 p_slot->state = POWERON_STATE; 637 mutex_unlock(&p_slot->lock); 638 mutex_lock(&p_slot->hotplug_lock); 639 retval = pciehp_enable_slot(p_slot); 640 mutex_unlock(&p_slot->hotplug_lock); 641 mutex_lock(&p_slot->lock); 642 p_slot->state = STATIC_STATE; 643 break; 644 case POWERON_STATE: 645 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 646 slot_name(p_slot)); 647 break; 648 case BLINKINGOFF_STATE: 649 case POWEROFF_STATE: 650 ctrl_info(ctrl, "Already enabled on slot %s\n", 651 slot_name(p_slot)); 652 break; 653 default: 654 ctrl_err(ctrl, "Not a valid state on slot %s\n", 655 slot_name(p_slot)); 656 break; 657 } 658 mutex_unlock(&p_slot->lock); 659 660 return retval; 661 } 662 663 int pciehp_sysfs_disable_slot(struct slot *p_slot) 664 { 665 int retval = -ENODEV; 666 struct controller *ctrl = p_slot->ctrl; 667 668 mutex_lock(&p_slot->lock); 669 switch (p_slot->state) { 670 case BLINKINGOFF_STATE: 671 cancel_delayed_work(&p_slot->work); 672 case STATIC_STATE: 673 p_slot->state = POWEROFF_STATE; 674 mutex_unlock(&p_slot->lock); 675 retval = pciehp_disable_slot(p_slot); 676 mutex_lock(&p_slot->lock); 677 p_slot->state = STATIC_STATE; 678 break; 679 case POWEROFF_STATE: 680 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 681 slot_name(p_slot)); 682 break; 683 case BLINKINGON_STATE: 684 case POWERON_STATE: 685 ctrl_info(ctrl, "Already disabled on slot %s\n", 686 slot_name(p_slot)); 687 break; 688 default: 689 ctrl_err(ctrl, "Not a valid state on slot %s\n", 690 slot_name(p_slot)); 691 break; 692 } 693 mutex_unlock(&p_slot->lock); 694 695 return retval; 696 } 697