arch/powerpc/kernel/eeh_driver.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/eeh_driver.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kernel/eeh_driver.c- Extension
.c- Size
- 33603 bytes
- Lines
- 1249
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/interrupt.hlinux/irq.hlinux/module.hlinux/pci.hlinux/pci_hotplug.hasm/eeh.hasm/eeh_event.hasm/ppc-pci.hasm/pci-bridge.hasm/rtas.h
Detected Declarations
struct eeh_rmv_datafunction eeh_result_priorityfunction pci_ers_merge_resultfunction eeh_dev_removedfunction eeh_edev_actionablefunction eeh_pcid_putfunction eeh_disable_irqfunction eeh_enable_irqfunction eeh_dev_save_statefunction eeh_set_channel_statefunction eeh_set_irq_statefunction eeh_for_each_pefunction eeh_pe_report_edevfunction eeh_pe_reportfunction eeh_report_errorfunction eeh_report_mmio_enabledfunction eeh_report_resetfunction eeh_dev_restore_statefunction eeh_report_resumefunction eeh_report_failurefunction eeh_rmv_devicefunction eeh_pe_for_each_devfunction resetfunction eeh_for_each_pefunction eeh_pe_reset_and_recoverfunction eeh_reset_devicefunction eeh_pe_cleanupfunction eeh_slot_presence_checkfunction eeh_clear_slot_attentionfunction addressesfunction eeh_for_each_pefunction eeh_handle_special_eventfunction list_for_each_entryfunction list_for_each_entry
Annotated Snippet
static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
{
if (!pdev || !pdev->dev.driver)
return NULL;
if (!try_module_get(pdev->dev.driver->owner))
return NULL;
return to_pci_driver(pdev->dev.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->dev.driver)
return;
module_put(pdev->dev.driver->owner);
}
/**
* 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.
*/
static void eeh_disable_irq(struct eeh_dev *edev)
{
/* Don't disable MSI and MSI-X interrupts. They are
* effectively disabled by the DMA Stopped state
* when an EEH error occurs.
*/
if (edev->pdev->msi_enabled || edev->pdev->msix_enabled)
return;
if (!irq_has_action(edev->pdev->irq))
return;
edev->mode |= EEH_DEV_IRQ_DISABLED;
disable_irq_nosync(edev->pdev->irq);
}
/**
* 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.
*/
static void eeh_enable_irq(struct eeh_dev *edev)
{
if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
edev->mode &= ~EEH_DEV_IRQ_DISABLED;
/*
* 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 asymmetries 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(edev->pdev->irq)))
enable_irq(edev->pdev->irq);
}
}
static void eeh_dev_save_state(struct eeh_dev *edev, void *userdata)
{
Annotation
- Immediate include surface: `linux/delay.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/module.h`, `linux/pci.h`, `linux/pci_hotplug.h`, `asm/eeh.h`, `asm/eeh_event.h`.
- Detected declarations: `struct eeh_rmv_data`, `function eeh_result_priority`, `function pci_ers_merge_result`, `function eeh_dev_removed`, `function eeh_edev_actionable`, `function eeh_pcid_put`, `function eeh_disable_irq`, `function eeh_enable_irq`, `function eeh_dev_save_state`, `function eeh_set_channel_state`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: pattern implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.