eeh_driver.c 20.6 KB
Newer Older
1 2
/*
 * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
3 4
 * Copyright IBM Corp. 2004 2005
 * Copyright Linas Vepstas <linas@linas.org> 2004, 2005
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
23
 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
24 25 26
 */
#include <linux/delay.h>
#include <linux/interrupt.h>
27
#include <linux/irq.h>
28
#include <linux/module.h>
29 30 31 32 33 34 35 36
#include <linux/pci.h>
#include <asm/eeh.h>
#include <asm/eeh_event.h>
#include <asm/ppc-pci.h>
#include <asm/pci-bridge.h>
#include <asm/prom.h>
#include <asm/rtas.h>

37 38 39 40 41 42 43
/**
 * eeh_pcid_name - Retrieve name of PCI device driver
 * @pdev: PCI device
 *
 * This routine is used to retrieve the name of PCI device driver
 * if that's valid.
 */
44
static inline const char *eeh_pcid_name(struct pci_dev *pdev)
45
{
46
	if (pdev && pdev->dev.driver)
47 48 49 50
		return pdev->dev.driver->name;
	return "";
}

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/**
 * eeh_pcid_get - Get the PCI device driver
 * @pdev: PCI device
 *
 * The function is used to retrieve the PCI device driver for
 * the indicated PCI device. Besides, we will increase the reference
 * of the PCI device driver to prevent that being unloaded on
 * the fly. Otherwise, kernel crash would be seen.
 */
static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
{
	if (!pdev || !pdev->driver)
		return NULL;

	if (!try_module_get(pdev->driver->driver.owner))
		return NULL;

	return pdev->driver;
}

/**
 * eeh_pcid_put - Dereference on the PCI device driver
 * @pdev: PCI device
 *
 * The function is called to do dereference on the PCI device
 * driver of the indicated PCI device.
 */
static inline void eeh_pcid_put(struct pci_dev *pdev)
{
	if (!pdev || !pdev->driver)
		return;

	module_put(pdev->driver->driver.owner);
}

86
#if 0
87
static void print_device_node_tree(struct pci_dn *pdn, int dent)
88 89
{
	int i;
90 91 92 93 94
	struct device_node *pc;

	if (!pdn)
		return;
	for (i = 0; i < dent; i++)
95 96 97 98 99
		printk(" ");
	printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
		pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
		pdn->eeh_pe_config_addr, pdn->node->full_name);
	dent += 3;
100
	pc = pdn->node->child;
101 102 103 104 105 106 107
	while (pc) {
		print_device_node_tree(PCI_DN(pc), dent);
		pc = pc->sibling;
	}
}
#endif

108
/**
109 110 111 112 113 114 115 116
 * eeh_disable_irq - Disable interrupt for the recovering device
 * @dev: PCI device
 *
 * This routine must be called when reporting temporary or permanent
 * error to the particular PCI device to disable interrupt of that
 * device. If the device has enabled MSI or MSI-X interrupt, we needn't
 * do real work because EEH should freeze DMA transfers for those PCI
 * devices encountering EEH errors, which includes MSI or MSI-X.
117 118 119
 */
static void eeh_disable_irq(struct pci_dev *dev)
{
120
	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
121 122 123 124

	/* Don't disable MSI and MSI-X interrupts. They are
	 * effectively disabled by the DMA Stopped state
	 * when an EEH error occurs.
125
	 */
126 127 128
	if (dev->msi_enabled || dev->msix_enabled)
		return;

129
	if (!irq_has_action(dev->irq))
130 131
		return;

G
Gavin Shan 已提交
132
	edev->mode |= EEH_DEV_IRQ_DISABLED;
133 134 135 136
	disable_irq_nosync(dev->irq);
}

/**
137 138 139 140 141
 * eeh_enable_irq - Enable interrupt for the recovering device
 * @dev: PCI device
 *
 * This routine must be called to enable interrupt while failed
 * device could be resumed.
142 143 144
 */
static void eeh_enable_irq(struct pci_dev *dev)
{
145
	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
146

G
Gavin Shan 已提交
147 148
	if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
		edev->mode &= ~EEH_DEV_IRQ_DISABLED;
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
		/*
		 * FIXME !!!!!
		 *
		 * This is just ass backwards. This maze has
		 * unbalanced irq_enable/disable calls. So instead of
		 * finding the root cause it works around the warning
		 * in the irq_enable code by conditionally calling
		 * into it.
		 *
		 * That's just wrong.The warning in the core code is
		 * there to tell people to fix their assymetries in
		 * their own code, not by abusing the core information
		 * to avoid it.
		 *
		 * I so wish that the assymetry would be the other way
		 * round and a few more irq_disable calls render that
		 * shit unusable forever.
		 *
		 *	tglx
		 */
		if (irqd_irq_disabled(irq_get_irq_data(dev->irq))
170
			enable_irq(dev->irq);
171 172
}

173
/**
174
 * eeh_report_error - Report pci error to each device driver
175
 * @data: eeh device
176
 * @userdata: return value
G
Gavin Shan 已提交
177 178 179
 *
 * Report an EEH error to each device driver, collect up and
 * merge the device driver responses. Cumulative response
180
 * passed back in "userdata".
181
 */
182
static void *eeh_report_error(void *data, void *userdata)
183
{
184 185
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
186
	enum pci_ers_result rc, *res = userdata;
187
	struct pci_driver *driver;
188

189 190 191 192
	/* We might not have the associated PCI device,
	 * then we should continue for next one.
	 */
	if (!dev) return NULL;
193 194
	dev->error_state = pci_channel_io_frozen;

195 196
	driver = eeh_pcid_get(dev);
	if (!driver) return NULL;
197

198 199
	eeh_disable_irq(dev);

200
	if (!driver->err_handler ||
201 202
	    !driver->err_handler->error_detected) {
		eeh_pcid_put(dev);
203
		return NULL;
204
	}
205

206
	rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);
207 208 209

	/* A driver that needs a reset trumps all others */
	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
210
	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
211

212
	eeh_pcid_put(dev);
213
	return NULL;
214 215 216
}

/**
217
 * eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled
218
 * @data: eeh device
219
 * @userdata: return value
220
 *
L
Linas Vepstas 已提交
221 222 223
 * Tells each device driver that IO ports, MMIO and config space I/O
 * are now enabled. Collects up and merges the device driver responses.
 * Cumulative response passed back in "userdata".
224
 */
225
static void *eeh_report_mmio_enabled(void *data, void *userdata)
226
{
227 228
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
229
	enum pci_ers_result rc, *res = userdata;
230
	struct pci_driver *driver;
231

232 233
	driver = eeh_pcid_get(dev);
	if (!driver) return NULL;
234

235
	if (!driver->err_handler ||
G
Gavin Shan 已提交
236 237
	    !driver->err_handler->mmio_enabled ||
	    (edev->mode & EEH_DEV_NO_HANDLER)) {
238
		eeh_pcid_put(dev);
239
		return NULL;
240
	}
241

242
	rc = driver->err_handler->mmio_enabled(dev);
243 244 245

	/* A driver that needs a reset trumps all others */
	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
246
	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
247

248
	eeh_pcid_put(dev);
249
	return NULL;
250 251
}

252
/**
253
 * eeh_report_reset - Tell device that slot has been reset
254
 * @data: eeh device
255 256 257 258 259 260
 * @userdata: return value
 *
 * This routine must be called while EEH tries to reset particular
 * PCI device so that the associated PCI device driver could take
 * some actions, usually to save data the driver needs so that the
 * driver can work again while the device is recovered.
261
 */
262
static void *eeh_report_reset(void *data, void *userdata)
263
{
264 265
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
266
	enum pci_ers_result rc, *res = userdata;
267
	struct pci_driver *driver;
268

269
	if (!dev) return NULL;
270 271
	dev->error_state = pci_channel_io_normal;

272 273 274
	driver = eeh_pcid_get(dev);
	if (!driver) return NULL;

275 276
	eeh_enable_irq(dev);

277
	if (!driver->err_handler ||
G
Gavin Shan 已提交
278 279
	    !driver->err_handler->slot_reset ||
	    (edev->mode & EEH_DEV_NO_HANDLER)) {
280
		eeh_pcid_put(dev);
281
		return NULL;
282
	}
283

284
	rc = driver->err_handler->slot_reset(dev);
285 286
	if ((*res == PCI_ERS_RESULT_NONE) ||
	    (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
287 288
	if (*res == PCI_ERS_RESULT_DISCONNECT &&
	     rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
289

290
	eeh_pcid_put(dev);
291
	return NULL;
292 293
}

294
/**
295
 * eeh_report_resume - Tell device to resume normal operations
296
 * @data: eeh device
297 298 299 300 301
 * @userdata: return value
 *
 * This routine must be called to notify the device driver that it
 * could resume so that the device driver can do some initialization
 * to make the recovered device work again.
302
 */
303
static void *eeh_report_resume(void *data, void *userdata)
304
{
305 306 307 308 309
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
	struct pci_driver *driver;

	if (!dev) return NULL;
310 311
	dev->error_state = pci_channel_io_normal;

312 313
	driver = eeh_pcid_get(dev);
	if (!driver) return NULL;
L
Linas Vepstas 已提交
314

315 316
	eeh_enable_irq(dev);

L
Linas Vepstas 已提交
317
	if (!driver->err_handler ||
G
Gavin Shan 已提交
318 319 320
	    !driver->err_handler->resume ||
	    (edev->mode & EEH_DEV_NO_HANDLER)) {
		edev->mode &= ~EEH_DEV_NO_HANDLER;
321
		eeh_pcid_put(dev);
322
		return NULL;
323
	}
324 325

	driver->err_handler->resume(dev);
326

327
	eeh_pcid_put(dev);
328
	return NULL;
329 330
}

331
/**
332
 * eeh_report_failure - Tell device driver that device is dead.
333
 * @data: eeh device
334
 * @userdata: return value
335 336 337 338
 *
 * This informs the device driver that the device is permanently
 * dead, and that no further recovery attempts will be made on it.
 */
339
static void *eeh_report_failure(void *data, void *userdata)
340
{
341 342 343 344 345
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
	struct pci_driver *driver;

	if (!dev) return NULL;
346 347
	dev->error_state = pci_channel_io_perm_failure;

348 349
	driver = eeh_pcid_get(dev);
	if (!driver) return NULL;
350

351 352 353
	eeh_disable_irq(dev);

	if (!driver->err_handler ||
354 355
	    !driver->err_handler->error_detected) {
		eeh_pcid_put(dev);
356
		return NULL;
357
	}
358

359
	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
360

361
	eeh_pcid_put(dev);
362
	return NULL;
363 364
}

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
static void *eeh_rmv_device(void *data, void *userdata)
{
	struct pci_driver *driver;
	struct eeh_dev *edev = (struct eeh_dev *)data;
	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
	int *removed = (int *)userdata;

	/*
	 * Actually, we should remove the PCI bridges as well.
	 * However, that's lots of complexity to do that,
	 * particularly some of devices under the bridge might
	 * support EEH. So we just care about PCI devices for
	 * simplicity here.
	 */
	if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
		return NULL;
381

382
	driver = eeh_pcid_get(dev);
383 384 385 386 387
	if (driver) {
		eeh_pcid_put(dev);
		if (driver->err_handler)
			return NULL;
	}
388 389 390 391 392 393 394 395

	/* Remove it from PCI subsystem */
	pr_debug("EEH: Removing %s without EEH sensitive driver\n",
		 pci_name(dev));
	edev->bus = dev->bus;
	edev->mode |= EEH_DEV_DISCONNECTED;
	(*removed)++;

396
	pci_lock_rescan_remove();
397
	pci_stop_and_remove_bus_device(dev);
398
	pci_unlock_rescan_remove();
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418

	return NULL;
}

static void *eeh_pe_detach_dev(void *data, void *userdata)
{
	struct eeh_pe *pe = (struct eeh_pe *)data;
	struct eeh_dev *edev, *tmp;

	eeh_pe_for_each_dev(pe, edev, tmp) {
		if (!(edev->mode & EEH_DEV_DISCONNECTED))
			continue;

		edev->mode &= ~(EEH_DEV_DISCONNECTED | EEH_DEV_IRQ_DISABLED);
		eeh_rmv_from_parent_pe(edev);
	}

	return NULL;
}

419
/**
420
 * eeh_reset_device - Perform actual reset of a pci slot
421
 * @pe: EEH PE
422
 * @bus: PCI bus corresponding to the isolcated slot
423
 *
424 425 426
 * This routine must be called to do reset on the indicated PE.
 * During the reset, udev might be invoked because those affected
 * PCI devices will be removed and then added.
427
 */
428
static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
429
{
430
	struct pci_bus *frozen_bus = eeh_pe_bus_get(pe);
431
	struct timeval tstamp;
432
	int cnt, rc, removed = 0;
433 434

	/* pcibios will clear the counter; save the value */
435
	cnt = pe->freeze_count;
436
	tstamp = pe->tstamp;
437

438 439 440 441 442 443
	/*
	 * We don't remove the corresponding PE instances because
	 * we need the information afterwords. The attached EEH
	 * devices are expected to be attached soon when calling
	 * into pcibios_add_pci_devices().
	 */
444
	eeh_pe_state_mark(pe, EEH_PE_KEEP);
445 446
	if (bus) {
		pci_lock_rescan_remove();
G
Gavin Shan 已提交
447
		pcibios_remove_pci_devices(bus);
448 449
		pci_unlock_rescan_remove();
	} else if (frozen_bus) {
450
		eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
451
	}
452 453

	/* Reset the pci controller. (Asserts RST#; resets config space).
454
	 * Reconfigure bridges and devices. Don't try to bring the system
455 456
	 * up if the reset failed for some reason.
	 */
457
	rc = eeh_reset_pe(pe);
458 459
	if (rc)
		return rc;
460

461 462
	pci_lock_rescan_remove();

463 464 465
	/* Restore PE */
	eeh_ops->configure_bridge(pe);
	eeh_pe_restore_bars(pe);
466 467

	/* Give the system 5 seconds to finish running the user-space
G
Gavin Shan 已提交
468 469 470
	 * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
	 * this is a hack, but if we don't do this, and try to bring
	 * the device up before the scripts have taken it down,
471 472 473
	 * potentially weird things happen.
	 */
	if (bus) {
474
		pr_info("EEH: Sleep 5s ahead of complete hotplug\n");
475
		ssleep(5);
476 477 478 479 480 481 482

		/*
		 * The EEH device is still connected with its parent
		 * PE. We should disconnect it so the binding can be
		 * rebuilt when adding PCI devices.
		 */
		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
483
		pcibios_add_pci_devices(bus);
484 485 486 487 488 489
	} else if (frozen_bus && removed) {
		pr_info("EEH: Sleep 5s ahead of partial hotplug\n");
		ssleep(5);

		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
		pcibios_add_pci_devices(frozen_bus);
490
	}
491
	eeh_pe_state_clear(pe, EEH_PE_KEEP);
492 493

	pe->tstamp = tstamp;
494
	pe->freeze_count = cnt;
495

496
	pci_unlock_rescan_remove();
497
	return 0;
498 499 500 501 502
}

/* The longest amount of time to wait for a pci device
 * to come back on line, in seconds.
 */
503
#define MAX_WAIT_FOR_RECOVERY 300
504

505
static void eeh_handle_normal_event(struct eeh_pe *pe)
506 507
{
	struct pci_bus *frozen_bus;
508
	int rc = 0;
509
	enum pci_ers_result result = PCI_ERS_RESULT_NONE;
510

511
	frozen_bus = eeh_pe_bus_get(pe);
512
	if (!frozen_bus) {
513 514 515
		pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
			__func__, pe->phb->global_number, pe->addr);
		return;
516 517
	}

518
	eeh_pe_update_time_stamp(pe);
519 520
	pe->freeze_count++;
	if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
521
		goto excess_failures;
522 523
	pr_warning("EEH: This PCI device has failed %d times in the last hour\n",
		pe->freeze_count);
524 525 526 527 528 529 530

	/* Walk the various device drivers attached to this slot through
	 * a reset sequence, giving each an opportunity to do what it needs
	 * to accomplish the reset.  Each child gets a report of the
	 * status ... if any child can't handle the reset, then the entire
	 * slot is dlpar removed and added.
	 */
531
	pr_info("EEH: Notify device drivers to shutdown\n");
532
	eeh_pe_dev_traverse(pe, eeh_report_error, &result);
533

534
	/* Get the current PCI slot state. This can take a long time,
535 536
	 * sometimes over 3 seconds for certain systems.
	 */
537
	rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
538
	if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
539
		pr_warning("EEH: Permanent failure\n");
540 541 542
		goto hard_fail;
	}

543 544
	/* Since rtas may enable MMIO when posting the error log,
	 * don't post the error log until after all dev drivers
545 546
	 * have been informed.
	 */
547
	pr_info("EEH: Collect temporary log\n");
548
	eeh_slot_error_detail(pe, EEH_LOG_TEMP);
549

550 551 552 553
	/* If all device drivers were EEH-unaware, then shut
	 * down all of the device drivers, and hope they
	 * go down willingly, without panicing the system.
	 */
554
	if (result == PCI_ERS_RESULT_NONE) {
555
		pr_info("EEH: Reset with hotplug activity\n");
556
		rc = eeh_reset_device(pe, frozen_bus);
557
		if (rc) {
558 559
			pr_warning("%s: Unable to reset, err=%d\n",
				   __func__, rc);
560
			goto hard_fail;
561
		}
562 563
	}

564 565
	/* If all devices reported they can proceed, then re-enable MMIO */
	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
566
		pr_info("EEH: Enable I/O for affected devices\n");
567
		rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
568

569 570
		if (rc < 0)
			goto hard_fail;
571 572 573
		if (rc) {
			result = PCI_ERS_RESULT_NEED_RESET;
		} else {
574
			pr_info("EEH: Notify device drivers to resume I/O\n");
575
			result = PCI_ERS_RESULT_NONE;
576
			eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result);
577
		}
578 579
	}

580
	/* If all devices reported they can proceed, then re-enable DMA */
581
	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
582
		pr_info("EEH: Enabled DMA for affected devices\n");
583
		rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA);
584

585 586
		if (rc < 0)
			goto hard_fail;
587 588
		if (rc)
			result = PCI_ERS_RESULT_NEED_RESET;
L
Linas Vepstas 已提交
589 590
		else
			result = PCI_ERS_RESULT_RECOVERED;
591 592 593
	}

	/* If any device has a hard failure, then shut off everything. */
594
	if (result == PCI_ERS_RESULT_DISCONNECT) {
595
		pr_warning("EEH: Device driver gave up\n");
596
		goto hard_fail;
597
	}
598 599 600

	/* If any device called out for a reset, then reset the slot */
	if (result == PCI_ERS_RESULT_NEED_RESET) {
601
		pr_info("EEH: Reset without hotplug activity\n");
602
		rc = eeh_reset_device(pe, NULL);
603
		if (rc) {
604 605
			pr_warning("%s: Cannot reset, err=%d\n",
				   __func__, rc);
606
			goto hard_fail;
607
		}
608 609 610

		pr_info("EEH: Notify device drivers "
			"the completion of reset\n");
611
		result = PCI_ERS_RESULT_NONE;
612
		eeh_pe_dev_traverse(pe, eeh_report_reset, &result);
613 614
	}

615
	/* All devices should claim they have recovered by now. */
616 617
	if ((result != PCI_ERS_RESULT_RECOVERED) &&
	    (result != PCI_ERS_RESULT_NONE)) {
618
		pr_warning("EEH: Not recovered\n");
619
		goto hard_fail;
620
	}
621

622
	/* Tell all device drivers that they can resume operations */
623
	pr_info("EEH: Notify device driver to resume\n");
624
	eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
625

626
	return;
G
Gavin Shan 已提交
627

628
excess_failures:
629 630 631 632 633
	/*
	 * About 90% of all real-life EEH failures in the field
	 * are due to poorly seated PCI cards. Only 10% or so are
	 * due to actual, failed cards.
	 */
634 635 636 637 638
	pr_err("EEH: PHB#%d-PE#%x has failed %d times in the\n"
	       "last hour and has been permanently disabled.\n"
	       "Please try reseating or replacing it.\n",
		pe->phb->global_number, pe->addr,
		pe->freeze_count);
639 640 641
	goto perm_error;

hard_fail:
642 643 644
	pr_err("EEH: Unable to recover from failure from PHB#%d-PE#%x.\n"
	       "Please try reseating or replacing it\n",
		pe->phb->global_number, pe->addr);
645

646
perm_error:
647
	eeh_slot_error_detail(pe, EEH_LOG_PERM);
648 649

	/* Notify all devices that they're about to go down. */
650
	eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
651 652

	/* Shut down the device drivers for good. */
653 654
	if (frozen_bus) {
		pci_lock_rescan_remove();
655
		pcibios_remove_pci_devices(frozen_bus);
656 657
		pci_unlock_rescan_remove();
	}
658
}
659 660 661 662 663

static void eeh_handle_special_event(void)
{
	struct eeh_pe *pe, *phb_pe;
	struct pci_bus *bus;
664
	struct pci_controller *hose;
665
	unsigned long flags;
666
	int rc;
667 668


669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
	do {
		rc = eeh_ops->next_error(&pe);

		switch (rc) {
		case EEH_NEXT_ERR_DEAD_IOC:
			/* Mark all PHBs in dead state */
			eeh_serialize_lock(&flags);

			/* Purge all events */
			eeh_remove_event(NULL);

			list_for_each_entry(hose, &hose_list, list_node) {
				phb_pe = eeh_phb_pe_get(hose);
				if (!phb_pe) continue;

				eeh_pe_state_mark(phb_pe,
					EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
			}

			eeh_serialize_unlock(flags);

			break;
		case EEH_NEXT_ERR_FROZEN_PE:
		case EEH_NEXT_ERR_FENCED_PHB:
		case EEH_NEXT_ERR_DEAD_PHB:
			/* Mark the PE in fenced state */
			eeh_serialize_lock(&flags);

			/* Purge all events of the PHB */
			eeh_remove_event(pe);

			if (rc == EEH_NEXT_ERR_DEAD_PHB)
				eeh_pe_state_mark(pe,
					EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
			else
				eeh_pe_state_mark(pe,
					EEH_PE_ISOLATED | EEH_PE_RECOVERING);

			eeh_serialize_unlock(flags);

			break;
		case EEH_NEXT_ERR_NONE:
			return;
		default:
			pr_warn("%s: Invalid value %d from next_error()\n",
				__func__, rc);
			return;
716 717
		}

718 719 720 721 722 723 724 725 726
		/*
		 * For fenced PHB and frozen PE, it's handled as normal
		 * event. We have to remove the affected PHBs for dead
		 * PHB and IOC
		 */
		if (rc == EEH_NEXT_ERR_FROZEN_PE ||
		    rc == EEH_NEXT_ERR_FENCED_PHB) {
			eeh_handle_normal_event(pe);
		} else {
727
			pci_lock_rescan_remove();
728 729 730 731 732 733 734 735 736 737 738 739
			list_for_each_entry(hose, &hose_list, list_node) {
				phb_pe = eeh_phb_pe_get(hose);
				if (!phb_pe ||
				    !(phb_pe->state & EEH_PE_PHB_DEAD))
					continue;

				/* Notify all devices to be down */
				bus = eeh_pe_bus_get(phb_pe);
				eeh_pe_dev_traverse(pe,
					eeh_report_failure, NULL);
				pcibios_remove_pci_devices(bus);
			}
740
			pci_unlock_rescan_remove();
741
		}
742 743 744 745 746 747 748 749

		/*
		 * If we have detected dead IOC, we needn't proceed
		 * any more since all PHBs would have been removed
		 */
		if (rc == EEH_NEXT_ERR_DEAD_IOC)
			break;
	} while (rc != EEH_NEXT_ERR_NONE);
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
}

/**
 * eeh_handle_event - Reset a PCI device after hard lockup.
 * @pe: EEH PE
 *
 * While PHB detects address or data parity errors on particular PCI
 * slot, the associated PE will be frozen. Besides, DMA's occurring
 * to wild addresses (which usually happen due to bugs in device
 * drivers or in PCI adapter firmware) can cause EEH error. #SERR,
 * #PERR or other misc PCI-related errors also can trigger EEH errors.
 *
 * Recovery process consists of unplugging the device driver (which
 * generated hotplug events to userspace), then issuing a PCI #RST to
 * the device, then reconfiguring the PCI config space for all bridges
 * & devices under this slot, and then finally restarting the device
 * drivers (which cause a second set of hotplug events to go out to
 * userspace).
 */
void eeh_handle_event(struct eeh_pe *pe)
{
	if (pe)
		eeh_handle_normal_event(pe);
	else
		eeh_handle_special_event();
}