arch/s390/pci/pci_event.c
Source file repositories/reference/linux-study-clean/arch/s390/pci/pci_event.c
File Facts
- System
- Linux kernel
- Corpus path
arch/s390/pci/pci_event.c- Extension
.c- Size
- 13379 bytes
- Lines
- 480
- Domain
- Architecture Layer
- Bucket
- arch/s390
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/kernel.hlinux/pci.hasm/pci_debug.hasm/pci_dma.hasm/sclp.hpci_bus.hpci_report.h
Detected Declarations
struct zpci_ccdf_errstruct zpci_ccdf_availfunction ers_result_indicates_abortfunction is_passed_throughfunction is_driver_supportedfunction zpci_event_notify_error_detectedfunction zpci_event_do_error_state_clearfunction zpci_event_do_resetfunction zpci_event_attempt_error_recoveryfunction zpci_event_io_failurefunction __zpci_event_errorfunction zpci_event_errorfunction zpci_event_hard_deconfiguredfunction zpci_event_reappearfunction __zpci_event_availabilityfunction zpci_event_availability
Annotated Snippet
static bool is_driver_supported(struct pci_driver *driver)
{
if (!driver || !driver->err_handler)
return false;
if (!driver->err_handler->error_detected)
return false;
return true;
}
static pci_ers_result_t zpci_event_notify_error_detected(struct pci_dev *pdev,
struct pci_driver *driver)
{
pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
ers_res = driver->err_handler->error_detected(pdev, pdev->error_state);
pci_uevent_ers(pdev, ers_res);
if (ers_result_indicates_abort(ers_res))
pr_info("%s: Automatic recovery failed after initial reporting\n", pci_name(pdev));
else if (ers_res == PCI_ERS_RESULT_NEED_RESET)
pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
return ers_res;
}
static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
struct pci_driver *driver)
{
pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
struct zpci_dev *zdev = to_zpci(pdev);
int rc;
/* The underlying device may have been disabled by the event */
if (!zdev_enabled(zdev))
return PCI_ERS_RESULT_NEED_RESET;
pr_info("%s: Unblocking device access for examination\n", pci_name(pdev));
rc = zpci_reset_load_store_blocked(zdev);
if (rc) {
pr_err("%s: Unblocking device access failed\n", pci_name(pdev));
/* Let's try a full reset instead */
return PCI_ERS_RESULT_NEED_RESET;
}
if (driver->err_handler->mmio_enabled)
ers_res = driver->err_handler->mmio_enabled(pdev);
else
ers_res = PCI_ERS_RESULT_NONE;
if (ers_result_indicates_abort(ers_res)) {
pr_info("%s: Automatic recovery failed after MMIO re-enable\n",
pci_name(pdev));
return ers_res;
} else if (ers_res == PCI_ERS_RESULT_NEED_RESET) {
pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
return ers_res;
}
pr_debug("%s: Unblocking DMA\n", pci_name(pdev));
rc = zpci_clear_error_state(zdev);
if (!rc) {
pdev->error_state = pci_channel_io_normal;
} else {
pr_err("%s: Unblocking DMA failed\n", pci_name(pdev));
/* Let's try a full reset instead */
return PCI_ERS_RESULT_NEED_RESET;
}
return ers_res;
}
static pci_ers_result_t zpci_event_do_reset(struct pci_dev *pdev,
struct pci_driver *driver)
{
pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
pr_info("%s: Initiating reset\n", pci_name(pdev));
if (zpci_hot_reset_device(to_zpci(pdev))) {
pr_err("%s: The reset request failed\n", pci_name(pdev));
return ers_res;
}
pdev->error_state = pci_channel_io_normal;
if (driver->err_handler->slot_reset)
ers_res = driver->err_handler->slot_reset(pdev);
else
ers_res = PCI_ERS_RESULT_NONE;
if (ers_result_indicates_abort(ers_res)) {
pr_info("%s: Automatic recovery failed after slot reset\n", pci_name(pdev));
return ers_res;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/pci.h`, `asm/pci_debug.h`, `asm/pci_dma.h`, `asm/sclp.h`, `pci_bus.h`, `pci_report.h`.
- Detected declarations: `struct zpci_ccdf_err`, `struct zpci_ccdf_avail`, `function ers_result_indicates_abort`, `function is_passed_through`, `function is_driver_supported`, `function zpci_event_notify_error_detected`, `function zpci_event_do_error_state_clear`, `function zpci_event_do_reset`, `function zpci_event_attempt_error_recovery`, `function zpci_event_io_failure`.
- Atlas domain: Architecture Layer / arch/s390.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.