drivers/pci/hotplug/shpchp_hpc.c
Source file repositories/reference/linux-study-clean/drivers/pci/hotplug/shpchp_hpc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/hotplug/shpchp_hpc.c- Extension
.c- Size
- 26651 bytes
- Lines
- 1049
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/types.hlinux/pci.hlinux/interrupt.hshpchp.h
Detected Declarations
function shpc_readbfunction shpc_readwfunction shpc_writewfunction shpc_readlfunction shpc_writelfunction shpc_indirect_readfunction int_poll_timeoutfunction start_int_poll_timerfunction is_ctrl_busyfunction shpc_poll_ctrl_busyfunction shpc_wait_cmdfunction shpc_write_cmdfunction shpchp_check_cmd_statusfunction shpchp_get_attention_statusfunction shpchp_get_power_statusfunction shpchp_get_latch_statusfunction shpchp_get_adapter_statusfunction shpchp_get_prog_intfunction shpchp_get_adapter_speedfunction shpchp_query_power_faultfunction shpchp_set_attention_statusfunction shpchp_green_led_onfunction shpchp_green_led_offfunction shpchp_green_led_blinkfunction shpchp_release_ctlrfunction shpchp_power_on_slotfunction shpchp_slot_enablefunction shpchp_slot_disablefunction shpc_get_cur_bus_speedfunction shpchp_set_bus_speed_modefunction shpc_isrfunction shpc_get_max_bus_speedfunction shpc_init
Annotated Snippet
if (!ctrl->cap_offset) {
ctrl_err(ctrl, "Cannot find PCI capability\n");
goto abort;
}
ctrl_dbg(ctrl, " cap_offset = %x\n", ctrl->cap_offset);
rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
if (rc) {
ctrl_err(ctrl, "Cannot read base_offset\n");
goto abort;
}
rc = shpc_indirect_read(ctrl, 3, &tempdword);
if (rc) {
ctrl_err(ctrl, "Cannot read slot config\n");
goto abort;
}
num_slots = tempdword & SLOT_NUM;
ctrl_dbg(ctrl, " num_slots (indirect) %x\n", num_slots);
for (i = 0; i < 9 + num_slots; i++) {
rc = shpc_indirect_read(ctrl, i, &tempdword);
if (rc) {
ctrl_err(ctrl, "Cannot read creg (index = %d)\n",
i);
goto abort;
}
ctrl_dbg(ctrl, " offset %d: value %x\n", i, tempdword);
}
ctrl->mmio_base =
pci_resource_start(pdev, 0) + shpc_base_offset;
ctrl->mmio_size = 0x24 + 0x4 * num_slots;
}
ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
pdev->vendor, pdev->device, pdev->subsystem_vendor,
pdev->subsystem_device);
rc = pci_enable_device(pdev);
if (rc) {
ctrl_err(ctrl, "pci_enable_device failed\n");
goto abort;
}
if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
ctrl_err(ctrl, "Cannot reserve MMIO region\n");
rc = -1;
goto abort;
}
ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
if (!ctrl->creg) {
ctrl_err(ctrl, "Cannot remap MMIO region %lx @ %lx\n",
ctrl->mmio_size, ctrl->mmio_base);
release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
rc = -1;
goto abort;
}
ctrl_dbg(ctrl, "ctrl->creg %p\n", ctrl->creg);
mutex_init(&ctrl->crit_sect);
mutex_init(&ctrl->cmd_lock);
/* Setup wait queue */
init_waitqueue_head(&ctrl->queue);
/* Return PCI Controller Info */
slot_config = shpc_readl(ctrl, SLOT_CONFIG);
ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
ctrl->num_slots = slot_config & SLOT_NUM;
ctrl->first_slot = (slot_config & PSN) >> 16;
ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
ctrl_dbg(ctrl, "SERR_INTR_ENABLE = %x\n", tempdword);
tempdword |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
COMMAND_INTR_MASK | ARBITER_SERR_MASK);
tempdword &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
ctrl_dbg(ctrl, "SERR_INTR_ENABLE = %x\n", tempdword);
/* Mask the MRL sensor SERR Mask of individual slot in
* Slot SERR-INT Mask & clear all the existing event if any
*/
for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
ctrl_dbg(ctrl, "Default Logical Slot Register %d value %x\n",
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/types.h`, `linux/pci.h`, `linux/interrupt.h`, `shpchp.h`.
- Detected declarations: `function shpc_readb`, `function shpc_readw`, `function shpc_writew`, `function shpc_readl`, `function shpc_writel`, `function shpc_indirect_read`, `function int_poll_timeout`, `function start_int_poll_timer`, `function is_ctrl_busy`, `function shpc_poll_ctrl_busy`.
- 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.