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, "PCI slot #%s - powering off due to button press\n", 380 slot_name(p_slot)); 381 } else { 382 p_slot->state = BLINKINGON_STATE; 383 ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", 384 slot_name(p_slot)); 385 } 386 /* blink green LED and turn off amber */ 387 pciehp_green_led_blink(p_slot); 388 pciehp_set_attention_status(p_slot, 0); 389 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 390 break; 391 case BLINKINGOFF_STATE: 392 case BLINKINGON_STATE: 393 /* 394 * Cancel if we are still blinking; this means that we 395 * press the attention again before the 5 sec. limit 396 * expires to cancel hot-add or hot-remove 397 */ 398 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); 399 cancel_delayed_work(&p_slot->work); 400 if (p_slot->state == BLINKINGOFF_STATE) 401 pciehp_green_led_on(p_slot); 402 else 403 pciehp_green_led_off(p_slot); 404 pciehp_set_attention_status(p_slot, 0); 405 ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", 406 slot_name(p_slot)); 407 p_slot->state = STATIC_STATE; 408 break; 409 case POWEROFF_STATE: 410 case POWERON_STATE: 411 /* 412 * Ignore if the slot is on power-on or power-off state; 413 * this means that the previous attention button action 414 * to hot-add or hot-remove is undergoing 415 */ 416 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); 417 break; 418 default: 419 ctrl_warn(ctrl, "Not a valid state\n"); 420 break; 421 } 422 } 423 424 /* 425 * Note: This function must be called with slot->lock held 426 */ 427 static void handle_surprise_event(struct slot *p_slot) 428 { 429 u8 getstatus; 430 struct power_work_info *info; 431 432 info = kmalloc(sizeof(*info), GFP_KERNEL); 433 if (!info) { 434 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 435 __func__); 436 return; 437 } 438 info->p_slot = p_slot; 439 INIT_WORK(&info->work, pciehp_power_thread); 440 441 pciehp_get_adapter_status(p_slot, &getstatus); 442 if (!getstatus) { 443 p_slot->state = POWEROFF_STATE; 444 info->req = DISABLE_REQ; 445 } else { 446 p_slot->state = POWERON_STATE; 447 info->req = ENABLE_REQ; 448 } 449 450 queue_work(p_slot->wq, &info->work); 451 } 452 453 /* 454 * Note: This function must be called with slot->lock held 455 */ 456 static void handle_link_event(struct slot *p_slot, u32 event) 457 { 458 struct controller *ctrl = p_slot->ctrl; 459 struct power_work_info *info; 460 461 info = kmalloc(sizeof(*info), GFP_KERNEL); 462 if (!info) { 463 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 464 __func__); 465 return; 466 } 467 info->p_slot = p_slot; 468 info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ; 469 INIT_WORK(&info->work, pciehp_power_thread); 470 471 switch (p_slot->state) { 472 case BLINKINGON_STATE: 473 case BLINKINGOFF_STATE: 474 cancel_delayed_work(&p_slot->work); 475 /* Fall through */ 476 case STATIC_STATE: 477 p_slot->state = event == INT_LINK_UP ? 478 POWERON_STATE : POWEROFF_STATE; 479 queue_work(p_slot->wq, &info->work); 480 break; 481 case POWERON_STATE: 482 if (event == INT_LINK_UP) { 483 ctrl_info(ctrl, 484 "Link Up event ignored on slot(%s): already powering on\n", 485 slot_name(p_slot)); 486 kfree(info); 487 } else { 488 ctrl_info(ctrl, 489 "Link Down event queued on slot(%s): currently getting powered on\n", 490 slot_name(p_slot)); 491 p_slot->state = POWEROFF_STATE; 492 queue_work(p_slot->wq, &info->work); 493 } 494 break; 495 case POWEROFF_STATE: 496 if (event == INT_LINK_UP) { 497 ctrl_info(ctrl, 498 "Link Up event queued on slot(%s): currently getting powered off\n", 499 slot_name(p_slot)); 500 p_slot->state = POWERON_STATE; 501 queue_work(p_slot->wq, &info->work); 502 } else { 503 ctrl_info(ctrl, 504 "Link Down event ignored on slot(%s): already powering off\n", 505 slot_name(p_slot)); 506 kfree(info); 507 } 508 break; 509 default: 510 ctrl_err(ctrl, "Not a valid state on slot(%s)\n", 511 slot_name(p_slot)); 512 kfree(info); 513 break; 514 } 515 } 516 517 static void interrupt_event_handler(struct work_struct *work) 518 { 519 struct event_info *info = container_of(work, struct event_info, work); 520 struct slot *p_slot = info->p_slot; 521 struct controller *ctrl = p_slot->ctrl; 522 523 mutex_lock(&p_slot->lock); 524 switch (info->event_type) { 525 case INT_BUTTON_PRESS: 526 handle_button_press_event(p_slot); 527 break; 528 case INT_POWER_FAULT: 529 if (!POWER_CTRL(ctrl)) 530 break; 531 pciehp_set_attention_status(p_slot, 1); 532 pciehp_green_led_off(p_slot); 533 break; 534 case INT_PRESENCE_ON: 535 if (!HP_SUPR_RM(ctrl)) 536 break; 537 ctrl_dbg(ctrl, "Surprise Insertion\n"); 538 handle_surprise_event(p_slot); 539 break; 540 case INT_PRESENCE_OFF: 541 /* 542 * Regardless of surprise capability, we need to 543 * definitely remove a card that has been pulled out! 544 */ 545 ctrl_dbg(ctrl, "Surprise Removal\n"); 546 handle_surprise_event(p_slot); 547 break; 548 case INT_LINK_UP: 549 case INT_LINK_DOWN: 550 handle_link_event(p_slot, info->event_type); 551 break; 552 default: 553 break; 554 } 555 mutex_unlock(&p_slot->lock); 556 557 kfree(info); 558 } 559 560 /* 561 * Note: This function must be called with slot->hotplug_lock held 562 */ 563 int pciehp_enable_slot(struct slot *p_slot) 564 { 565 u8 getstatus = 0; 566 int rc; 567 struct controller *ctrl = p_slot->ctrl; 568 569 pciehp_get_adapter_status(p_slot, &getstatus); 570 if (!getstatus) { 571 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 572 return -ENODEV; 573 } 574 if (MRL_SENS(p_slot->ctrl)) { 575 pciehp_get_latch_status(p_slot, &getstatus); 576 if (getstatus) { 577 ctrl_info(ctrl, "Latch open on slot(%s)\n", 578 slot_name(p_slot)); 579 return -ENODEV; 580 } 581 } 582 583 if (POWER_CTRL(p_slot->ctrl)) { 584 pciehp_get_power_status(p_slot, &getstatus); 585 if (getstatus) { 586 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 587 slot_name(p_slot)); 588 return -EINVAL; 589 } 590 } 591 592 pciehp_get_latch_status(p_slot, &getstatus); 593 594 rc = board_added(p_slot); 595 if (rc) 596 pciehp_get_latch_status(p_slot, &getstatus); 597 598 return rc; 599 } 600 601 /* 602 * Note: This function must be called with slot->hotplug_lock held 603 */ 604 int pciehp_disable_slot(struct slot *p_slot) 605 { 606 u8 getstatus = 0; 607 struct controller *ctrl = p_slot->ctrl; 608 609 if (!p_slot->ctrl) 610 return 1; 611 612 if (POWER_CTRL(p_slot->ctrl)) { 613 pciehp_get_power_status(p_slot, &getstatus); 614 if (!getstatus) { 615 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 616 slot_name(p_slot)); 617 return -EINVAL; 618 } 619 } 620 621 return remove_board(p_slot); 622 } 623 624 int pciehp_sysfs_enable_slot(struct slot *p_slot) 625 { 626 int retval = -ENODEV; 627 struct controller *ctrl = p_slot->ctrl; 628 629 mutex_lock(&p_slot->lock); 630 switch (p_slot->state) { 631 case BLINKINGON_STATE: 632 cancel_delayed_work(&p_slot->work); 633 case STATIC_STATE: 634 p_slot->state = POWERON_STATE; 635 mutex_unlock(&p_slot->lock); 636 mutex_lock(&p_slot->hotplug_lock); 637 retval = pciehp_enable_slot(p_slot); 638 mutex_unlock(&p_slot->hotplug_lock); 639 mutex_lock(&p_slot->lock); 640 p_slot->state = STATIC_STATE; 641 break; 642 case POWERON_STATE: 643 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 644 slot_name(p_slot)); 645 break; 646 case BLINKINGOFF_STATE: 647 case POWEROFF_STATE: 648 ctrl_info(ctrl, "Already enabled on slot %s\n", 649 slot_name(p_slot)); 650 break; 651 default: 652 ctrl_err(ctrl, "Not a valid state on slot %s\n", 653 slot_name(p_slot)); 654 break; 655 } 656 mutex_unlock(&p_slot->lock); 657 658 return retval; 659 } 660 661 int pciehp_sysfs_disable_slot(struct slot *p_slot) 662 { 663 int retval = -ENODEV; 664 struct controller *ctrl = p_slot->ctrl; 665 666 mutex_lock(&p_slot->lock); 667 switch (p_slot->state) { 668 case BLINKINGOFF_STATE: 669 cancel_delayed_work(&p_slot->work); 670 case STATIC_STATE: 671 p_slot->state = POWEROFF_STATE; 672 mutex_unlock(&p_slot->lock); 673 retval = pciehp_disable_slot(p_slot); 674 mutex_lock(&p_slot->lock); 675 p_slot->state = STATIC_STATE; 676 break; 677 case POWEROFF_STATE: 678 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 679 slot_name(p_slot)); 680 break; 681 case BLINKINGON_STATE: 682 case POWERON_STATE: 683 ctrl_info(ctrl, "Already disabled on slot %s\n", 684 slot_name(p_slot)); 685 break; 686 default: 687 ctrl_err(ctrl, "Not a valid state on slot %s\n", 688 slot_name(p_slot)); 689 break; 690 } 691 mutex_unlock(&p_slot->lock); 692 693 return retval; 694 } 695