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 void update_slot_info(struct slot *slot) 450 { 451 slot->hpc_ops->get_power_status(slot, &slot->pwr_save); 452 slot->hpc_ops->get_attention_status(slot, &slot->attention_save); 453 slot->hpc_ops->get_latch_status(slot, &slot->latch_save); 454 slot->hpc_ops->get_adapter_status(slot, &slot->presence_save); 455 } 456 457 /* 458 * Note: This function must be called with slot->lock held 459 */ 460 static void handle_button_press_event(struct slot *p_slot) 461 { 462 u8 getstatus; 463 struct controller *ctrl = p_slot->ctrl; 464 465 switch (p_slot->state) { 466 case STATIC_STATE: 467 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 468 if (getstatus) { 469 p_slot->state = BLINKINGOFF_STATE; 470 ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n", 471 slot_name(p_slot)); 472 } else { 473 p_slot->state = BLINKINGON_STATE; 474 ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n", 475 slot_name(p_slot)); 476 } 477 /* blink green LED and turn off amber */ 478 p_slot->hpc_ops->green_led_blink(p_slot); 479 p_slot->hpc_ops->set_attention_status(p_slot, 0); 480 481 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); 482 break; 483 case BLINKINGOFF_STATE: 484 case BLINKINGON_STATE: 485 /* 486 * Cancel if we are still blinking; this means that we 487 * press the attention again before the 5 sec. limit 488 * expires to cancel hot-add or hot-remove 489 */ 490 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", 491 slot_name(p_slot)); 492 cancel_delayed_work(&p_slot->work); 493 if (p_slot->state == BLINKINGOFF_STATE) 494 p_slot->hpc_ops->green_led_on(p_slot); 495 else 496 p_slot->hpc_ops->green_led_off(p_slot); 497 p_slot->hpc_ops->set_attention_status(p_slot, 0); 498 ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n", 499 slot_name(p_slot)); 500 p_slot->state = STATIC_STATE; 501 break; 502 case POWEROFF_STATE: 503 case POWERON_STATE: 504 /* 505 * Ignore if the slot is on power-on or power-off state; 506 * this means that the previous attention button action 507 * to hot-add or hot-remove is undergoing 508 */ 509 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", 510 slot_name(p_slot)); 511 update_slot_info(p_slot); 512 break; 513 default: 514 ctrl_warn(ctrl, "Not a valid state\n"); 515 break; 516 } 517 } 518 519 static void interrupt_event_handler(struct work_struct *work) 520 { 521 struct event_info *info = container_of(work, struct event_info, work); 522 struct slot *p_slot = info->p_slot; 523 524 mutex_lock(&p_slot->lock); 525 switch (info->event_type) { 526 case INT_BUTTON_PRESS: 527 handle_button_press_event(p_slot); 528 break; 529 case INT_POWER_FAULT: 530 ctrl_dbg(p_slot->ctrl, "%s: Power fault\n", __func__); 531 p_slot->hpc_ops->set_attention_status(p_slot, 1); 532 p_slot->hpc_ops->green_led_off(p_slot); 533 break; 534 default: 535 update_slot_info(p_slot); 536 break; 537 } 538 mutex_unlock(&p_slot->lock); 539 540 kfree(info); 541 } 542 543 544 static int shpchp_enable_slot (struct slot *p_slot) 545 { 546 u8 getstatus = 0; 547 int rc, retval = -ENODEV; 548 struct controller *ctrl = p_slot->ctrl; 549 550 /* Check to see if (latch closed, card present, power off) */ 551 mutex_lock(&p_slot->ctrl->crit_sect); 552 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 553 if (rc || !getstatus) { 554 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 555 goto out; 556 } 557 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 558 if (rc || getstatus) { 559 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 560 goto out; 561 } 562 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 563 if (rc || getstatus) { 564 ctrl_info(ctrl, "Already enabled on slot(%s)\n", 565 slot_name(p_slot)); 566 goto out; 567 } 568 569 p_slot->is_a_board = 1; 570 571 /* We have to save the presence info for these slots */ 572 p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); 573 p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save)); 574 ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); 575 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 576 577 if ((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD && 578 p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458) 579 && p_slot->ctrl->num_slots == 1) { 580 /* handle AMD POGO errata; this must be done before enable */ 581 amd_pogo_errata_save_misc_reg(p_slot); 582 retval = board_added(p_slot); 583 /* handle AMD POGO errata; this must be done after enable */ 584 amd_pogo_errata_restore_misc_reg(p_slot); 585 } else 586 retval = board_added(p_slot); 587 588 if (retval) { 589 p_slot->hpc_ops->get_adapter_status(p_slot, 590 &(p_slot->presence_save)); 591 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 592 } 593 594 update_slot_info(p_slot); 595 out: 596 mutex_unlock(&p_slot->ctrl->crit_sect); 597 return retval; 598 } 599 600 601 static int shpchp_disable_slot (struct slot *p_slot) 602 { 603 u8 getstatus = 0; 604 int rc, retval = -ENODEV; 605 struct controller *ctrl = p_slot->ctrl; 606 607 if (!p_slot->ctrl) 608 return -ENODEV; 609 610 /* Check to see if (latch closed, card present, power on) */ 611 mutex_lock(&p_slot->ctrl->crit_sect); 612 613 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 614 if (rc || !getstatus) { 615 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot)); 616 goto out; 617 } 618 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 619 if (rc || getstatus) { 620 ctrl_info(ctrl, "Latch open on slot(%s)\n", slot_name(p_slot)); 621 goto out; 622 } 623 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 624 if (rc || !getstatus) { 625 ctrl_info(ctrl, "Already disabled on slot(%s)\n", 626 slot_name(p_slot)); 627 goto out; 628 } 629 630 retval = remove_board(p_slot); 631 update_slot_info(p_slot); 632 out: 633 mutex_unlock(&p_slot->ctrl->crit_sect); 634 return retval; 635 } 636 637 int shpchp_sysfs_enable_slot(struct slot *p_slot) 638 { 639 int retval = -ENODEV; 640 struct controller *ctrl = p_slot->ctrl; 641 642 mutex_lock(&p_slot->lock); 643 switch (p_slot->state) { 644 case BLINKINGON_STATE: 645 cancel_delayed_work(&p_slot->work); 646 /* fall through */ 647 case STATIC_STATE: 648 p_slot->state = POWERON_STATE; 649 mutex_unlock(&p_slot->lock); 650 retval = shpchp_enable_slot(p_slot); 651 mutex_lock(&p_slot->lock); 652 p_slot->state = STATIC_STATE; 653 break; 654 case POWERON_STATE: 655 ctrl_info(ctrl, "Slot %s is already in powering on state\n", 656 slot_name(p_slot)); 657 break; 658 case BLINKINGOFF_STATE: 659 case POWEROFF_STATE: 660 ctrl_info(ctrl, "Already enabled on slot %s\n", 661 slot_name(p_slot)); 662 break; 663 default: 664 ctrl_err(ctrl, "Not a valid state on slot %s\n", 665 slot_name(p_slot)); 666 break; 667 } 668 mutex_unlock(&p_slot->lock); 669 670 return retval; 671 } 672 673 int shpchp_sysfs_disable_slot(struct slot *p_slot) 674 { 675 int retval = -ENODEV; 676 struct controller *ctrl = p_slot->ctrl; 677 678 mutex_lock(&p_slot->lock); 679 switch (p_slot->state) { 680 case BLINKINGOFF_STATE: 681 cancel_delayed_work(&p_slot->work); 682 /* fall through */ 683 case STATIC_STATE: 684 p_slot->state = POWEROFF_STATE; 685 mutex_unlock(&p_slot->lock); 686 retval = shpchp_disable_slot(p_slot); 687 mutex_lock(&p_slot->lock); 688 p_slot->state = STATIC_STATE; 689 break; 690 case POWEROFF_STATE: 691 ctrl_info(ctrl, "Slot %s is already in powering off state\n", 692 slot_name(p_slot)); 693 break; 694 case BLINKINGON_STATE: 695 case POWERON_STATE: 696 ctrl_info(ctrl, "Already disabled on slot %s\n", 697 slot_name(p_slot)); 698 break; 699 default: 700 ctrl_err(ctrl, "Not a valid state on slot %s\n", 701 slot_name(p_slot)); 702 break; 703 } 704 mutex_unlock(&p_slot->lock); 705 706 return retval; 707 } 708