scripts/dtc/checks.c

Source file repositories/reference/linux-study-clean/scripts/dtc/checks.c

File Facts

System
Linux kernel
Corpus path
scripts/dtc/checks.c
Extension
.c
Size
55848 bytes
Lines
2083
Domain
Support Tooling And Documentation
Bucket
scripts
Inferred role
Support Tooling And Documentation: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct bus_type pci_bus = {
	.name = "PCI",
};

static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node)
{
	struct property *prop;
	cell_t *cells;

	prop = get_property(node, "device_type");
	if (!prop || !streq(prop->val.val, "pci"))
		return;

	node->bus = &pci_bus;

	if (!strprefixeq(node->name, node->basenamelen, "pci") &&
	    !strprefixeq(node->name, node->basenamelen, "pcie"))
		FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\"");

	prop = get_property(node, "ranges");
	if (!prop)
		FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)");

	if (node_addr_cells(node) != 3)
		FAIL(c, dti, node, "incorrect #address-cells for PCI bridge");
	if (node_size_cells(node) != 2)
		FAIL(c, dti, node, "incorrect #size-cells for PCI bridge");

	prop = get_property(node, "bus-range");
	if (!prop)
		return;

	if (prop->val.len != (sizeof(cell_t) * 2)) {
		FAIL_PROP(c, dti, node, prop, "value must be 2 cells");
		return;
	}
	cells = (cell_t *)prop->val.val;
	if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
		FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell");
	if (fdt32_to_cpu(cells[1]) > 0xff)
		FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256");
}
WARNING(pci_bridge, check_pci_bridge, NULL,
	&device_type_is_string, &addr_size_cells);

static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node)
{
	struct property *prop;
	unsigned int bus_num, min_bus, max_bus;
	cell_t *cells;

	if (!node->parent || (node->parent->bus != &pci_bus))
		return;

	prop = get_property(node, "reg");
	if (!prop)
		return;

	cells = (cell_t *)prop->val.val;
	bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16;

	prop = get_property(node->parent, "bus-range");
	if (!prop) {
		min_bus = max_bus = 0;
	} else {
		cells = (cell_t *)prop->val.val;
		min_bus = fdt32_to_cpu(cells[0]);
		max_bus = fdt32_to_cpu(cells[1]);
	}
	if ((bus_num < min_bus) || (bus_num > max_bus))
		FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
			  bus_num, min_bus, max_bus);
}
WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);

static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node)
{
	struct property *prop;
	const char *unitname = get_unitname(node);
	char unit_addr[5];
	unsigned int dev, func, reg;
	cell_t *cells;

	if (!node->parent || (node->parent->bus != &pci_bus))
		return;

	prop = get_property(node, "reg");
	if (!prop)
		return;

Annotation

Implementation Notes