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", p_slot->name); 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", p_slot->name); 92 event_type = INT_SWITCH_OPEN; 93 } else { 94 /* 95 * Switch closed 96 */ 97 ctrl_info(ctrl, "Latch close on Slot(%s)\n", p_slot->name); 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", p_slot->name); 124 event_type = INT_PRESENCE_ON; 125 } else { 126 /* 127 * Not Present 128 */ 129 ctrl_info(ctrl, "Card not present on Slot(%s)\n", p_slot->name); 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 146 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { 147 /* 148 * power fault Cleared 149 */ 150 ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", 151 p_slot->name); 152 event_type = INT_POWER_FAULT_CLEAR; 153 } else { 154 /* 155 * power fault 156 */ 157 ctrl_info(ctrl, "Power fault on Slot(%s)\n", p_slot->name); 158 event_type = INT_POWER_FAULT; 159 ctrl_info(ctrl, "power fault bit %x set\n", 0); 160 } 161 162 queue_interrupt_event(p_slot, event_type); 163 164 return 1; 165 } 166 167 /* The following routines constitute the bulk of the 168 hotplug controller logic 169 */ 170 171 static void set_slot_off(struct controller *ctrl, struct slot * pslot) 172 { 173 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ 174 if (POWER_CTRL(ctrl)) { 175 if (pslot->hpc_ops->power_off_slot(pslot)) { 176 ctrl_err(ctrl, 177 "%s: Issue of Slot Power Off command failed\n", 178 __func__); 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, "%s: Issue of Set Attention " 196 "Led command failed\n", __func__); 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 214 ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n", 215 __func__, p_slot->device, ctrl->slot_device_offset, 216 p_slot->hp_slot); 217 218 if (POWER_CTRL(ctrl)) { 219 /* Power on slot */ 220 retval = p_slot->hpc_ops->power_on_slot(p_slot); 221 if (retval) 222 return retval; 223 } 224 225 if (PWR_LED(ctrl)) 226 p_slot->hpc_ops->green_led_blink(p_slot); 227 228 /* Wait for ~1 second */ 229 msleep(1000); 230 231 /* Check link training status */ 232 retval = p_slot->hpc_ops->check_lnk_status(ctrl); 233 if (retval) { 234 ctrl_err(ctrl, "%s: Failed to check link status\n", __func__); 235 set_slot_off(ctrl, p_slot); 236 return retval; 237 } 238 239 /* Check for a power fault */ 240 if (p_slot->hpc_ops->query_power_fault(p_slot)) { 241 ctrl_dbg(ctrl, "%s: power fault detected\n", __func__); 242 retval = POWER_FAILURE; 243 goto err_exit; 244 } 245 246 retval = pciehp_configure_device(p_slot); 247 if (retval) { 248 ctrl_err(ctrl, "Cannot add device 0x%x:%x\n", 249 p_slot->bus, p_slot->device); 250 goto err_exit; 251 } 252 253 /* 254 * Some PCI Express root ports require fixup after hot-plug operation. 255 */ 256 if (pcie_mch_quirk) 257 pci_fixup_device(pci_fixup_final, ctrl->pci_dev); 258 if (PWR_LED(ctrl)) 259 p_slot->hpc_ops->green_led_on(p_slot); 260 261 return 0; 262 263 err_exit: 264 set_slot_off(ctrl, p_slot); 265 return retval; 266 } 267 268 /** 269 * remove_board - Turns off slot and LEDs 270 * @p_slot: slot where board is being removed 271 */ 272 static int remove_board(struct slot *p_slot) 273 { 274 int retval = 0; 275 struct controller *ctrl = p_slot->ctrl; 276 277 retval = pciehp_unconfigure_device(p_slot); 278 if (retval) 279 return retval; 280 281 ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); 282 283 if (POWER_CTRL(ctrl)) { 284 /* power off slot */ 285 retval = p_slot->hpc_ops->power_off_slot(p_slot); 286 if (retval) { 287 ctrl_err(ctrl, "%s: Issue of Slot Disable command " 288 "failed\n", __func__); 289 return retval; 290 } 291 } 292 293 /* 294 * After turning power off, we must wait for at least 1 second 295 * before taking any action that relies on power having been 296 * removed from the slot/adapter. 297 */ 298 msleep(1000); 299 300 if (PWR_LED(ctrl)) 301 /* turn off Green LED */ 302 p_slot->hpc_ops->green_led_off(p_slot); 303 304 return 0; 305 } 306 307 struct power_work_info { 308 struct slot *p_slot; 309 struct work_struct work; 310 }; 311 312 /** 313 * pciehp_power_thread - handle pushbutton events 314 * @work: &struct work_struct describing work to be done 315 * 316 * Scheduled procedure to handle blocking stuff for the pushbuttons. 317 * Handles all pending events and exits. 318 */ 319 static void pciehp_power_thread(struct work_struct *work) 320 { 321 struct power_work_info *info = 322 container_of(work, struct power_work_info, work); 323 struct slot *p_slot = info->p_slot; 324 325 mutex_lock(&p_slot->lock); 326 switch (p_slot->state) { 327 case POWEROFF_STATE: 328 mutex_unlock(&p_slot->lock); 329 ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n", 330 __func__, 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", p_slot->name); 416 } else { 417 p_slot->state = BLINKINGON_STATE; 418 ctrl_info(ctrl, 419 "PCI slot #%s - powering on due to button " 420 "press.\n", p_slot->name); 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", p_slot->name); 438 ctrl_dbg(ctrl, "%s: button cancel\n", __func__); 439 cancel_delayed_work(&p_slot->work); 440 if (p_slot->state == BLINKINGOFF_STATE) { 441 if (PWR_LED(ctrl)) 442 p_slot->hpc_ops->green_led_on(p_slot); 443 } else { 444 if (PWR_LED(ctrl)) 445 p_slot->hpc_ops->green_led_off(p_slot); 446 } 447 if (ATTN_LED(ctrl)) 448 p_slot->hpc_ops->set_attention_status(p_slot, 0); 449 ctrl_info(ctrl, "PCI slot #%s - action canceled " 450 "due to button press\n", p_slot->name); 451 p_slot->state = STATIC_STATE; 452 break; 453 case POWEROFF_STATE: 454 case POWERON_STATE: 455 /* 456 * Ignore if the slot is on power-on or power-off state; 457 * this means that the previous attention button action 458 * to hot-add or hot-remove is undergoing 459 */ 460 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", p_slot->name); 461 update_slot_info(p_slot); 462 break; 463 default: 464 ctrl_warn(ctrl, "Not a valid state\n"); 465 break; 466 } 467 } 468 469 /* 470 * Note: This function must be called with slot->lock held 471 */ 472 static void handle_surprise_event(struct slot *p_slot) 473 { 474 u8 getstatus; 475 struct power_work_info *info; 476 477 info = kmalloc(sizeof(*info), GFP_KERNEL); 478 if (!info) { 479 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 480 __func__); 481 return; 482 } 483 info->p_slot = p_slot; 484 INIT_WORK(&info->work, pciehp_power_thread); 485 486 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 487 if (!getstatus) 488 p_slot->state = POWEROFF_STATE; 489 else 490 p_slot->state = POWERON_STATE; 491 492 queue_work(pciehp_wq, &info->work); 493 } 494 495 static void interrupt_event_handler(struct work_struct *work) 496 { 497 struct event_info *info = container_of(work, struct event_info, work); 498 struct slot *p_slot = info->p_slot; 499 struct controller *ctrl = p_slot->ctrl; 500 501 mutex_lock(&p_slot->lock); 502 switch (info->event_type) { 503 case INT_BUTTON_PRESS: 504 handle_button_press_event(p_slot); 505 break; 506 case INT_POWER_FAULT: 507 if (!POWER_CTRL(ctrl)) 508 break; 509 if (ATTN_LED(ctrl)) 510 p_slot->hpc_ops->set_attention_status(p_slot, 1); 511 if (PWR_LED(ctrl)) 512 p_slot->hpc_ops->green_led_off(p_slot); 513 break; 514 case INT_PRESENCE_ON: 515 case INT_PRESENCE_OFF: 516 if (!HP_SUPR_RM(ctrl)) 517 break; 518 ctrl_dbg(ctrl, "Surprise Removal\n"); 519 update_slot_info(p_slot); 520 handle_surprise_event(p_slot); 521 break; 522 default: 523 update_slot_info(p_slot); 524 break; 525 } 526 mutex_unlock(&p_slot->lock); 527 528 kfree(info); 529 } 530 531 int pciehp_enable_slot(struct slot *p_slot) 532 { 533 u8 getstatus = 0; 534 int rc; 535 struct controller *ctrl = p_slot->ctrl; 536 537 /* Check to see if (latch closed, card present, power off) */ 538 mutex_lock(&p_slot->ctrl->crit_sect); 539 540 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 541 if (rc || !getstatus) { 542 ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", 543 __func__, p_slot->name); 544 mutex_unlock(&p_slot->ctrl->crit_sect); 545 return -ENODEV; 546 } 547 if (MRL_SENS(p_slot->ctrl)) { 548 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 549 if (rc || getstatus) { 550 ctrl_info(ctrl, "%s: latch open on slot(%s)\n", 551 __func__, p_slot->name); 552 mutex_unlock(&p_slot->ctrl->crit_sect); 553 return -ENODEV; 554 } 555 } 556 557 if (POWER_CTRL(p_slot->ctrl)) { 558 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 559 if (rc || getstatus) { 560 ctrl_info(ctrl, "%s: already enabled on slot(%s)\n", 561 __func__, p_slot->name); 562 mutex_unlock(&p_slot->ctrl->crit_sect); 563 return -EINVAL; 564 } 565 } 566 567 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 568 569 rc = board_added(p_slot); 570 if (rc) { 571 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 572 } 573 574 update_slot_info(p_slot); 575 576 mutex_unlock(&p_slot->ctrl->crit_sect); 577 return rc; 578 } 579 580 581 int pciehp_disable_slot(struct slot *p_slot) 582 { 583 u8 getstatus = 0; 584 int ret = 0; 585 struct controller *ctrl = p_slot->ctrl; 586 587 if (!p_slot->ctrl) 588 return 1; 589 590 /* Check to see if (latch closed, card present, power on) */ 591 mutex_lock(&p_slot->ctrl->crit_sect); 592 593 if (!HP_SUPR_RM(p_slot->ctrl)) { 594 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 595 if (ret || !getstatus) { 596 ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", 597 __func__, p_slot->name); 598 mutex_unlock(&p_slot->ctrl->crit_sect); 599 return -ENODEV; 600 } 601 } 602 603 if (MRL_SENS(p_slot->ctrl)) { 604 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 605 if (ret || getstatus) { 606 ctrl_info(ctrl, "%s: latch open on slot(%s)\n", 607 __func__, p_slot->name); 608 mutex_unlock(&p_slot->ctrl->crit_sect); 609 return -ENODEV; 610 } 611 } 612 613 if (POWER_CTRL(p_slot->ctrl)) { 614 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 615 if (ret || !getstatus) { 616 ctrl_info(ctrl, "%s: already disabled slot(%s)\n", 617 __func__, p_slot->name); 618 mutex_unlock(&p_slot->ctrl->crit_sect); 619 return -EINVAL; 620 } 621 } 622 623 ret = remove_board(p_slot); 624 update_slot_info(p_slot); 625 626 mutex_unlock(&p_slot->ctrl->crit_sect); 627 return ret; 628 } 629 630 int pciehp_sysfs_enable_slot(struct slot *p_slot) 631 { 632 int retval = -ENODEV; 633 struct controller *ctrl = p_slot->ctrl; 634 635 mutex_lock(&p_slot->lock); 636 switch (p_slot->state) { 637 case BLINKINGON_STATE: 638 cancel_delayed_work(&p_slot->work); 639 case STATIC_STATE: 640 p_slot->state = POWERON_STATE; 641 mutex_unlock(&p_slot->lock); 642 retval = pciehp_enable_slot(p_slot); 643 mutex_lock(&p_slot->lock); 644 p_slot->state = STATIC_STATE; 645 break; 646 case POWERON_STATE: 647 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 648 p_slot->name); 649 break; 650 case BLINKINGOFF_STATE: 651 case POWEROFF_STATE: 652 ctrl_info(ctrl, "Already enabled on slot %s\n", p_slot->name); 653 break; 654 default: 655 ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); 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 p_slot->name); 682 break; 683 case BLINKINGON_STATE: 684 case POWERON_STATE: 685 ctrl_info(ctrl, "Already disabled on slot %s\n", p_slot->name); 686 break; 687 default: 688 ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); 689 break; 690 } 691 mutex_unlock(&p_slot->lock); 692 693 return retval; 694 } 695