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); }
/** * 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); }