1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Standard Hot Plug Controller Driver 4 * 5 * Copyright (C) 1995,2001 Compaq Computer Corporation 6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 7 * Copyright (C) 2001 IBM Corp. 8 * Copyright (C) 2003-2004 Intel Corporation 9 * 10 * All rights reserved. 11 * 12 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 13 * 14 */ 15 16 #include <linux/module.h> 17 #include <linux/kernel.h> 18 #include <linux/types.h> 19 #include <linux/slab.h> 20 #include <linux/pci.h> 21 #include "../pci.h" 22 #include "shpchp.h" 23 24 static void interrupt_event_handler(struct work_struct *work); 25 static int shpchp_enable_slot(struct slot *p_slot); 26 static int shpchp_disable_slot(struct slot *p_slot); 27 28 static int queue_interrupt_event(struct slot *p_slot, u32 event_type) 29 { 30 struct event_info *info; 31 32 info = kmalloc(sizeof(*info), GFP_ATOMIC); 33 if (!info) 34 return -ENOMEM; 35 36 info->event_type = event_type; 37 info->p_slot = p_slot; 38 INIT_WORK(&info->work, interrupt_event_handler); 39 40 queue_work(p_slot->wq, &info->work); 41 42 return 0; 43 } 44 45 u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) 46 { 47 struct slot *p_slot; 48 u32 event_type; 49 50 /* Attention Button Change */ 51 ctrl_dbg(ctrl, "Attention button interrupt received\n"); 52 53 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 54 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 55 56 /* 57 * Button pressed - See if need to TAKE ACTION!!! 58 */ 59 ctrl_info(ctrl, "Button pressed on Slot(%s)\n", slot_name(p_slot)); 60 event_type = INT_BUTTON_PRESS; 61 62 queue_interrupt_event(p_slot, event_type); 63 64 return 0; 65 66 } 67 68 u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl) 69 { 70 struct slot *p_slot; 71 u8 getstatus; 72 u32 event_type; 73 74 /* Switch Change */ 75 ctrl_dbg(ctrl, "Switch interrupt received\n"); 76 77 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 78 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 79 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 80 ctrl_dbg(ctrl, "Card present %x Power status %x\n", 81 p_slot->presence_save, p_slot->pwr_save); 82 83 if (getstatus) { 84 /* 85 * Switch opened 86 */ 87 ctrl_info(ctrl, "Latch open on Slot(%s)\n", slot_name(p_slot)); 88 event_type = INT_SWITCH_OPEN; 89 if (p_slot->pwr_save && p_slot->presence_save) { 90 event_type = INT_POWER_FAULT; 91 ctrl_err(ctrl, "Surprise Removal of card\n"); 92 } 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 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) 107 { 108 struct slot *p_slot; 109 u32 event_type; 110 111 /* Presence Change */ 112 ctrl_dbg(ctrl, "Presence/Notify input change\n"); 113 114 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 115 116 /* 117 * Save the presence state 118 */ 119 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 120 if (p_slot->presence_save) { 121 /* 122 * Card Present 123 */ 124 ctrl_info(ctrl, "Card present on Slot(%s)\n", 125 slot_name(p_slot)); 126 event_type = INT_PRESENCE_ON; 127 } else { 128 /* 129 * Not Present 130 */ 131 ctrl_info(ctrl, "Card not present on Slot(%s)\n", 132 slot_name(p_slot)); 133 event_type = INT_PRESENCE_OFF; 134 } 135 136 queue_interrupt_event(p_slot, event_type); 137 138 return 1; 139 } 140 141 u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) 142 { 143 struct slot *p_slot; 144 u32 event_type; 145 146 /* Power fault */ 147 ctrl_dbg(ctrl, "Power fault interrupt received\n"); 148 149 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 150 151 if (!(p_slot->hpc_ops->query_power_fault(p_slot))) { 152 /* 153 * Power fault Cleared 154 */ 155 ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", 156 slot_name(p_slot)); 157 p_slot->status = 0x00; 158 event_type = INT_POWER_FAULT_CLEAR; 159 } else { 160 /* 161 * Power fault 162 */ 163 ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot)); 164 event_type = INT_POWER_FAULT; 165 /* set power fault status for this board */ 166 p_slot->status = 0xFF; 167 ctrl_info(ctrl, "Power fault bit %x set\n", hp_slot); 168 } 169 170 queue_interrupt_event(p_slot, event_type); 171 172 return 1; 173 } 174 175 /* The following routines constitute the bulk of the 176 hotplug controller logic 177 */ 178 static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, 179 enum pci_bus_speed speed) 180 { 181 int rc = 0; 182 183 ctrl_dbg(ctrl, "Change speed to %d\n", speed); 184 rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed); 185 if (rc) { 186 ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", 187 __func__); 188 return WRONG_BUS_FREQUENCY; 189 } 190 return rc; 191 } 192 193 static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, 194 u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, 195 enum pci_bus_speed msp) 196 { 197 int rc = 0; 198 199 /* 200 * If other slots on the same bus are occupied, we cannot 201 * change the bus speed. 202 */ 203 if (flag) { 204 if (asp < bsp) { 205 ctrl_err(ctrl, "Speed of bus %x and adapter %x mismatch\n", 206 bsp, asp); 207 rc = WRONG_BUS_FREQUENCY; 208 } 209 return rc; 210 } 211 212 if (asp < msp) { 213 if (bsp != asp) 214 rc = change_bus_speed(ctrl, pslot, asp); 215 } else { 216 if (bsp != msp) 217 rc = change_bus_speed(ctrl, pslot, msp); 218 } 219 return rc; 220 } 221 222 /** 223 * board_added - Called after a board has been added to the system. 224 * @p_slot: target &slot 225 * 226 * Turns power on for the board. 227 * Configures board. 228 */ 229 static int board_added(struct slot *p_slot) 230 { 231 u8 hp_slot; 232 u8 slots_not_empty = 0; 233 int rc = 0; 234 enum pci_bus_speed asp, bsp, msp; 235 struct controller *ctrl = p_slot->ctrl; 236 struct pci_bus *parent = ctrl->pci_dev->subordinate; 237 238 hp_slot = p_slot->device - ctrl->slot_device_offset; 239 240 ctrl_dbg(ctrl, "%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n", 241 __func__, p_slot->device, ctrl->slot_device_offset, hp_slot); 242 243 /* Power on slot without connecting to bus */ 244 rc = p_slot->hpc_ops->power_on_slot(p_slot); 245 if (rc) { 246 ctrl_err(ctrl, "Failed to power on slot\n"); 247 return -1; 248 } 249 250 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { 251 rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz); 252 if (rc) { 253 ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", 254 __func__); 255 return WRONG_BUS_FREQUENCY; 256 } 257 258 /* turn on board, blink green LED, turn off Amber LED */ 259 rc = p_slot->hpc_ops->slot_enable(p_slot); 260 if (rc) { 261 ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); 262 return rc; 263 } 264 } 265 266 rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); 267 if (rc) { 268 ctrl_err(ctrl, "Can't get adapter speed or bus mode mismatch\n"); 269 return WRONG_BUS_FREQUENCY; 270 } 271 272 bsp = ctrl->pci_dev->subordinate->cur_bus_speed; 273 msp = ctrl->pci_dev->subordinate->max_bus_speed; 274 275 /* Check if there are other slots or devices on the same bus */ 276 if (!list_empty(&ctrl->pci_dev->subordinate->devices)) 277 slots_not_empty = 1; 278 279 ctrl_dbg(ctrl, "%s: slots_not_empty %d, adapter_speed %d, bus_speed %d, max_bus_speed %d\n", 280 __func__, slots_not_empty, asp, 281 bsp, msp); 282 283 rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp); 284 if (rc) 285 return rc; 286 287 /* turn on board, blink green LED, turn off Amber LED */ 288 rc = p_slot->hpc_ops->slot_enable(p_slot); 289 if (rc) { 290 ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); 291 return rc; 292 } 293 294 /* Wait for ~1 second */ 295 msleep(1000); 296 297 ctrl_dbg(ctrl, "%s: slot status = %x\n", __func__, p_slot->status); 298 /* Check for a power fault */ 299 if (p_slot->status == 0xFF) { 300 /* power fault occurred, but it was benign */ 301 ctrl_dbg(ctrl, "%s: Power fault\n", __func__); 302 rc = POWER_FAILURE; 303 p_slot->status = 0; 304 goto err_exit; 305 } 306 307 if (shpchp_configure_device(p_slot)) { 308 ctrl_err(ctrl, "Cannot add device at %04x:%02x:%02x\n", 309 pci_domain_nr(parent), p_slot->bus, p_slot->device); 310 goto err_exit; 311 } 312 313 p_slot->status = 0; 314 p_slot->is_a_board = 0x01; 315 p_slot->pwr_save = 1; 316 317 p_slot->hpc_ops->green_led_on(p_slot); 318 319 return 0; 320 321 err_exit: 322 /* turn off slot, turn on Amber LED, turn off Green LED */ 323 rc = p_slot->hpc_ops->slot_disable(p_slot); 324 if (rc) { 325 ctrl_err(ctrl, "%s: Issue of Slot Disable command failed\n", 326 __func__); 327 return rc; 328 } 329 330 return(rc); 331 } 332 333 334 /** 335 * remove_board - Turns off slot and LEDs 336 * @p_slot: target &slot 337 */ 338 static int remove_board(struct slot *p_slot) 339 { 340 struct controller *ctrl = p_slot->ctrl; 341 u8 hp_slot; 342 int rc; 343 344 if (shpchp_unconfigure_device(p_slot)) 345 return(1); 346 347 hp_slot = p_slot->device - ctrl->slot_device_offset; 348 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 349 350 ctrl_dbg(ctrl, "%s: hp_slot = %d\n", __func__, hp_slot); 351 352 /* Change status to shutdown */ 353 if (p_slot->is_a_board) 354 p_slot->status = 0x01; 355 356 /* turn off slot, turn on Amber LED, turn off Green LED */ 357 rc = p_slot->hpc_ops->slot_disable(p_slot); 358 if (rc) { 359 ctrl_err(ctrl, "%s: Issue of Slot Disable command failed\n", 360 __func__); 361 return rc; 362 } 363 364 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); 365 if (rc) { 366 ctrl_err(ctrl, "Issue of Set Attention command failed\n"); 367 return rc; 368 } 369 370 p_slot->pwr_save = 0; 371 p_slot->is_a_board = 0; 372 373 return 0; 374 } 375 376 377 struct pushbutton_work_info { 378 struct slot *p_slot; 379 struct work_struct work; 380 }; 381 382 /** 383 * shpchp_pushbutton_thread - handle pushbutton events 384 * @work: &struct work_struct to be handled 385 * 386 * Scheduled procedure to handle blocking stuff for the pushbuttons. 387 * Handles all pending events and exits. 388 */ 389 static void shpchp_pushbutton_thread(struct work_struct *work) 390 { 391 struct pushbutton_work_info *info = 392 container_of(work, struct pushbutton_work_info, work); 393 struct slot *p_slot = info->p_slot; 394 395 mutex_lock(&p_slot->lock); 396 switch (p_slot->state) { 397 case POWEROFF_STATE: 398 mutex_unlock(&p_slot->lock); 399 shpchp_disable_slot(p_slot); 400 mutex_lock(&p_slot->lock); 401 p_slot->state = STATIC_STATE; 402 break; 403 case POWERON_STATE: 404 mutex_unlock(&p_slot->lock); 405 if (shpchp_enable_slot(p_slot)) 406 p_slot->hpc_ops->green_led_off(p_slot); 407 mutex_lock(&p_slot->lock); 408 p_slot->state = STATIC_STATE; 409 break; 410 default: 411 break; 412 } 413 mutex_unlock(&p_slot->lock); 414 415 kfree(info); 416 } 417 418 void shpchp_queue_pushbutton_work(struct work_struct *work) 419 { 420 struct slot *p_slot = container_of(work, struct slot, work.work); 421 struct pushbutton_work_info *info; 422 423 info = kmalloc(sizeof(*info), GFP_KERNEL); 424 if (!info) { 425 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 426 __func__); 427 return; 428 } 429 info->p_slot = p_slot; 430 INIT_WORK(&info->work, shpchp_pushbutton_thread); 431 432 mutex_lock(&p_slot->lock); 433 switch (p_slot->state) { 434 case BLINKINGOFF_STATE: 435 p_slot->state = POWEROFF_STATE; 436 break; 437 case BLINKINGON_STATE: 438 p_slot->state = POWERON_STATE; 439 break; 440 default: 441 kfree(info); 442 goto out; 443 } 444 queue_work(p_slot->wq, &info->work); 445 out: 446 mutex_unlock(&p_slot->lock); 447 } 448 449 static int update_slot_info (struct slot *slot) 450 { 451 struct hotplug_slot_info *info; 452 int result; 453 454 info = kmalloc(sizeof(*info), GFP_KERNEL); 455 if (!info) 456 return -ENOMEM; 457 458 slot->hpc_ops->get_power_status(slot, &(info->power_status)); 459 slot->hpc_ops->get_attention_status(slot, &(info->attention_status)); 460 slot->hpc_ops->get_latch_status(slot, &(info->latch_status)); 461 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status)); 462 463 result = pci_hp_change_slot_info(slot->hotplug_slot, info); 464 kfree (info); 465 return result; 466 } 467 468 /* 469 * Note: This function must be called with slot->lock held 470 */ 471 static void handle_button_press_event(struct slot *p_slot) 472 { 473 u8 getstatus; 474 struct controller *ctrl = p_slot->ctrl; 475 476 switch (p_slot->state) { 477 case STATIC_STATE: 478 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 479 if (getstatus) { 480 p_slot->state = BLINKINGOFF_STATE; 481 ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", 482 slot_name(p_slot)); 483 } else { 484 p_slot->state = BLINKINGON_STATE; 485 ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", 486 slot_name(p_slot)); 487 } 488 /* blink green LED and turn off amber */ 489 p_slot->hpc_ops->green_led_blink(p_slot); 490 p_slot->hpc_ops->set_attention_status(p_slot, 0); 491 492 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 493 break; 494 case BLINKINGOFF_STATE: 495 case BLINKINGON_STATE: 496 /* 497 * Cancel if we are still blinking; this means that we 498 * press the attention again before the 5 sec. limit 499 * expires to cancel hot-add or hot-remove 500 */ 501 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", 502 slot_name(p_slot)); 503 cancel_delayed_work(&p_slot->work); 504 if (p_slot->state == BLINKINGOFF_STATE) 505 p_slot->hpc_ops->green_led_on(p_slot); 506 else 507 p_slot->hpc_ops->green_led_off(p_slot); 508 p_slot->hpc_ops->set_attention_status(p_slot, 0); 509 ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", 510 slot_name(p_slot)); 511 p_slot->state = STATIC_STATE; 512 break; 513 case POWEROFF_STATE: 514 case POWERON_STATE: 515 /* 516 * Ignore if the slot is on power-on or power-off state; 517 * this means that the previous attention button action 518 * to hot-add or hot-remove is undergoing 519 */ 520 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", 521 slot_name(p_slot)); 522 update_slot_info(p_slot); 523 break; 524 default: 525 ctrl_warn(ctrl, "Not a valid state\n"); 526 break; 527 } 528 } 529 530 static void interrupt_event_handler(struct work_struct *work) 531 { 532 struct event_info *info = container_of(work, struct event_info, work); 533 struct slot *p_slot = info->p_slot; 534 535 mutex_lock(&p_slot->lock); 536 switch (info->event_type) { 537 case INT_BUTTON_PRESS: 538 handle_button_press_event(p_slot); 539 break; 540 case INT_POWER_FAULT: 541 ctrl_dbg(p_slot->ctrl, "%s: Power fault\n", __func__); 542 p_slot->hpc_ops->set_attention_status(p_slot, 1); 543 p_slot->hpc_ops->green_led_off(p_slot); 544 break; 545 default: 546 update_slot_info(p_slot); 547 break; 548 } 549 mutex_unlock(&p_slot->lock); 550 551 kfree(info); 552 } 553 554 555 static int shpchp_enable_slot (struct slot *p_slot) 556 { 557 u8 getstatus = 0; 558 int rc, retval = -ENODEV; 559 struct controller *ctrl = p_slot->ctrl; 560 561 /* Check to see if (latch closed, card present, power off) */ 562 mutex_lock(&p_slot->ctrl->crit_sect); 563 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 564 if (rc || !getstatus) { 565 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 566 goto out; 567 } 568 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 569 if (rc || getstatus) { 570 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 571 goto out; 572 } 573 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 574 if (rc || getstatus) { 575 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 576 slot_name(p_slot)); 577 goto out; 578 } 579 580 p_slot->is_a_board = 1; 581 582 /* We have to save the presence info for these slots */ 583 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 584 p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save)); 585 ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); 586 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 587 588 if ((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD && 589 p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458) 590 && p_slot->ctrl->num_slots == 1) { 591 /* handle AMD POGO errata; this must be done before enable */ 592 amd_pogo_errata_save_misc_reg(p_slot); 593 retval = board_added(p_slot); 594 /* handle AMD POGO errata; this must be done after enable */ 595 amd_pogo_errata_restore_misc_reg(p_slot); 596 } else 597 retval = board_added(p_slot); 598 599 if (retval) { 600 p_slot->hpc_ops->get_adapter_status(p_slot, 601 &(p_slot->presence_save)); 602 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 603 } 604 605 update_slot_info(p_slot); 606 out: 607 mutex_unlock(&p_slot->ctrl->crit_sect); 608 return retval; 609 } 610 611 612 static int shpchp_disable_slot (struct slot *p_slot) 613 { 614 u8 getstatus = 0; 615 int rc, retval = -ENODEV; 616 struct controller *ctrl = p_slot->ctrl; 617 618 if (!p_slot->ctrl) 619 return -ENODEV; 620 621 /* Check to see if (latch closed, card present, power on) */ 622 mutex_lock(&p_slot->ctrl->crit_sect); 623 624 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 625 if (rc || !getstatus) { 626 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 627 goto out; 628 } 629 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 630 if (rc || getstatus) { 631 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 632 goto out; 633 } 634 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 635 if (rc || !getstatus) { 636 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 637 slot_name(p_slot)); 638 goto out; 639 } 640 641 retval = remove_board(p_slot); 642 update_slot_info(p_slot); 643 out: 644 mutex_unlock(&p_slot->ctrl->crit_sect); 645 return retval; 646 } 647 648 int shpchp_sysfs_enable_slot(struct slot *p_slot) 649 { 650 int retval = -ENODEV; 651 struct controller *ctrl = p_slot->ctrl; 652 653 mutex_lock(&p_slot->lock); 654 switch (p_slot->state) { 655 case BLINKINGON_STATE: 656 cancel_delayed_work(&p_slot->work); 657 case STATIC_STATE: 658 p_slot->state = POWERON_STATE; 659 mutex_unlock(&p_slot->lock); 660 retval = shpchp_enable_slot(p_slot); 661 mutex_lock(&p_slot->lock); 662 p_slot->state = STATIC_STATE; 663 break; 664 case POWERON_STATE: 665 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 666 slot_name(p_slot)); 667 break; 668 case BLINKINGOFF_STATE: 669 case POWEROFF_STATE: 670 ctrl_info(ctrl, "Already enabled on slot %s\n", 671 slot_name(p_slot)); 672 break; 673 default: 674 ctrl_err(ctrl, "Not a valid state on slot %s\n", 675 slot_name(p_slot)); 676 break; 677 } 678 mutex_unlock(&p_slot->lock); 679 680 return retval; 681 } 682 683 int shpchp_sysfs_disable_slot(struct slot *p_slot) 684 { 685 int retval = -ENODEV; 686 struct controller *ctrl = p_slot->ctrl; 687 688 mutex_lock(&p_slot->lock); 689 switch (p_slot->state) { 690 case BLINKINGOFF_STATE: 691 cancel_delayed_work(&p_slot->work); 692 case STATIC_STATE: 693 p_slot->state = POWEROFF_STATE; 694 mutex_unlock(&p_slot->lock); 695 retval = shpchp_disable_slot(p_slot); 696 mutex_lock(&p_slot->lock); 697 p_slot->state = STATIC_STATE; 698 break; 699 case POWEROFF_STATE: 700 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 701 slot_name(p_slot)); 702 break; 703 case BLINKINGON_STATE: 704 case POWERON_STATE: 705 ctrl_info(ctrl, "Already disabled on slot %s\n", 706 slot_name(p_slot)); 707 break; 708 default: 709 ctrl_err(ctrl, "Not a valid state on slot %s\n", 710 slot_name(p_slot)); 711 break; 712 } 713 mutex_unlock(&p_slot->lock); 714 715 return retval; 716 } 717