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 shpchp_unconfigure_device(p_slot); 345 346 hp_slot = p_slot->device - ctrl->slot_device_offset; 347 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 348 349 ctrl_dbg(ctrl, "%s: hp_slot = %d\n", __func__, hp_slot); 350 351 /* Change status to shutdown */ 352 if (p_slot->is_a_board) 353 p_slot->status = 0x01; 354 355 /* turn off slot, turn on Amber LED, turn off Green LED */ 356 rc = p_slot->hpc_ops->slot_disable(p_slot); 357 if (rc) { 358 ctrl_err(ctrl, "%s: Issue of Slot Disable command failed\n", 359 __func__); 360 return rc; 361 } 362 363 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); 364 if (rc) { 365 ctrl_err(ctrl, "Issue of Set Attention command failed\n"); 366 return rc; 367 } 368 369 p_slot->pwr_save = 0; 370 p_slot->is_a_board = 0; 371 372 return 0; 373 } 374 375 376 struct pushbutton_work_info { 377 struct slot *p_slot; 378 struct work_struct work; 379 }; 380 381 /** 382 * shpchp_pushbutton_thread - handle pushbutton events 383 * @work: &struct work_struct to be handled 384 * 385 * Scheduled procedure to handle blocking stuff for the pushbuttons. 386 * Handles all pending events and exits. 387 */ 388 static void shpchp_pushbutton_thread(struct work_struct *work) 389 { 390 struct pushbutton_work_info *info = 391 container_of(work, struct pushbutton_work_info, work); 392 struct slot *p_slot = info->p_slot; 393 394 mutex_lock(&p_slot->lock); 395 switch (p_slot->state) { 396 case POWEROFF_STATE: 397 mutex_unlock(&p_slot->lock); 398 shpchp_disable_slot(p_slot); 399 mutex_lock(&p_slot->lock); 400 p_slot->state = STATIC_STATE; 401 break; 402 case POWERON_STATE: 403 mutex_unlock(&p_slot->lock); 404 if (shpchp_enable_slot(p_slot)) 405 p_slot->hpc_ops->green_led_off(p_slot); 406 mutex_lock(&p_slot->lock); 407 p_slot->state = STATIC_STATE; 408 break; 409 default: 410 break; 411 } 412 mutex_unlock(&p_slot->lock); 413 414 kfree(info); 415 } 416 417 void shpchp_queue_pushbutton_work(struct work_struct *work) 418 { 419 struct slot *p_slot = container_of(work, struct slot, work.work); 420 struct pushbutton_work_info *info; 421 422 info = kmalloc(sizeof(*info), GFP_KERNEL); 423 if (!info) { 424 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 425 __func__); 426 return; 427 } 428 info->p_slot = p_slot; 429 INIT_WORK(&info->work, shpchp_pushbutton_thread); 430 431 mutex_lock(&p_slot->lock); 432 switch (p_slot->state) { 433 case BLINKINGOFF_STATE: 434 p_slot->state = POWEROFF_STATE; 435 break; 436 case BLINKINGON_STATE: 437 p_slot->state = POWERON_STATE; 438 break; 439 default: 440 kfree(info); 441 goto out; 442 } 443 queue_work(p_slot->wq, &info->work); 444 out: 445 mutex_unlock(&p_slot->lock); 446 } 447 448 static void update_slot_info(struct slot *slot) 449 { 450 slot->hpc_ops->get_power_status(slot, &slot->pwr_save); 451 slot->hpc_ops->get_attention_status(slot, &slot->attention_save); 452 slot->hpc_ops->get_latch_status(slot, &slot->latch_save); 453 slot->hpc_ops->get_adapter_status(slot, &slot->presence_save); 454 } 455 456 /* 457 * Note: This function must be called with slot->lock held 458 */ 459 static void handle_button_press_event(struct slot *p_slot) 460 { 461 u8 getstatus; 462 struct controller *ctrl = p_slot->ctrl; 463 464 switch (p_slot->state) { 465 case STATIC_STATE: 466 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 467 if (getstatus) { 468 p_slot->state = BLINKINGOFF_STATE; 469 ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", 470 slot_name(p_slot)); 471 } else { 472 p_slot->state = BLINKINGON_STATE; 473 ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", 474 slot_name(p_slot)); 475 } 476 /* blink green LED and turn off amber */ 477 p_slot->hpc_ops->green_led_blink(p_slot); 478 p_slot->hpc_ops->set_attention_status(p_slot, 0); 479 480 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 481 break; 482 case BLINKINGOFF_STATE: 483 case BLINKINGON_STATE: 484 /* 485 * Cancel if we are still blinking; this means that we 486 * press the attention again before the 5 sec. limit 487 * expires to cancel hot-add or hot-remove 488 */ 489 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", 490 slot_name(p_slot)); 491 cancel_delayed_work(&p_slot->work); 492 if (p_slot->state == BLINKINGOFF_STATE) 493 p_slot->hpc_ops->green_led_on(p_slot); 494 else 495 p_slot->hpc_ops->green_led_off(p_slot); 496 p_slot->hpc_ops->set_attention_status(p_slot, 0); 497 ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", 498 slot_name(p_slot)); 499 p_slot->state = STATIC_STATE; 500 break; 501 case POWEROFF_STATE: 502 case POWERON_STATE: 503 /* 504 * Ignore if the slot is on power-on or power-off state; 505 * this means that the previous attention button action 506 * to hot-add or hot-remove is undergoing 507 */ 508 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", 509 slot_name(p_slot)); 510 update_slot_info(p_slot); 511 break; 512 default: 513 ctrl_warn(ctrl, "Not a valid state\n"); 514 break; 515 } 516 } 517 518 static void interrupt_event_handler(struct work_struct *work) 519 { 520 struct event_info *info = container_of(work, struct event_info, work); 521 struct slot *p_slot = info->p_slot; 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 ctrl_dbg(p_slot->ctrl, "%s: Power fault\n", __func__); 530 p_slot->hpc_ops->set_attention_status(p_slot, 1); 531 p_slot->hpc_ops->green_led_off(p_slot); 532 break; 533 default: 534 update_slot_info(p_slot); 535 break; 536 } 537 mutex_unlock(&p_slot->lock); 538 539 kfree(info); 540 } 541 542 543 static int shpchp_enable_slot (struct slot *p_slot) 544 { 545 u8 getstatus = 0; 546 int rc, retval = -ENODEV; 547 struct controller *ctrl = p_slot->ctrl; 548 549 /* Check to see if (latch closed, card present, power off) */ 550 mutex_lock(&p_slot->ctrl->crit_sect); 551 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 552 if (rc || !getstatus) { 553 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 554 goto out; 555 } 556 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 557 if (rc || getstatus) { 558 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 559 goto out; 560 } 561 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 562 if (rc || getstatus) { 563 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 564 slot_name(p_slot)); 565 goto out; 566 } 567 568 p_slot->is_a_board = 1; 569 570 /* We have to save the presence info for these slots */ 571 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 572 p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save)); 573 ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); 574 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 575 576 if ((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD && 577 p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458) 578 && p_slot->ctrl->num_slots == 1) { 579 /* handle AMD POGO errata; this must be done before enable */ 580 amd_pogo_errata_save_misc_reg(p_slot); 581 retval = board_added(p_slot); 582 /* handle AMD POGO errata; this must be done after enable */ 583 amd_pogo_errata_restore_misc_reg(p_slot); 584 } else 585 retval = board_added(p_slot); 586 587 if (retval) { 588 p_slot->hpc_ops->get_adapter_status(p_slot, 589 &(p_slot->presence_save)); 590 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 591 } 592 593 update_slot_info(p_slot); 594 out: 595 mutex_unlock(&p_slot->ctrl->crit_sect); 596 return retval; 597 } 598 599 600 static int shpchp_disable_slot (struct slot *p_slot) 601 { 602 u8 getstatus = 0; 603 int rc, retval = -ENODEV; 604 struct controller *ctrl = p_slot->ctrl; 605 606 if (!p_slot->ctrl) 607 return -ENODEV; 608 609 /* Check to see if (latch closed, card present, power on) */ 610 mutex_lock(&p_slot->ctrl->crit_sect); 611 612 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 613 if (rc || !getstatus) { 614 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 615 goto out; 616 } 617 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 618 if (rc || getstatus) { 619 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 620 goto out; 621 } 622 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 623 if (rc || !getstatus) { 624 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 625 slot_name(p_slot)); 626 goto out; 627 } 628 629 retval = remove_board(p_slot); 630 update_slot_info(p_slot); 631 out: 632 mutex_unlock(&p_slot->ctrl->crit_sect); 633 return retval; 634 } 635 636 int shpchp_sysfs_enable_slot(struct slot *p_slot) 637 { 638 int retval = -ENODEV; 639 struct controller *ctrl = p_slot->ctrl; 640 641 mutex_lock(&p_slot->lock); 642 switch (p_slot->state) { 643 case BLINKINGON_STATE: 644 cancel_delayed_work(&p_slot->work); 645 /* fall through */ 646 case STATIC_STATE: 647 p_slot->state = POWERON_STATE; 648 mutex_unlock(&p_slot->lock); 649 retval = shpchp_enable_slot(p_slot); 650 mutex_lock(&p_slot->lock); 651 p_slot->state = STATIC_STATE; 652 break; 653 case POWERON_STATE: 654 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 655 slot_name(p_slot)); 656 break; 657 case BLINKINGOFF_STATE: 658 case POWEROFF_STATE: 659 ctrl_info(ctrl, "Already enabled on slot %s\n", 660 slot_name(p_slot)); 661 break; 662 default: 663 ctrl_err(ctrl, "Not a valid state on slot %s\n", 664 slot_name(p_slot)); 665 break; 666 } 667 mutex_unlock(&p_slot->lock); 668 669 return retval; 670 } 671 672 int shpchp_sysfs_disable_slot(struct slot *p_slot) 673 { 674 int retval = -ENODEV; 675 struct controller *ctrl = p_slot->ctrl; 676 677 mutex_lock(&p_slot->lock); 678 switch (p_slot->state) { 679 case BLINKINGOFF_STATE: 680 cancel_delayed_work(&p_slot->work); 681 /* fall through */ 682 case STATIC_STATE: 683 p_slot->state = POWEROFF_STATE; 684 mutex_unlock(&p_slot->lock); 685 retval = shpchp_disable_slot(p_slot); 686 mutex_lock(&p_slot->lock); 687 p_slot->state = STATIC_STATE; 688 break; 689 case POWEROFF_STATE: 690 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 691 slot_name(p_slot)); 692 break; 693 case BLINKINGON_STATE: 694 case POWERON_STATE: 695 ctrl_info(ctrl, "Already disabled on slot %s\n", 696 slot_name(p_slot)); 697 break; 698 default: 699 ctrl_err(ctrl, "Not a valid state on slot %s\n", 700 slot_name(p_slot)); 701 break; 702 } 703 mutex_unlock(&p_slot->lock); 704 705 return retval; 706 } 707