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/slab.h>
34#include <linux/pci.h>
35#include "../pci.h"
36#include "pciehp.h"
37
38static void interrupt_event_handler(struct work_struct *work);
39
40static 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	queue_work(p_slot->wq, &info->work);
53
54	return 0;
55}
56
57u8 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
76u8 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	pciehp_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
105u8 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	pciehp_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
138u8 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	ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
146	event_type = INT_POWER_FAULT;
147	ctrl_info(ctrl, "Power fault bit %x set\n", 0);
148	queue_interrupt_event(p_slot, event_type);
149
150	return 1;
151}
152
153void pciehp_handle_linkstate_change(struct slot *p_slot)
154{
155	u32 event_type;
156	struct controller *ctrl = p_slot->ctrl;
157
158	/* Link Status Change */
159	ctrl_dbg(ctrl, "Data Link Layer State change\n");
160
161	if (pciehp_check_link_active(ctrl)) {
162		ctrl_info(ctrl, "slot(%s): Link Up event\n",
163			  slot_name(p_slot));
164		event_type = INT_LINK_UP;
165	} else {
166		ctrl_info(ctrl, "slot(%s): Link Down event\n",
167			  slot_name(p_slot));
168		event_type = INT_LINK_DOWN;
169	}
170
171	queue_interrupt_event(p_slot, event_type);
172}
173
174/* The following routines constitute the bulk of the
175   hotplug controller logic
176 */
177
178static void set_slot_off(struct controller *ctrl, struct slot *pslot)
179{
180	/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
181	if (POWER_CTRL(ctrl)) {
182		pciehp_power_off_slot(pslot);
183
184		/*
185		 * After turning power off, we must wait for at least 1 second
186		 * before taking any action that relies on power having been
187		 * removed from the slot/adapter.
188		 */
189		msleep(1000);
190	}
191
192	pciehp_green_led_off(pslot);
193	pciehp_set_attention_status(pslot, 1);
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 */
203static int board_added(struct slot *p_slot)
204{
205	int retval = 0;
206	struct controller *ctrl = p_slot->ctrl;
207	struct pci_bus *parent = ctrl->pcie->port->subordinate;
208
209	if (POWER_CTRL(ctrl)) {
210		/* Power on slot */
211		retval = pciehp_power_on_slot(p_slot);
212		if (retval)
213			return retval;
214	}
215
216	pciehp_green_led_blink(p_slot);
217
218	/* Check link training status */
219	retval = pciehp_check_link_status(ctrl);
220	if (retval) {
221		ctrl_err(ctrl, "Failed to check link status\n");
222		goto err_exit;
223	}
224
225	/* Check for a power fault */
226	if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
227		ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
228		retval = -EIO;
229		goto err_exit;
230	}
231
232	retval = pciehp_configure_device(p_slot);
233	if (retval) {
234		ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",
235			 pci_domain_nr(parent), parent->number);
236		if (retval != -EEXIST)
237			goto err_exit;
238	}
239
240	pciehp_green_led_on(p_slot);
241	return 0;
242
243err_exit:
244	set_slot_off(ctrl, p_slot);
245	return retval;
246}
247
248/**
249 * remove_board - Turns off slot and LEDs
250 * @p_slot: slot where board is being removed
251 */
252static int remove_board(struct slot *p_slot)
253{
254	int retval;
255	struct controller *ctrl = p_slot->ctrl;
256
257	retval = pciehp_unconfigure_device(p_slot);
258	if (retval)
259		return retval;
260
261	if (POWER_CTRL(ctrl)) {
262		pciehp_power_off_slot(p_slot);
263
264		/*
265		 * After turning power off, we must wait for at least 1 second
266		 * before taking any action that relies on power having been
267		 * removed from the slot/adapter.
268		 */
269		msleep(1000);
270	}
271
272	/* turn off Green LED */
273	pciehp_green_led_off(p_slot);
274	return 0;
275}
276
277struct power_work_info {
278	struct slot *p_slot;
279	struct work_struct work;
280	unsigned int req;
281#define DISABLE_REQ 0
282#define ENABLE_REQ  1
283};
284
285/**
286 * pciehp_power_thread - handle pushbutton events
287 * @work: &struct work_struct describing work to be done
288 *
289 * Scheduled procedure to handle blocking stuff for the pushbuttons.
290 * Handles all pending events and exits.
291 */
292static void pciehp_power_thread(struct work_struct *work)
293{
294	struct power_work_info *info =
295		container_of(work, struct power_work_info, work);
296	struct slot *p_slot = info->p_slot;
297	int ret;
298
299	switch (info->req) {
300	case DISABLE_REQ:
301		ctrl_dbg(p_slot->ctrl,
302			 "Disabling domain:bus:device=%04x:%02x:00\n",
303			 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
304			 p_slot->ctrl->pcie->port->subordinate->number);
305		mutex_lock(&p_slot->hotplug_lock);
306		pciehp_disable_slot(p_slot);
307		mutex_unlock(&p_slot->hotplug_lock);
308		mutex_lock(&p_slot->lock);
309		p_slot->state = STATIC_STATE;
310		mutex_unlock(&p_slot->lock);
311		break;
312	case ENABLE_REQ:
313		ctrl_dbg(p_slot->ctrl,
314			 "Enabling domain:bus:device=%04x:%02x:00\n",
315			 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
316			 p_slot->ctrl->pcie->port->subordinate->number);
317		mutex_lock(&p_slot->hotplug_lock);
318		ret = pciehp_enable_slot(p_slot);
319		mutex_unlock(&p_slot->hotplug_lock);
320		if (ret)
321			pciehp_green_led_off(p_slot);
322		mutex_lock(&p_slot->lock);
323		p_slot->state = STATIC_STATE;
324		mutex_unlock(&p_slot->lock);
325		break;
326	default:
327		break;
328	}
329
330	kfree(info);
331}
332
333void pciehp_queue_pushbutton_work(struct work_struct *work)
334{
335	struct slot *p_slot = container_of(work, struct slot, work.work);
336	struct power_work_info *info;
337
338	info = kmalloc(sizeof(*info), GFP_KERNEL);
339	if (!info) {
340		ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
341			 __func__);
342		return;
343	}
344	info->p_slot = p_slot;
345	INIT_WORK(&info->work, pciehp_power_thread);
346
347	mutex_lock(&p_slot->lock);
348	switch (p_slot->state) {
349	case BLINKINGOFF_STATE:
350		p_slot->state = POWEROFF_STATE;
351		info->req = DISABLE_REQ;
352		break;
353	case BLINKINGON_STATE:
354		p_slot->state = POWERON_STATE;
355		info->req = ENABLE_REQ;
356		break;
357	default:
358		kfree(info);
359		goto out;
360	}
361	queue_work(p_slot->wq, &info->work);
362 out:
363	mutex_unlock(&p_slot->lock);
364}
365
366/*
367 * Note: This function must be called with slot->lock held
368 */
369static void handle_button_press_event(struct slot *p_slot)
370{
371	struct controller *ctrl = p_slot->ctrl;
372	u8 getstatus;
373
374	switch (p_slot->state) {
375	case STATIC_STATE:
376		pciehp_get_power_status(p_slot, &getstatus);
377		if (getstatus) {
378			p_slot->state = BLINKINGOFF_STATE;
379			ctrl_info(ctrl, "PCI slot #%s - powering off due to button press\n",
380				  slot_name(p_slot));
381		} else {
382			p_slot->state = BLINKINGON_STATE;
383			ctrl_info(ctrl, "PCI slot #%s - powering on due to button press\n",
384				  slot_name(p_slot));
385		}
386		/* blink green LED and turn off amber */
387		pciehp_green_led_blink(p_slot);
388		pciehp_set_attention_status(p_slot, 0);
389		queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
390		break;
391	case BLINKINGOFF_STATE:
392	case BLINKINGON_STATE:
393		/*
394		 * Cancel if we are still blinking; this means that we
395		 * press the attention again before the 5 sec. limit
396		 * expires to cancel hot-add or hot-remove
397		 */
398		ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));
399		cancel_delayed_work(&p_slot->work);
400		if (p_slot->state == BLINKINGOFF_STATE)
401			pciehp_green_led_on(p_slot);
402		else
403			pciehp_green_led_off(p_slot);
404		pciehp_set_attention_status(p_slot, 0);
405		ctrl_info(ctrl, "PCI slot #%s - action canceled due to button press\n",
406			  slot_name(p_slot));
407		p_slot->state = STATIC_STATE;
408		break;
409	case POWEROFF_STATE:
410	case POWERON_STATE:
411		/*
412		 * Ignore if the slot is on power-on or power-off state;
413		 * this means that the previous attention button action
414		 * to hot-add or hot-remove is undergoing
415		 */
416		ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
417		break;
418	default:
419		ctrl_warn(ctrl, "Not a valid state\n");
420		break;
421	}
422}
423
424/*
425 * Note: This function must be called with slot->lock held
426 */
427static void handle_surprise_event(struct slot *p_slot)
428{
429	u8 getstatus;
430	struct power_work_info *info;
431
432	info = kmalloc(sizeof(*info), GFP_KERNEL);
433	if (!info) {
434		ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
435			 __func__);
436		return;
437	}
438	info->p_slot = p_slot;
439	INIT_WORK(&info->work, pciehp_power_thread);
440
441	pciehp_get_adapter_status(p_slot, &getstatus);
442	if (!getstatus) {
443		p_slot->state = POWEROFF_STATE;
444		info->req = DISABLE_REQ;
445	} else {
446		p_slot->state = POWERON_STATE;
447		info->req = ENABLE_REQ;
448	}
449
450	queue_work(p_slot->wq, &info->work);
451}
452
453/*
454 * Note: This function must be called with slot->lock held
455 */
456static void handle_link_event(struct slot *p_slot, u32 event)
457{
458	struct controller *ctrl = p_slot->ctrl;
459	struct power_work_info *info;
460
461	info = kmalloc(sizeof(*info), GFP_KERNEL);
462	if (!info) {
463		ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
464			 __func__);
465		return;
466	}
467	info->p_slot = p_slot;
468	info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ;
469	INIT_WORK(&info->work, pciehp_power_thread);
470
471	switch (p_slot->state) {
472	case BLINKINGON_STATE:
473	case BLINKINGOFF_STATE:
474		cancel_delayed_work(&p_slot->work);
475		/* Fall through */
476	case STATIC_STATE:
477		p_slot->state = event == INT_LINK_UP ?
478		    POWERON_STATE : POWEROFF_STATE;
479		queue_work(p_slot->wq, &info->work);
480		break;
481	case POWERON_STATE:
482		if (event == INT_LINK_UP) {
483			ctrl_info(ctrl,
484				  "Link Up event ignored on slot(%s): already powering on\n",
485				  slot_name(p_slot));
486			kfree(info);
487		} else {
488			ctrl_info(ctrl,
489				  "Link Down event queued on slot(%s): currently getting powered on\n",
490				  slot_name(p_slot));
491			p_slot->state = POWEROFF_STATE;
492			queue_work(p_slot->wq, &info->work);
493		}
494		break;
495	case POWEROFF_STATE:
496		if (event == INT_LINK_UP) {
497			ctrl_info(ctrl,
498				  "Link Up event queued on slot(%s): currently getting powered off\n",
499				  slot_name(p_slot));
500			p_slot->state = POWERON_STATE;
501			queue_work(p_slot->wq, &info->work);
502		} else {
503			ctrl_info(ctrl,
504				  "Link Down event ignored on slot(%s): already powering off\n",
505				  slot_name(p_slot));
506			kfree(info);
507		}
508		break;
509	default:
510		ctrl_err(ctrl, "Not a valid state on slot(%s)\n",
511			 slot_name(p_slot));
512		kfree(info);
513		break;
514	}
515}
516
517static void interrupt_event_handler(struct work_struct *work)
518{
519	struct event_info *info = container_of(work, struct event_info, work);
520	struct slot *p_slot = info->p_slot;
521	struct controller *ctrl = p_slot->ctrl;
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		if (!POWER_CTRL(ctrl))
530			break;
531		pciehp_set_attention_status(p_slot, 1);
532		pciehp_green_led_off(p_slot);
533		break;
534	case INT_PRESENCE_ON:
535		ctrl_dbg(ctrl, "Surprise Insertion\n");
536		handle_surprise_event(p_slot);
537		break;
538	case INT_PRESENCE_OFF:
539		/*
540		 * Regardless of surprise capability, we need to
541		 * definitely remove a card that has been pulled out!
542		 */
543		ctrl_dbg(ctrl, "Surprise Removal\n");
544		handle_surprise_event(p_slot);
545		break;
546	case INT_LINK_UP:
547	case INT_LINK_DOWN:
548		handle_link_event(p_slot, info->event_type);
549		break;
550	default:
551		break;
552	}
553	mutex_unlock(&p_slot->lock);
554
555	kfree(info);
556}
557
558/*
559 * Note: This function must be called with slot->hotplug_lock held
560 */
561int pciehp_enable_slot(struct slot *p_slot)
562{
563	u8 getstatus = 0;
564	int rc;
565	struct controller *ctrl = p_slot->ctrl;
566
567	pciehp_get_adapter_status(p_slot, &getstatus);
568	if (!getstatus) {
569		ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot));
570		return -ENODEV;
571	}
572	if (MRL_SENS(p_slot->ctrl)) {
573		pciehp_get_latch_status(p_slot, &getstatus);
574		if (getstatus) {
575			ctrl_info(ctrl, "Latch open on slot(%s)\n",
576				  slot_name(p_slot));
577			return -ENODEV;
578		}
579	}
580
581	if (POWER_CTRL(p_slot->ctrl)) {
582		pciehp_get_power_status(p_slot, &getstatus);
583		if (getstatus) {
584			ctrl_info(ctrl, "Already enabled on slot(%s)\n",
585				  slot_name(p_slot));
586			return -EINVAL;
587		}
588	}
589
590	pciehp_get_latch_status(p_slot, &getstatus);
591
592	rc = board_added(p_slot);
593	if (rc)
594		pciehp_get_latch_status(p_slot, &getstatus);
595
596	return rc;
597}
598
599/*
600 * Note: This function must be called with slot->hotplug_lock held
601 */
602int pciehp_disable_slot(struct slot *p_slot)
603{
604	u8 getstatus = 0;
605	struct controller *ctrl = p_slot->ctrl;
606
607	if (!p_slot->ctrl)
608		return 1;
609
610	if (POWER_CTRL(p_slot->ctrl)) {
611		pciehp_get_power_status(p_slot, &getstatus);
612		if (!getstatus) {
613			ctrl_info(ctrl, "Already disabled on slot(%s)\n",
614				  slot_name(p_slot));
615			return -EINVAL;
616		}
617	}
618
619	return remove_board(p_slot);
620}
621
622int pciehp_sysfs_enable_slot(struct slot *p_slot)
623{
624	int retval = -ENODEV;
625	struct controller *ctrl = p_slot->ctrl;
626
627	mutex_lock(&p_slot->lock);
628	switch (p_slot->state) {
629	case BLINKINGON_STATE:
630		cancel_delayed_work(&p_slot->work);
631	case STATIC_STATE:
632		p_slot->state = POWERON_STATE;
633		mutex_unlock(&p_slot->lock);
634		mutex_lock(&p_slot->hotplug_lock);
635		retval = pciehp_enable_slot(p_slot);
636		mutex_unlock(&p_slot->hotplug_lock);
637		mutex_lock(&p_slot->lock);
638		p_slot->state = STATIC_STATE;
639		break;
640	case POWERON_STATE:
641		ctrl_info(ctrl, "Slot %s is already in powering on state\n",
642			  slot_name(p_slot));
643		break;
644	case BLINKINGOFF_STATE:
645	case POWEROFF_STATE:
646		ctrl_info(ctrl, "Already enabled on slot %s\n",
647			  slot_name(p_slot));
648		break;
649	default:
650		ctrl_err(ctrl, "Not a valid state on slot %s\n",
651			 slot_name(p_slot));
652		break;
653	}
654	mutex_unlock(&p_slot->lock);
655
656	return retval;
657}
658
659int pciehp_sysfs_disable_slot(struct slot *p_slot)
660{
661	int retval = -ENODEV;
662	struct controller *ctrl = p_slot->ctrl;
663
664	mutex_lock(&p_slot->lock);
665	switch (p_slot->state) {
666	case BLINKINGOFF_STATE:
667		cancel_delayed_work(&p_slot->work);
668	case STATIC_STATE:
669		p_slot->state = POWEROFF_STATE;
670		mutex_unlock(&p_slot->lock);
671		retval = pciehp_disable_slot(p_slot);
672		mutex_lock(&p_slot->lock);
673		p_slot->state = STATIC_STATE;
674		break;
675	case POWEROFF_STATE:
676		ctrl_info(ctrl, "Slot %s is already in powering off state\n",
677			  slot_name(p_slot));
678		break;
679	case BLINKINGON_STATE:
680	case POWERON_STATE:
681		ctrl_info(ctrl, "Already disabled on slot %s\n",
682			  slot_name(p_slot));
683		break;
684	default:
685		ctrl_err(ctrl, "Not a valid state on slot %s\n",
686			 slot_name(p_slot));
687		break;
688	}
689	mutex_unlock(&p_slot->lock);
690
691	return retval;
692}
693