drivers/misc/hpilo.c
Source file repositories/reference/linux-study-clean/drivers/misc/hpilo.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/hpilo.c- Extension
.c- Size
- 22365 bytes
- Lines
- 928
- Domain
- Driver Families
- Bucket
- drivers/misc
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/kernel.hlinux/types.hlinux/module.hlinux/fs.hlinux/pci.hlinux/interrupt.hlinux/ioport.hlinux/device.hlinux/file.hlinux/cdev.hlinux/sched.hlinux/spinlock.hlinux/delay.hlinux/uaccess.hlinux/io.hlinux/wait.hlinux/poll.hlinux/slab.hhpilo.h
Detected Declarations
function get_entry_idfunction get_entry_lenfunction mk_entryfunction desc_mem_szfunction fifo_enqueuefunction fifo_dequeuefunction fifo_check_recvfunction ilo_pkt_enqueuefunction ilo_pkt_dequeuefunction ilo_pkt_recvfunction doorbell_setfunction doorbell_clrfunction ctrl_setfunction ctrl_setupfunction fifo_szfunction fifo_setupfunction ilo_ccb_closefunction ilo_ccb_setupfunction ilo_ccb_openfunction ilo_ccb_verifyfunction is_channel_resetfunction set_channel_resetfunction get_device_outboundfunction is_db_resetfunction clear_pending_dbfunction clear_devicefunction ilo_enable_interruptsfunction ilo_disable_interruptsfunction ilo_set_resetfunction ilo_readfunction ilo_writefunction ilo_pollfunction ilo_closefunction ilo_openfunction ilo_isrfunction ilo_unmap_devicefunction ilo_map_devicefunction ilo_removefunction ilo_probefunction ilo_initfunction ilo_exitmodule init ilo_init
Annotated Snippet
static const struct file_operations ilo_fops = {
.owner = THIS_MODULE,
.read = ilo_read,
.write = ilo_write,
.poll = ilo_poll,
.open = ilo_open,
.release = ilo_close,
.llseek = noop_llseek,
};
static irqreturn_t ilo_isr(int irq, void *data)
{
struct ilo_hwinfo *hw = data;
int pending, i;
spin_lock(&hw->alloc_lock);
/* check for ccbs which have data */
pending = get_device_outbound(hw);
if (!pending) {
spin_unlock(&hw->alloc_lock);
return IRQ_NONE;
}
if (is_db_reset(pending)) {
/* wake up all ccbs if the device was reset */
pending = -1;
ilo_set_reset(hw);
}
for (i = 0; i < max_ccb; i++) {
if (!hw->ccb_alloc[i])
continue;
if (pending & (1 << i))
wake_up_interruptible(&hw->ccb_alloc[i]->ccb_waitq);
}
/* clear the device of the channels that have been handled */
clear_pending_db(hw, pending);
spin_unlock(&hw->alloc_lock);
return IRQ_HANDLED;
}
static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
{
pci_iounmap(pdev, hw->db_vaddr);
pci_iounmap(pdev, hw->ram_vaddr);
pci_iounmap(pdev, hw->mmio_vaddr);
}
static int ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
{
int bar;
unsigned long off;
u8 pci_rev_id;
int rc;
/* map the memory mapped i/o registers */
hw->mmio_vaddr = pci_iomap(pdev, 1, 0);
if (hw->mmio_vaddr == NULL) {
dev_err(&pdev->dev, "Error mapping mmio\n");
goto out;
}
/* map the adapter shared memory region */
rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev_id);
if (rc != 0) {
dev_err(&pdev->dev, "Error reading PCI rev id: %d\n", rc);
goto out;
}
if (pci_rev_id >= PCI_REV_ID_NECHES) {
bar = 5;
/* Last 8k is reserved for CCBs */
off = pci_resource_len(pdev, bar) - 0x2000;
} else {
bar = 2;
off = 0;
}
hw->ram_vaddr = pci_iomap_range(pdev, bar, off, max_ccb * ILOHW_CCB_SZ);
if (hw->ram_vaddr == NULL) {
dev_err(&pdev->dev, "Error mapping shared mem\n");
goto mmio_free;
}
/* map the doorbell aperture */
hw->db_vaddr = pci_iomap(pdev, 3, max_ccb * ONE_DB_SIZE);
if (hw->db_vaddr == NULL) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/types.h`, `linux/module.h`, `linux/fs.h`, `linux/pci.h`, `linux/interrupt.h`, `linux/ioport.h`, `linux/device.h`.
- Detected declarations: `function get_entry_id`, `function get_entry_len`, `function mk_entry`, `function desc_mem_sz`, `function fifo_enqueue`, `function fifo_dequeue`, `function fifo_check_recv`, `function ilo_pkt_enqueue`, `function ilo_pkt_dequeue`, `function ilo_pkt_recv`.
- Atlas domain: Driver Families / drivers/misc.
- 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.