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