[PULL 01/10] hw/sd/sdhci: Do not force sdhci_mmio_*_ops onto all SD controllers

Philippe Mathieu-Daudé posted 10 patches 2 years, 6 months ago
Maintainers: "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Bin Meng <bin.meng@windriver.com>, Aurelien Jarno <aurelien@aurel32.net>, Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
[PULL 01/10] hw/sd/sdhci: Do not force sdhci_mmio_*_ops onto all SD controllers
Posted by Philippe Mathieu-Daudé 2 years, 6 months ago
From: Bernhard Beschow <shentey@gmail.com>

Since commit c0a55a0c9da2 "hw/sd/sdhci: Support big endian SD host controller
interfaces" sdhci_common_realize() forces all SD card controllers to use either
sdhci_mmio_le_ops or sdhci_mmio_be_ops, depending on the "endianness" property.
However, there are device models which use different MMIO ops: TYPE_IMX_USDHC
uses usdhc_mmio_ops and TYPE_S3C_SDHCI uses sdhci_s3c_mmio_ops.

Forcing sdhci_mmio_le_ops breaks SD card handling on the "sabrelite" board, for
example. Fix this by defaulting the io_ops to little endian and switch to big
endian in sdhci_common_realize() only if there is a matchig big endian variant
available.

Fixes: c0a55a0c9da2 ("hw/sd/sdhci: Support big endian SD host controller
interfaces")

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-Id: <20230709080950.92489-1-shentey@gmail.com>
---
 hw/sd/sdhci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 6811f0f1a8..362c2c86aa 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1382,6 +1382,8 @@ void sdhci_initfn(SDHCIState *s)
 
     s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
     s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
+
+    s->io_ops = &sdhci_mmio_le_ops;
 }
 
 void sdhci_uninitfn(SDHCIState *s)
@@ -1399,9 +1401,13 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
 
     switch (s->endianness) {
     case DEVICE_LITTLE_ENDIAN:
-        s->io_ops = &sdhci_mmio_le_ops;
+        /* s->io_ops is little endian by default */
         break;
     case DEVICE_BIG_ENDIAN:
+        if (s->io_ops != &sdhci_mmio_le_ops) {
+            error_setg(errp, "SD controller doesn't support big endianness");
+            return;
+        }
         s->io_ops = &sdhci_mmio_be_ops;
         break;
     default:
-- 
2.38.1
Re: [PULL 01/10] hw/sd/sdhci: Do not force sdhci_mmio_*_ops onto all SD controllers
Posted by Bernhard Beschow 2 years, 5 months ago

Am 25. Juli 2023 14:58:20 UTC schrieb "Philippe Mathieu-Daudé" <philmd@linaro.org>:
>From: Bernhard Beschow <shentey@gmail.com>
>
>Since commit c0a55a0c9da2 "hw/sd/sdhci: Support big endian SD host controller
>interfaces" sdhci_common_realize() forces all SD card controllers to use either
>sdhci_mmio_le_ops or sdhci_mmio_be_ops, depending on the "endianness" property.
>However, there are device models which use different MMIO ops: TYPE_IMX_USDHC
>uses usdhc_mmio_ops and TYPE_S3C_SDHCI uses sdhci_s3c_mmio_ops.
>
>Forcing sdhci_mmio_le_ops breaks SD card handling on the "sabrelite" board, for
>example. Fix this by defaulting the io_ops to little endian and switch to big
>endian in sdhci_common_realize() only if there is a matchig big endian variant
>available.
>
>Fixes: c0a55a0c9da2 ("hw/sd/sdhci: Support big endian SD host controller
>interfaces")
>
>Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>Tested-by: Guenter Roeck <linux@roeck-us.net>
>Message-Id: <20230709080950.92489-1-shentey@gmail.com>

Ping qemu-stable

AFAIU the regression happens since 8.0, thus would be great to have a fix there.

Best regards,
Bernhard

>---
> hw/sd/sdhci.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
>diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
>index 6811f0f1a8..362c2c86aa 100644
>--- a/hw/sd/sdhci.c
>+++ b/hw/sd/sdhci.c
>@@ -1382,6 +1382,8 @@ void sdhci_initfn(SDHCIState *s)
> 
>     s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
>     s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
>+
>+    s->io_ops = &sdhci_mmio_le_ops;
> }
> 
> void sdhci_uninitfn(SDHCIState *s)
>@@ -1399,9 +1401,13 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
> 
>     switch (s->endianness) {
>     case DEVICE_LITTLE_ENDIAN:
>-        s->io_ops = &sdhci_mmio_le_ops;
>+        /* s->io_ops is little endian by default */
>         break;
>     case DEVICE_BIG_ENDIAN:
>+        if (s->io_ops != &sdhci_mmio_le_ops) {
>+            error_setg(errp, "SD controller doesn't support big endianness");
>+            return;
>+        }
>         s->io_ops = &sdhci_mmio_be_ops;
>         break;
>     default: