drivers/pci/switch/switchtec.c
Source file repositories/reference/linux-study-clean/drivers/pci/switch/switchtec.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/switch/switchtec.c- Extension
.c- Size
- 53048 bytes
- Lines
- 1913
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/switchtec.hlinux/switchtec_ioctl.hlinux/interrupt.hlinux/module.hlinux/fs.hlinux/uaccess.hlinux/poll.hlinux/wait.hlinux/io-64-nonatomic-lo-hi.hlinux/nospec.h
Detected Declarations
struct switchtec_userenum mrpc_statefunction is_firmware_runningfunction stuser_freefunction stuser_putfunction stuser_set_statefunction flush_wc_buffunction mrpc_cmd_submitfunction mrpc_queue_cmdfunction mrpc_cleanup_cmdfunction mrpc_complete_cmdfunction mrpc_event_workfunction mrpc_error_complete_cmdfunction mrpc_timeout_workfunction device_version_showfunction fw_version_showfunction io_string_showfunction component_vendor_showfunction component_id_showfunction component_revision_showfunction partition_showfunction partition_count_showfunction switchtec_dev_openfunction switchtec_dev_releasefunction lock_mutex_and_test_alivefunction switchtec_dev_writefunction switchtec_dev_readfunction switchtec_dev_pollfunction ioctl_flash_infofunction set_fw_info_partfunction flash_part_info_gen3function flash_part_info_gen4function ioctl_flash_part_infofunction ioctl_event_summaryfunction event_ctlfunction ioctl_event_ctlfunction ioctl_pff_to_portfunction ioctl_port_to_pfffunction switchtec_dev_ioctlfunction link_event_workfunction check_link_state_eventsfunction enable_link_state_eventsfunction enable_dma_mrpcfunction stdev_releasefunction stdev_killfunction list_for_each_entry_safefunction mask_eventfunction mask_all_events
Annotated Snippet
static const struct file_operations switchtec_fops = {
.owner = THIS_MODULE,
.open = switchtec_dev_open,
.release = switchtec_dev_release,
.write = switchtec_dev_write,
.read = switchtec_dev_read,
.poll = switchtec_dev_poll,
.unlocked_ioctl = switchtec_dev_ioctl,
.compat_ioctl = compat_ptr_ioctl,
};
static void link_event_work(struct work_struct *work)
{
struct switchtec_dev *stdev;
stdev = container_of(work, struct switchtec_dev, link_event_work);
if (stdev->link_notifier)
stdev->link_notifier(stdev);
}
static void check_link_state_events(struct switchtec_dev *stdev)
{
int idx;
u32 reg;
int count;
int occurred = 0;
for (idx = 0; idx < stdev->pff_csr_count; idx++) {
reg = ioread32(&stdev->mmio_pff_csr[idx].link_state_hdr);
dev_dbg(&stdev->dev, "link_state: %d->%08x\n", idx, reg);
count = (reg >> 5) & 0xFF;
if (count != stdev->link_event_count[idx]) {
occurred = 1;
stdev->link_event_count[idx] = count;
}
}
if (occurred)
schedule_work(&stdev->link_event_work);
}
static void enable_link_state_events(struct switchtec_dev *stdev)
{
int idx;
for (idx = 0; idx < stdev->pff_csr_count; idx++) {
iowrite32(SWITCHTEC_EVENT_CLEAR |
SWITCHTEC_EVENT_EN_IRQ,
&stdev->mmio_pff_csr[idx].link_state_hdr);
}
}
static void enable_dma_mrpc(struct switchtec_dev *stdev)
{
writeq(stdev->dma_mrpc_dma_addr, &stdev->mmio_mrpc->dma_addr);
flush_wc_buf(stdev);
iowrite32(SWITCHTEC_DMA_MRPC_EN, &stdev->mmio_mrpc->dma_en);
}
static void stdev_release(struct device *dev)
{
struct switchtec_dev *stdev = to_stdev(dev);
kfree(stdev);
}
static void stdev_kill(struct switchtec_dev *stdev)
{
struct switchtec_user *stuser, *tmpuser;
pci_clear_master(stdev->pdev);
cancel_delayed_work_sync(&stdev->mrpc_timeout);
/* Mark the hardware as unavailable and complete all completions */
scoped_guard (mutex, &stdev->mrpc_mutex) {
stdev->alive = false;
/* Wake up and kill any users waiting on an MRPC request */
list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) {
stuser->cmd_done = true;
wake_up_interruptible(&stuser->cmd_comp);
list_del_init(&stuser->list);
stuser_put(stuser);
}
}
Annotation
- Immediate include surface: `linux/switchtec.h`, `linux/switchtec_ioctl.h`, `linux/interrupt.h`, `linux/module.h`, `linux/fs.h`, `linux/uaccess.h`, `linux/poll.h`, `linux/wait.h`.
- Detected declarations: `struct switchtec_user`, `enum mrpc_state`, `function is_firmware_running`, `function stuser_free`, `function stuser_put`, `function stuser_set_state`, `function flush_wc_buf`, `function mrpc_cmd_submit`, `function mrpc_queue_cmd`, `function mrpc_cleanup_cmd`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.