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