static int cxl_find_regblock()

in pci.c [423:453]


static int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
			     struct cxl_register_map *map)
{
	u32 regloc_size, regblocks;
	int regloc, i;

	regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL,
					   PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
	if (!regloc)
		return -ENXIO;

	pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, &regloc_size);
	regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size);

	regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET;
	regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8;

	for (i = 0; i < regblocks; i++, regloc += 8) {
		u32 reg_lo, reg_hi;

		pci_read_config_dword(pdev, regloc, &reg_lo);
		pci_read_config_dword(pdev, regloc + 4, &reg_hi);

		cxl_decode_regblock(reg_lo, reg_hi, map);

		if (map->reg_type == type)
			return 0;
	}

	return -ENODEV;
}