soc_get_family/revision/machine() return 0 on success, negative on
error. print_cpuinfo() checked "if (ret)", so a failed call (e.g.
-ENOSYS) was treated as success and printed name[] unpopulated or
stale. Fix the checks to "if (!ret)".

This alone would drop CPU:/Silicon:/Chip: output on Xilinx/AMD
boards: soc_xilinx_versal.c, soc_xilinx_versal_net.c,
soc_xilinx_zynqmp.c and soc_amd_versal2.c return snprintf()'s byte
count instead of 0, which the old inverted check happened to mask.
Fix all four to return 0 on success / -ENOSPC on truncation, per the
documented soc_ops contract.

The wrong return values also affected soc_device_match(), which expects
0 from these ops. With a nonzero byte count returned its strcmp()
comparisons were skipped, so any Versal revision matched the
{ .family = "Versal", .revision = "v2" } entry in cadence_ospi_versal.c
and took the CQSPI_DLL_MODE_MASTER path. After this fix family and
revision are actually compared; production "v2" silicon is unaffected,
while ES1/v1 parts now correctly fall through to -ENOTSUPP.

Fixes: 86ceedd84e2 ("xilinx: common: Separate display cpu info function")
Signed-off-by: Pranav Sanwal <[email protected]>
Message-ID: <[email protected]>
---
 board/xilinx/common/cpu-info.c      |  6 +++---
 drivers/soc/soc_amd_versal2.c       | 18 ++++++++++++++----
 drivers/soc/soc_xilinx_versal.c     | 14 ++++++++++++--
 drivers/soc/soc_xilinx_versal_net.c | 14 ++++++++++++--
 drivers/soc/soc_xilinx_zynqmp.c     | 21 ++++++++++++++++++---
 5 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/board/xilinx/common/cpu-info.c b/board/xilinx/common/cpu-info.c
index 765bb24d937..6fc3d612b46 100644
--- a/board/xilinx/common/cpu-info.c
+++ b/board/xilinx/common/cpu-info.c
@@ -20,15 +20,15 @@ int print_cpuinfo(void)
        }
 
        ret = soc_get_family(soc, name, SOC_MAX_STR_SIZE);
-       if (ret)
+       if (!ret)
                printf("CPU:   %s\n", name);
 
        ret = soc_get_revision(soc, name, SOC_MAX_STR_SIZE);
-       if (ret)
+       if (!ret)
                printf("Silicon: %s\n", name);
 
        ret = soc_get_machine(soc, name, SOC_MAX_STR_SIZE);
-       if (ret)
+       if (!ret)
                printf("Chip:  %s\n", name);
 
        return 0;
diff --git a/drivers/soc/soc_amd_versal2.c b/drivers/soc/soc_amd_versal2.c
index 530b3249431..ac505d0f961 100644
--- a/drivers/soc/soc_amd_versal2.c
+++ b/drivers/soc/soc_amd_versal2.c
@@ -26,17 +26,27 @@ struct soc_amd_versal2_priv {
 static int soc_amd_versal2_get_family(struct udevice *dev, char *buf, int size)
 {
        struct soc_amd_versal2_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "%s", priv->family);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "%s", priv->family);
+       return 0;
 }
 
 static int soc_amd_versal2_get_revision(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_amd_versal2_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "v%d.%d",
+                      (u32)FIELD_GET(PS_VERSION_MAJOR, priv->revision),
+                      (u32)FIELD_GET(PS_VERSION_MINOR, priv->revision));
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "v%d.%d",
-                       (u32)FIELD_GET(PS_VERSION_MAJOR, priv->revision),
-                       (u32)FIELD_GET(PS_VERSION_MINOR, priv->revision));
+       return 0;
 }
 
 static const struct soc_ops soc_amd_versal2_ops = {
diff --git a/drivers/soc/soc_xilinx_versal.c b/drivers/soc/soc_xilinx_versal.c
index ff6eb873d8a..8dc93a66acc 100644
--- a/drivers/soc/soc_xilinx_versal.c
+++ b/drivers/soc/soc_xilinx_versal.c
@@ -24,15 +24,25 @@ struct soc_xilinx_versal_priv {
 static int soc_xilinx_versal_get_family(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "%s", priv->family);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "%s", priv->family);
+       return 0;
 }
 
 static int soc_xilinx_versal_get_revision(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "v%d", priv->revision);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "v%d", priv->revision);
+       return 0;
 }
 
 static const struct soc_ops soc_xilinx_versal_ops = {
diff --git a/drivers/soc/soc_xilinx_versal_net.c 
b/drivers/soc/soc_xilinx_versal_net.c
index 7afb110d8ce..9b3d1b8a131 100644
--- a/drivers/soc/soc_xilinx_versal_net.c
+++ b/drivers/soc/soc_xilinx_versal_net.c
@@ -26,15 +26,25 @@ struct soc_xilinx_versal_net_priv {
 static int soc_xilinx_versal_net_get_family(struct udevice *dev, char *buf, 
int size)
 {
        struct soc_xilinx_versal_net_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "%s", priv->family);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "%s", priv->family);
+       return 0;
 }
 
 static int soc_xilinx_versal_net_get_revision(struct udevice *dev, char *buf, 
int size)
 {
        struct soc_xilinx_versal_net_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "v%d", priv->revision);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "v%d", priv->revision);
+       return 0;
 }
 
 static const struct soc_ops soc_xilinx_versal_net_ops = {
diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
index 1dc0b05a1a3..cf6896aef4a 100644
--- a/drivers/soc/soc_xilinx_zynqmp.c
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -368,26 +368,41 @@ static int soc_xilinx_zynqmp_detect_machine(struct 
udevice *dev, u32 idcode,
 static int soc_xilinx_zynqmp_get_family(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = snprintf(buf, size, "%s", priv->family);
+       if (ret >= size)
+               return -ENOSPC;
 
-       return snprintf(buf, size, "%s", priv->family);
+       return 0;
 }
 
 static int soc_xilinx_zynqmp_get_machine(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
        const char *machine = priv->machine;
+       int ret;
 
        if (!machine[0])
                machine = "unknown";
 
-       return snprintf(buf, size, "%s", machine);
+       ret = snprintf(buf, size, "%s", machine);
+       if (ret >= size)
+               return -ENOSPC;
+
+       return 0;
 }
 
 static int soc_xilinx_zynqmp_get_revision(struct udevice *dev, char *buf, int 
size)
 {
        struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+       int ret;
 
-       return snprintf(buf, size, "v%d", priv->revision);
+       ret = snprintf(buf, size, "v%d", priv->revision);
+       if (ret >= size)
+               return -ENOSPC;
+
+       return 0;
 }
 
 static const struct soc_ops soc_xilinx_zynqmp_ops = {
-- 
2.43.7

Reply via email to