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.

Dependency Surface

Detected Declarations

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

Implementation Notes