drivers/pci/setup-cardbus.c

Source file repositories/reference/linux-study-clean/drivers/pci/setup-cardbus.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/setup-cardbus.c
Extension
.c
Size
8841 bytes
Lines
307
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 (realloc_head) {
			b_res->end -= pci_cardbus_mem_size;
			pci_dev_res_add_to_list(realloc_head, bridge, b_res,
						pci_cardbus_mem_size,
						pci_cardbus_mem_size);
		}

		/* Reduce that to half */
		b_res_3_size = pci_cardbus_mem_size;
	}

handle_b_res_3:
	b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
	if (resource_assigned(b_res))
		goto handle_done;
	resource_set_range(b_res, pci_cardbus_mem_size, b_res_3_size);
	b_res->flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN;
	if (realloc_head) {
		b_res->end -= b_res_3_size;
		pci_dev_res_add_to_list(realloc_head, bridge, b_res,
					b_res_3_size, pci_cardbus_mem_size);
	}

handle_done:
	return 0;
}

void pci_setup_cardbus_bridge(struct pci_bus *bus)
{
	struct pci_dev *bridge = bus->self;
	struct resource *res;
	struct pci_bus_region region;

	pci_info(bridge, "CardBus bridge to %pR\n",
		 &bus->busn_res);

	res = bus->resource[0];
	pcibios_resource_to_bus(bridge->bus, &region, res);
	if (resource_assigned(res) && res->flags & IORESOURCE_IO) {
		/*
		 * The IO resource is allocated a range twice as large as it
		 * would normally need.  This allows us to set both IO regs.
		 */
		pci_info(bridge, "  bridge window %pR\n", res);
		pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
					region.start);
		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
					region.end);
	}

	res = bus->resource[1];
	pcibios_resource_to_bus(bridge->bus, &region, res);
	if (resource_assigned(res) && res->flags & IORESOURCE_IO) {
		pci_info(bridge, "  bridge window %pR\n", res);
		pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
					region.start);
		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
					region.end);
	}

	res = bus->resource[2];
	pcibios_resource_to_bus(bridge->bus, &region, res);
	if (resource_assigned(res) && res->flags & IORESOURCE_MEM) {
		pci_info(bridge, "  bridge window %pR\n", res);
		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
					region.start);
		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
					region.end);
	}

	res = bus->resource[3];
	pcibios_resource_to_bus(bridge->bus, &region, res);
	if (resource_assigned(res) && res->flags & IORESOURCE_MEM) {
		pci_info(bridge, "  bridge window %pR\n", res);
		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
					region.start);
		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
					region.end);
	}
}
EXPORT_SYMBOL(pci_setup_cardbus_bridge);

int pci_setup_cardbus(char *str)
{
	if (!strncmp(str, "cbiosize=", 9)) {
		pci_cardbus_io_size = memparse(str + 9, &str);
		return 0;
	} else if (!strncmp(str, "cbmemsize=", 10)) {
		pci_cardbus_mem_size = memparse(str + 10, &str);
		return 0;

Annotation

Implementation Notes