drivers/pci/hotplug/ibmphp_ebda.c

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

File Facts

System
Linux kernel
Corpus path
drivers/pci/hotplug/ibmphp_ebda.c
Extension
.c
Size
32171 bytes
Lines
1119
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver ibmphp_driver;

/*
 * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
 * each hpc from physical address to a list of hot plug controllers based on
 * hpc descriptors.
 */
static int __init ebda_rsrc_controller(void)
{
	u16 addr, addr_slot, addr_bus;
	u8 ctlr_id, temp, bus_index;
	u16 ctlr, slot, bus;
	u16 slot_num, bus_num, index;
	struct controller *hpc_ptr;
	struct ebda_hpc_bus *bus_ptr;
	struct ebda_hpc_slot *slot_ptr;
	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
	int rc;
	struct slot *tmp_slot;
	char name[SLOT_NAME_SIZE];

	addr = hpc_list_ptr->phys_addr;
	for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
		bus_index = 1;
		ctlr_id = readb(io_mem + addr);
		addr += 1;
		slot_num = readb(io_mem + addr);

		addr += 1;
		addr_slot = addr;	/* offset of slot structure */
		addr += (slot_num * 4);

		bus_num = readb(io_mem + addr);

		addr += 1;
		addr_bus = addr;	/* offset of bus */
		addr += (bus_num * 9);	/* offset of ctlr_type */
		temp = readb(io_mem + addr);

		addr += 1;
		/* init hpc structure */
		hpc_ptr = alloc_ebda_hpc(slot_num, bus_num);
		if (!hpc_ptr) {
			return -ENOMEM;
		}
		hpc_ptr->ctlr_id = ctlr_id;
		hpc_ptr->ctlr_relative_id = ctlr;
		hpc_ptr->slot_count = slot_num;
		hpc_ptr->bus_count = bus_num;
		debug("now enter ctlr data structure ---\n");
		debug("ctlr id: %x\n", ctlr_id);
		debug("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
		debug("count of slots controlled by this ctlr: %x\n", slot_num);
		debug("count of buses controlled by this ctlr: %x\n", bus_num);

		/* init slot structure, fetch slot, bus, cap... */
		slot_ptr = hpc_ptr->slots;
		for (slot = 0; slot < slot_num; slot++) {
			slot_ptr->slot_num = readb(io_mem + addr_slot);
			slot_ptr->slot_bus_num = readb(io_mem + addr_slot + slot_num);
			slot_ptr->ctl_index = readb(io_mem + addr_slot + 2*slot_num);
			slot_ptr->slot_cap = readb(io_mem + addr_slot + 3*slot_num);

			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max

			bus_info_ptr2 = ibmphp_find_same_bus_num(slot_ptr->slot_bus_num);
			if (!bus_info_ptr2) {
				bus_info_ptr1 = kzalloc_obj(struct bus_info);
				if (!bus_info_ptr1) {
					rc = -ENOMEM;
					goto error_no_slot;
				}
				bus_info_ptr1->slot_min = slot_ptr->slot_num;
				bus_info_ptr1->slot_max = slot_ptr->slot_num;
				bus_info_ptr1->slot_count += 1;
				bus_info_ptr1->busno = slot_ptr->slot_bus_num;
				bus_info_ptr1->index = bus_index++;
				bus_info_ptr1->current_speed = 0xff;
				bus_info_ptr1->current_bus_mode = 0xff;

				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;

				list_add_tail(&bus_info_ptr1->bus_info_list, &bus_info_head);

			} else {
				bus_info_ptr2->slot_min = min(bus_info_ptr2->slot_min, slot_ptr->slot_num);
				bus_info_ptr2->slot_max = max(bus_info_ptr2->slot_max, slot_ptr->slot_num);
				bus_info_ptr2->slot_count += 1;

			}

Annotation

Implementation Notes