drivers/pci/hotplug/pciehp_hpc.c
Source file repositories/reference/linux-study-clean/drivers/pci/hotplug/pciehp_hpc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/hotplug/pciehp_hpc.c- Extension
.c- Size
- 31386 bytes
- Lines
- 1125
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: implementation source
- Status
- source implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/dmi.hlinux/kernel.hlinux/types.hlinux/jiffies.hlinux/kthread.hlinux/pci.hlinux/pm_runtime.hlinux/interrupt.hlinux/slab.h../pci.hpciehp.h
Detected Declarations
function pciehp_request_irqfunction pciehp_free_irqfunction pcie_poll_cmdfunction pcie_wait_cmdfunction pcie_do_write_cmdfunction pcie_write_cmdfunction pcie_write_cmd_nowaitfunction pciehp_check_link_activefunction pci_bus_check_devfunction pcie_wait_for_presencefunction pciehp_check_link_statusfunction __pciehp_link_setfunction pciehp_link_enablefunction pciehp_get_raw_indicator_statusfunction pciehp_get_attention_statusfunction pciehp_get_power_statusfunction pciehp_get_latch_statusfunction pciehp_card_presentfunction pciehp_card_present_or_link_activefunction pciehp_query_power_faultfunction pciehp_set_raw_indicator_statusfunction pciehp_set_indicatorsfunction pciehp_power_on_slotfunction pciehp_power_off_slotfunction pciehp_device_replacedfunction pciehp_ignore_link_changefunction pciehp_isrfunction pciehp_istfunction pciehp_pollfunction pcie_enable_notificationfunction pcie_disable_notificationfunction pcie_clear_hotplug_eventsfunction pcie_enable_interruptfunction pcie_disable_interruptfunction pciehp_slot_resetfunction pciehp_reset_slotfunction pcie_init_notificationfunction pcie_shutdown_notificationfunction dbg_ctrlfunction pcie_hotplug_depthfunction pciehp_release_ctrlfunction quirk_cmd_compl
Annotated Snippet
if (PCI_POSSIBLE_ERROR(slot_status)) {
ctrl_info(ctrl, "%s: no response from device\n",
__func__);
return 0;
}
if (slot_status & PCI_EXP_SLTSTA_CC) {
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_CC);
ctrl->cmd_busy = 0;
smp_mb();
return 1;
}
msleep(10);
timeout -= 10;
} while (timeout >= 0);
return 0; /* timeout */
}
static void pcie_wait_cmd(struct controller *ctrl)
{
unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
unsigned long duration = msecs_to_jiffies(msecs);
unsigned long cmd_timeout = ctrl->cmd_started + duration;
unsigned long now, timeout;
int rc;
/*
* If the controller does not generate notifications for command
* completions, we never need to wait between writes.
*/
if (NO_CMD_CMPL(ctrl))
return;
if (!ctrl->cmd_busy)
return;
/*
* Even if the command has already timed out, we want to call
* pcie_poll_cmd() so it can clear PCI_EXP_SLTSTA_CC.
*/
now = jiffies;
if (time_before_eq(cmd_timeout, now))
timeout = 1;
else
timeout = cmd_timeout - now;
if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE &&
ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE)
rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
else
rc = pcie_poll_cmd(ctrl, jiffies_to_msecs(timeout));
if (!rc)
ctrl_info(ctrl, "Timeout on hotplug command %#06x (issued %u msec ago)\n",
ctrl->slot_ctrl,
jiffies_to_msecs(jiffies - ctrl->cmd_started));
}
#define CC_ERRATUM_MASK (PCI_EXP_SLTCTL_PCC | \
PCI_EXP_SLTCTL_PIC | \
PCI_EXP_SLTCTL_AIC | \
PCI_EXP_SLTCTL_EIC)
static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
u16 mask, bool wait)
{
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_ctrl_orig, slot_ctrl;
mutex_lock(&ctrl->ctrl_lock);
/*
* Always wait for any previous command that might still be in progress
*/
pcie_wait_cmd(ctrl);
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
if (PCI_POSSIBLE_ERROR(slot_ctrl)) {
ctrl_info(ctrl, "%s: no response from device\n", __func__);
goto out;
}
slot_ctrl_orig = slot_ctrl;
slot_ctrl &= ~mask;
slot_ctrl |= (cmd & mask);
ctrl->cmd_busy = 1;
smp_mb();
ctrl->slot_ctrl = slot_ctrl;
pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/dmi.h`, `linux/kernel.h`, `linux/types.h`, `linux/jiffies.h`, `linux/kthread.h`, `linux/pci.h`, `linux/pm_runtime.h`.
- Detected declarations: `function pciehp_request_irq`, `function pciehp_free_irq`, `function pcie_poll_cmd`, `function pcie_wait_cmd`, `function pcie_do_write_cmd`, `function pcie_write_cmd`, `function pcie_write_cmd_nowait`, `function pciehp_check_link_active`, `function pci_bus_check_dev`, `function pcie_wait_for_presence`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: source 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.