drivers/pci/hotplug/cpci_hotplug_core.c

Source file repositories/reference/linux-study-clean/drivers/pci/hotplug/cpci_hotplug_core.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/hotplug/cpci_hotplug_core.c
Extension
.c
Size
14249 bytes
Lines
632
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!slot) {
			status = -ENOMEM;
			goto error;
		}

		slot->bus = bus;
		slot->number = i;
		slot->devfn = PCI_DEVFN(i, 0);

		snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);

		slot->hotplug_slot.ops = &cpci_hotplug_slot_ops;

		dbg("registering slot %s", name);
		status = pci_hp_register(&slot->hotplug_slot, bus, i, name);
		if (status) {
			err("pci_hp_register failed with error %d", status);
			goto error_slot;
		}
		dbg("slot registered with name: %s", slot_name(slot));

		/* Add slot to our internal list */
		down_write(&list_rwsem);
		list_add(&slot->slot_list, &slot_list);
		slots++;
		up_write(&list_rwsem);
	}
	return 0;
error_slot:
	kfree(slot);
error:
	return status;
}
EXPORT_SYMBOL_GPL(cpci_hp_register_bus);

int
cpci_hp_unregister_bus(struct pci_bus *bus)
{
	struct slot *slot;
	struct slot *tmp;
	int status = 0;

	down_write(&list_rwsem);
	if (!slots) {
		up_write(&list_rwsem);
		return -1;
	}
	list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
		if (slot->bus == bus) {
			list_del(&slot->slot_list);
			slots--;

			dbg("deregistering slot %s", slot_name(slot));
			pci_hp_deregister(&slot->hotplug_slot);
			release_slot(slot);
		}
	}
	up_write(&list_rwsem);
	return status;
}
EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);

/* This is the interrupt mode interrupt handler */
static irqreturn_t
cpci_hp_intr(int irq, void *data)
{
	dbg("entered cpci_hp_intr");

	/* Check to see if it was our interrupt */
	if ((controller->irq_flags & IRQF_SHARED) &&
	    !controller->ops->check_irq(controller->dev_id)) {
		dbg("exited cpci_hp_intr, not our interrupt");
		return IRQ_NONE;
	}

	/* Disable ENUM interrupt */
	controller->ops->disable_irq();

	/* Trigger processing by the event thread */
	wake_up_process(cpci_thread);
	return IRQ_HANDLED;
}

/*
 * According to PICMG 2.1 R2.0, section 6.3.2, upon
 * initialization, the system driver shall clear the
 * INS bits of the cold-inserted devices.
 */
static int
init_slots(int clear_ins)

Annotation

Implementation Notes