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