arch/x86/kernel/probe_roms.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/probe_roms.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/probe_roms.c
Extension
.c
Size
6464 bytes
Lines
271
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pci_driver *drv = to_pci_driver(pdev->dev.driver);
	const struct pci_device_id *id;

	if (pdev->vendor == vendor && pdev->device == device)
		return true;

	for (id = drv ? drv->id_table : NULL; id && id->vendor; id++)
		if (id->vendor == vendor && id->device == device)
			break;

	return id && id->vendor;
}

static bool probe_list(struct pci_dev *pdev, unsigned short vendor,
		       const void *rom_list)
{
	unsigned short device;

	do {
		if (get_kernel_nofault(device, rom_list) != 0)
			device = 0;

		if (device && match_id(pdev, vendor, device))
			break;

		rom_list += 2;
	} while (device);

	return !!device;
}

static struct resource *find_oprom(struct pci_dev *pdev)
{
	struct resource *oprom = NULL;
	int i;

	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
		struct resource *res = &adapter_rom_resources[i];
		unsigned short offset, vendor, device, list, rev;
		const void *rom;

		if (res->end == 0)
			break;

		rom = isa_bus_to_virt(res->start);
		if (get_kernel_nofault(offset, rom + 0x18) != 0)
			continue;

		if (get_kernel_nofault(vendor, rom + offset + 0x4) != 0)
			continue;

		if (get_kernel_nofault(device, rom + offset + 0x6) != 0)
			continue;

		if (match_id(pdev, vendor, device)) {
			oprom = res;
			break;
		}

		if (get_kernel_nofault(list, rom + offset + 0x8) == 0 &&
		    get_kernel_nofault(rev, rom + offset + 0xc) == 0 &&
		    rev >= 3 && list &&
		    probe_list(pdev, vendor, rom + offset + list)) {
			oprom = res;
			break;
		}
	}

	return oprom;
}

void __iomem *pci_map_biosrom(struct pci_dev *pdev)
{
	struct resource *oprom = find_oprom(pdev);

	if (!oprom)
		return NULL;

	return ioremap(oprom->start, resource_size(oprom));
}
EXPORT_SYMBOL(pci_map_biosrom);

void pci_unmap_biosrom(void __iomem *image)
{
	iounmap(image);
}
EXPORT_SYMBOL(pci_unmap_biosrom);

size_t pci_biosrom_size(struct pci_dev *pdev)
{

Annotation

Implementation Notes