From 42f3663a3f67b4da4dcdaaea615e3645aec0ba78 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 16 Dec 2020 21:20:18 -0700 Subject: [PATCH] pci: Update to use new sequence numbers Now that we know the sequence number at bind time, there is no need for special-case code in dm_pci_hose_probe_bus(). Note: the PCI_CAP_ID_EA code may need a look, but there are no test failures so I have left it as is. Signed-off-by: Simon Glass --- drivers/pci/pci-uclass.c | 45 ++++++++++++++++++++++++---------------- drivers/pci/pci_auto.c | 10 ++++----- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index ebe7fb7cd2..bff183eea2 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -14,6 +14,7 @@ #include #include #include +#include #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) #include #endif @@ -544,7 +545,7 @@ int pci_auto_config_devices(struct udevice *bus) continue; ret = dm_pciauto_config_device(dev); if (ret < 0) - return ret; + return log_msg_ret("auto", ret); max_bus = ret; sub_bus = max(sub_bus, max_bus); @@ -554,7 +555,7 @@ int pci_auto_config_devices(struct udevice *bus) } debug("%s: done\n", __func__); - return sub_bus; + return log_msg_ret("sub", sub_bus); } int pci_generic_mmap_write_config( @@ -641,17 +642,9 @@ int dm_pci_hose_probe_bus(struct udevice *bus) if (ret) { debug("%s: Cannot probe bus %s: %d\n", __func__, bus->name, ret); - return ret; + return log_msg_ret("probe", ret); } - if (!ea_pos) { - if (sub_bus != dev_seq(bus)) { - debug("%s: Internal error, bus '%s' got seq %d, expected %d\n", - __func__, bus->name, dev_seq(bus), sub_bus); - return -EPIPE; - } - sub_bus = pci_get_bus_max(); - } dm_pciauto_postscan_setup_bridge(bus, sub_bus); return sub_bus; @@ -714,7 +707,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, if (ofnode_valid(node) && !ofnode_is_available(node)) { debug("%s: Ignoring disabled device\n", __func__); - return -EPERM; + return log_msg_ret("dis", -EPERM); } start = ll_entry_start(struct pci_driver_entry, pci_driver_entry); @@ -740,7 +733,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, */ if (!(gd->flags & GD_FLG_RELOC) && !(drv->flags & DM_FLAG_PRE_RELOC)) - return -EPERM; + return log_msg_ret("pre", -EPERM); /* * We could pass the descriptor to the driver as @@ -768,7 +761,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, * limited (ie: using Cache As RAM). */ if (!(gd->flags & GD_FLG_RELOC) && !bridge) - return -EPERM; + return log_msg_ret("notbr", -EPERM); /* Bind a generic driver so that the device can be used */ sprintf(name, "pci_%x:%x.%x", dev_seq(parent), PCI_DEV(bdf), @@ -1009,11 +1002,26 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node, static int pci_uclass_pre_probe(struct udevice *bus) { struct pci_controller *hose; + struct uclass *uc; + int ret; debug("%s, bus=%d/%s, parent=%s\n", __func__, dev_seq(bus), bus->name, bus->parent->name); hose = bus->uclass_priv; + /* + * Set the sequence number, if device_bind() doesn't. We want control + * of this so that numbers are allocated as devices are probed. That + * ensures that sub-bus numbered is correct (sub-buses must get numbers + * higher than their parents) + */ + if (dev_seq(bus) == -1) { + ret = uclass_get(UCLASS_PCI, &uc); + if (ret) + return ret; + bus->sqq = uclass_find_next_free_req_seq(uc); + } + /* For bridges, use the top-level PCI controller */ if (!device_is_on_pci_bus(bus)) { hose->ctlr = bus; @@ -1024,6 +1032,7 @@ static int pci_uclass_pre_probe(struct udevice *bus) parent_hose = dev_get_uclass_priv(bus->parent); hose->ctlr = parent_hose->bus; } + hose->bus = bus; hose->first_busno = dev_seq(bus); hose->last_busno = dev_seq(bus); @@ -1044,14 +1053,14 @@ static int pci_uclass_post_probe(struct udevice *bus) debug("%s: probing bus %d\n", __func__, dev_seq(bus)); ret = pci_bind_bus_devices(bus); if (ret) - return ret; + return log_msg_ret("bind", ret); if (CONFIG_IS_ENABLED(PCI_PNP) && ll_boot_init() && (!hose->skip_auto_config_until_reloc || (gd->flags & GD_FLG_RELOC))) { ret = pci_auto_config_devices(bus); if (ret < 0) - return log_msg_ret("pci auto-config", ret); + return log_msg_ret("cfg", ret); } #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) @@ -1071,7 +1080,7 @@ static int pci_uclass_post_probe(struct udevice *bus) if ((gd->flags & GD_FLG_RELOC) && dev_seq(bus) == 0 && ll_boot_init()) { ret = fsp_init_phase_pci(); if (ret) - return ret; + return log_msg_ret("fsp", ret); } #endif @@ -1791,7 +1800,7 @@ int pci_sriov_get_totalvfs(struct udevice *pdev) UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", - .flags = DM_UC_FLAG_SEQ_ALIAS, + .flags = DM_UC_FLAG_SEQ_ALIAS | DM_UC_FLAG_NO_AUTO_SEQ, .post_bind = dm_scan_fdt_dev, .pre_probe = pci_uclass_pre_probe, .post_probe = pci_uclass_post_probe, diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 4d797ec034..68ef4e8092 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -321,7 +321,7 @@ int dm_pciauto_config_device(struct udevice *dev) bool enum_only = false; struct udevice *ctlr = pci_get_controller(dev); struct pci_controller *ctlr_hose = dev_get_uclass_priv(ctlr); - int n; + int ret; #ifdef CONFIG_PCI_ENUM_ONLY enum_only = true; @@ -341,10 +341,10 @@ int dm_pciauto_config_device(struct udevice *dev) dm_pciauto_setup_device(dev, 2, pci_mem, pci_prefetch, pci_io, enum_only); - n = dm_pci_hose_probe_bus(dev); - if (n < 0) - return n; - sub_bus = (unsigned int)n; + ret = dm_pci_hose_probe_bus(dev); + if (ret < 0) + return log_msg_ret("probe", ret); + sub_bus = ret; break; case PCI_CLASS_BRIDGE_CARDBUS: -- 2.39.5