Example #1
0
static void __rtas_set_slot_reset(struct pci_dn *pdn)
{
	rtas_pci_slot_reset (pdn, 1);

	/* The PCI bus requires that the reset be held high for at least
	 * a 100 milliseconds. We wait a bit longer 'just in case'.  */

#define PCI_BUS_RST_HOLD_TIME_MSEC 250
	msleep (PCI_BUS_RST_HOLD_TIME_MSEC);
	
	/* We might get hit with another EEH freeze as soon as the 
	 * pci slot reset line is dropped. Make sure we don't miss
	 * these, and clear the flag now. */
	eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED);

	rtas_pci_slot_reset (pdn, 0);

	/* After a PCI slot has been reset, the PCI Express spec requires
	 * a 1.5 second idle time for the bus to stabilize, before starting
	 * up traffic. */
#define PCI_BUS_SETTLE_TIME_MSEC 1800
	msleep (PCI_BUS_SETTLE_TIME_MSEC);
}
Example #2
0
/**
 * eeh_event_handler - dispatch EEH events.  The detection of a frozen
 * slot can occur inside an interrupt, where it can be hard to do
 * anything about it.  The goal of this routine is to pull these
 * detection events out of the context of the interrupt handler, and
 * re-dispatch them for processing at a later time in a normal context.
 *
 * @dummy - unused
 */
static int eeh_event_handler(void * dummy)
{
	unsigned long flags;
	struct eeh_event	*event;

	daemonize ("eehd");

	while (1) {
		set_current_state(TASK_INTERRUPTIBLE);

		spin_lock_irqsave(&eeh_eventlist_lock, flags);
		event = NULL;

		/* Unqueue the event, get ready to process. */
		if (!list_empty(&eeh_eventlist)) {
			event = list_entry(eeh_eventlist.next, struct eeh_event, list);
			list_del(&event->list);
		}
		
		if (event)
			eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);

		spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
		if (event == NULL)
			break;

		printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
		       pci_name(event->dev));

		handle_eeh_events(event);

		eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);

		pci_dev_put(event->dev);
		kfree(event);
	}