atomic_inc(&eeh_fail_count); if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
pdn->eeh_check_count ++; if (pdn->eeh_check_count >= EEH_MAX_FAILS) { printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", pdn->eeh_check_count); dump_stack();
int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev){	int ret;	int rets[3];	unsigned long flags;	int reset_state;	struct eeh_event  *event;	struct pci_dn *pdn;	struct device_node *pe_dn;	int rc = 0;	__get_cpu_var(total_mmio_ffs)++;	if (!eeh_subsystem_enabled)		return 0;	if (!dn) {		__get_cpu_var(no_dn)++;		return 0;	}	pdn = PCI_DN(dn);	/* Access to IO BARs might get this far and still not want checking. */	if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||	    pdn->eeh_mode & EEH_MODE_NOCHECK) {		__get_cpu_var(ignored_check)++;#ifdef DEBUG		printk ("EEH:ignored check for %s %s\n", pci_name (dev), dn->full_name);#endif		return 0;	}	if (!pdn->eeh_config_addr) {		__get_cpu_var(no_cfg_addr)++;		return 0;	}	/* If we already have a pending isolation event for this	 * slot, we know it's bad already, we don't need to check.	 * Do this checking under a lock; as multiple PCI devices	 * in one slot might report errors simultaneously, and we	 * only want one error recovery routine running.	 */	spin_lock_irqsave(&confirm_error_lock, flags);	rc = 1;	if (pdn->eeh_mode & EEH_MODE_ISOLATED) {		atomic_inc(&eeh_fail_count);		if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {			/* re-read the slot reset state */			if (read_slot_reset_state(pdn, rets) != 0)				rets[0] = -1;	/* reset state unknown */			eeh_panic(dev, rets[0]);		}		goto dn_unlock;	}	/*	 * Now test for an EEH failure.  This is VERY expensive.	 * Note that the eeh_config_addr may be a parent device	 * in the case of a device behind a bridge, or it may be	 * function zero of a multi-function device.	 * In any case they must share a common PHB.	 */	ret = read_slot_reset_state(pdn, rets);	/* If the call to firmware failed, punt */	if (ret != 0) {		printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",		       ret, dn->full_name);		__get_cpu_var(false_positives)++;		rc = 0;		goto dn_unlock;	}	/* If EEH is not supported on this device, punt. */	if (rets[1] != 1) {		printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",		       ret, dn->full_name);		__get_cpu_var(false_positives)++;		rc = 0;		goto dn_unlock;	}	/* If not the kind of error we know about, punt. */	if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {		__get_cpu_var(false_positives)++;		rc = 0;		goto dn_unlock;	}	/* Note that config-io to empty slots may fail;	 * we recognize empty because they don't have children. */	if ((rets[0] == 5) && (dn->child == NULL)) {		__get_cpu_var(false_positives)++;		rc = 0;		goto dn_unlock;	}	__get_cpu_var(slot_resets)++; 	/* Avoid repeated reports of this failure, including problems	 * with other functions on this device, and functions under	 * bridges. */	pe_dn = find_device_pe (dn);	__eeh_mark_slot (pe_dn);	spin_unlock_irqrestore(&confirm_error_lock, flags);	reset_state = rets[0];	eeh_slot_error_detail (pdn, 1 /* Temporary Error */);	printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n",	       rets[0], dn->name, dn->full_name);	event = kmalloc(sizeof(*event), GFP_ATOMIC);	if (event == NULL) {		eeh_panic(dev, reset_state);		return 1; 	}	event->dev = dev;	event->dn = dn;	event->reset_state = reset_state;	/* We may or may not be called in an interrupt context */	spin_lock_irqsave(&eeh_eventlist_lock, flags);	list_add(&event->list, &eeh_eventlist);	spin_unlock_irqrestore(&eeh_eventlist_lock, flags);	/* Most EEH events are due to device driver bugs.  Having	 * a stack trace will help the device-driver authors figure	 * out what happened.  So print that out. */	if (rets[0] != 5) dump_stack();	schedule_work(&eeh_event_wq);	return 1;dn_unlock:	spin_unlock_irqrestore(&confirm_error_lock, flags);	return rc;}