The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9342829d578e26f10a5cbc26e2b9e66cfd9864c4

commit 9342829d578e26f10a5cbc26e2b9e66cfd9864c4
Author:     Cristian Marussi <cristian.maru...@arm.com>
AuthorDate: 2025-01-23 12:49:02 +0000
Commit:     Andrew Turner <and...@freebsd.org>
CommitDate: 2025-01-23 17:26:26 +0000

    scmi: Make transports report the effective length of the received messages
    
    Once a message is received that fits into the RX buffer, update the
    msg.rx_len field with the effective length of the message received.
    
    Tested on:      Arm Morello Board
    Reviewed by:    andrew
    Sponsored by:   Arm Ltd
    Pull Request:   https://reviews.freebsd.org/D47420
    Signed-off-by: Cristian Marussi <cristian.maru...@arm.com>
---
 sys/dev/firmware/arm/scmi.c         | 10 ++++++----
 sys/dev/firmware/arm/scmi.h         |  2 +-
 sys/dev/firmware/arm/scmi_mailbox.c | 10 +++++-----
 sys/dev/firmware/arm/scmi_shmem.c   | 22 +++++++++-------------
 sys/dev/firmware/arm/scmi_shmem.h   |  6 +++---
 sys/dev/firmware/arm/scmi_smc.c     |  4 ++--
 sys/dev/firmware/arm/scmi_virtio.c  |  5 ++---
 7 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
index 37496136c828..00a229762414 100644
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -146,7 +146,8 @@ static struct scmi_req *scmi_req_lookup_inflight(struct 
scmi_softc *, uint32_t);
 
 static int             scmi_wait_for_response(struct scmi_softc *,
                            struct scmi_req *, void **);
-static void            scmi_process_response(struct scmi_softc *, uint32_t);
+static void            scmi_process_response(struct scmi_softc *, uint32_t,
+                           unsigned int);
 
 int
 scmi_attach(device_t dev)
@@ -469,7 +470,7 @@ scmi_req_lookup_inflight(struct scmi_softc *sc, uint32_t 
hdr)
 }
 
 static void
-scmi_process_response(struct scmi_softc *sc, uint32_t hdr)
+scmi_process_response(struct scmi_softc *sc, uint32_t hdr, uint32_t rx_len)
 {
        bool timed_out = false;
        struct scmi_req *req;
@@ -484,6 +485,7 @@ scmi_process_response(struct scmi_softc *sc, uint32_t hdr)
 
        mtx_lock_spin(&req->mtx);
        req->done = true;
+       req->msg.rx_len = rx_len;
        if (!req->timed_out) {
                /*
                 * Consider the case in which a polled message is picked
@@ -512,7 +514,7 @@ scmi_process_response(struct scmi_softc *sc, uint32_t hdr)
 }
 
 void
-scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr)
+scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t rx_len)
 {
        struct scmi_softc *sc;
 
@@ -524,7 +526,7 @@ scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr)
                return;
        }
 
-       scmi_process_response(sc, hdr);
+       scmi_process_response(sc, hdr, rx_len);
 }
 
 static int
diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h
index 345ae6eeb03a..5ad7b0db3f5f 100644
--- a/sys/dev/firmware/arm/scmi.h
+++ b/sys/dev/firmware/arm/scmi.h
@@ -75,7 +75,7 @@ void *scmi_buf_get(device_t dev, uint8_t protocol_id, uint8_t 
message_id,
                   int tx_payd_sz, int rx_payld_sz);
 void scmi_buf_put(device_t dev, void *buf);
 int scmi_request(device_t dev, void *in, void **);
-void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr);
+void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t 
rx_len);
 
 DECLARE_CLASS(scmi_driver);
 
diff --git a/sys/dev/firmware/arm/scmi_mailbox.c 
b/sys/dev/firmware/arm/scmi_mailbox.c
index 858b81f68845..d7b642b69b85 100644
--- a/sys/dev/firmware/arm/scmi_mailbox.c
+++ b/sys/dev/firmware/arm/scmi_mailbox.c
@@ -70,14 +70,14 @@ static void
 scmi_mailbox_a2p_callback(void *arg)
 {
        struct scmi_mailbox_softc *sc;
-       uint32_t msg_header;
+       uint32_t msg_header, rx_len;
        int ret;
 
        sc = arg;
 
-       ret = scmi_shmem_read_msg_header(sc->a2p_dev, &msg_header);
+       ret = scmi_shmem_read_msg_header(sc->a2p_dev, &msg_header, &rx_len);
        if (ret == 0)
-               scmi_rx_irq_callback(sc->base.dev, sc->a2p_dev, msg_header);
+               scmi_rx_irq_callback(sc->base.dev, sc->a2p_dev, msg_header, 
rx_len);
 }
 
 static int
@@ -154,7 +154,7 @@ scmi_mailbox_poll_msg(device_t dev, struct scmi_msg *msg, 
unsigned int tmo_ms)
        sc = device_get_softc(dev);
 
        do {
-               if (scmi_shmem_poll_msg(sc->a2p_dev, &msg->hdr))
+               if (scmi_shmem_poll_msg(sc->a2p_dev, &msg->hdr, &msg->rx_len))
                        break;
                DELAY(SCMI_MBOX_POLL_INTERVAL_MS * 1000);
        } while (tmo_loops--);
@@ -171,7 +171,7 @@ scmi_mailbox_collect_reply(device_t dev, struct scmi_msg 
*msg)
        sc = device_get_softc(dev);
 
        ret = scmi_shmem_read_msg_payload(sc->a2p_dev,
-           msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE);
+           msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE, msg->rx_len);
 
        return (ret);
 }
diff --git a/sys/dev/firmware/arm/scmi_shmem.c 
b/sys/dev/firmware/arm/scmi_shmem.c
index 9bab4bc4004e..a63d96b64cb5 100644
--- a/sys/dev/firmware/arm/scmi_shmem.c
+++ b/sys/dev/firmware/arm/scmi_shmem.c
@@ -247,7 +247,7 @@ scmi_shmem_clear_channel(device_t dev)
 }
 
 int
-scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header)
+scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header, unsigned int 
*rx_len)
 {
        uint32_t length, header;
 
@@ -256,6 +256,7 @@ scmi_shmem_read_msg_header(device_t dev, uint32_t 
*msg_header)
        if (le32toh(length) < sizeof(header))
                return (EINVAL);
 
+       *rx_len = le32toh(length);
        /* Read header. */
        scmi_shmem_read(dev, SMT_OFFSET_MSG_HEADER, &header,
            SMT_SIZE_MSG_HEADER);
@@ -266,14 +267,11 @@ scmi_shmem_read_msg_header(device_t dev, uint32_t 
*msg_header)
 }
 
 int
-scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len)
+scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len, 
uint32_t rx_len)
 {
-       uint32_t length, payld_len;
-
-       /* Read length. */
-       scmi_shmem_read(dev, SMT_OFFSET_LENGTH, &length, SMT_SIZE_LENGTH);
-       payld_len = le32toh(length) - SCMI_MSG_HDR_SIZE;
+       uint32_t payld_len;
 
+       payld_len = rx_len - SCMI_MSG_HDR_SIZE;
        if (payld_len > buf_len) {
                device_printf(dev,
                    "RX payload %dbytes exceeds buflen %dbytes. Truncate.\n",
@@ -296,7 +294,7 @@ scmi_shmem_tx_complete(device_t dev)
        scmi_shmem_release_channel(sc);
 }
 
-bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header)
+bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header, uint32_t *rx_len)
 {
        uint32_t status;
        bool ret;
@@ -306,12 +304,10 @@ bool scmi_shmem_poll_msg(device_t dev, uint32_t 
*msg_header)
 
        ret = (status & (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |
            SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE));
+       if (ret == 0)
+               return (ret);
 
-       if (ret)
-               scmi_shmem_read(dev, SMT_OFFSET_MSG_HEADER, msg_header,
-                   SMT_SIZE_MSG_HEADER);
-
-       return (ret);
+       return (scmi_shmem_read_msg_header(dev, msg_header, rx_len));
 }
 
 static device_method_t shmem_methods[] = {
diff --git a/sys/dev/firmware/arm/scmi_shmem.h 
b/sys/dev/firmware/arm/scmi_shmem.h
index ed8763d5c145..bc8284502129 100644
--- a/sys/dev/firmware/arm/scmi_shmem.h
+++ b/sys/dev/firmware/arm/scmi_shmem.h
@@ -63,9 +63,9 @@ struct scmi_smt_header {
 device_t scmi_shmem_get(device_t sdev, phandle_t node, int index);
 int scmi_shmem_prepare_msg(device_t dev, uint8_t *msg, uint32_t tx_len,
     bool polling);
-bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header);
-int scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header);
-int scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len);
+bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header, uint32_t *rx_len);
+int scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header, uint32_t 
*rx_len);
+int scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len, 
uint32_t rx_len);
 void scmi_shmem_tx_complete(device_t);
 void scmi_shmem_clear_channel(device_t);
 
diff --git a/sys/dev/firmware/arm/scmi_smc.c b/sys/dev/firmware/arm/scmi_smc.c
index 9f0d899233fa..81c66ad7bb46 100644
--- a/sys/dev/firmware/arm/scmi_smc.c
+++ b/sys/dev/firmware/arm/scmi_smc.c
@@ -122,7 +122,7 @@ scmi_smc_poll_msg(device_t dev, struct scmi_msg *msg, 
unsigned int tmo)
         * Nothing to poll since commands are completed as soon as smc
         * returns ... but did we get back what we were poling for ?
         */
-       scmi_shmem_read_msg_header(sc->a2p_dev, &msg->hdr);
+       scmi_shmem_read_msg_header(sc->a2p_dev, &msg->hdr, &msg->rx_len);
 
        return (0);
 }
@@ -136,7 +136,7 @@ scmi_smc_collect_reply(device_t dev, struct scmi_msg *msg)
        sc = device_get_softc(dev);
 
        ret = scmi_shmem_read_msg_payload(sc->a2p_dev,
-           msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE);
+           msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE, msg->rx_len);
 
        return (ret);
 }
diff --git a/sys/dev/firmware/arm/scmi_virtio.c 
b/sys/dev/firmware/arm/scmi_virtio.c
index 12cbb9ecefd5..8714fee2ec87 100644
--- a/sys/dev/firmware/arm/scmi_virtio.c
+++ b/sys/dev/firmware/arm/scmi_virtio.c
@@ -76,7 +76,7 @@ scmi_virtio_callback(void *msg, unsigned int len, void *priv)
        }
 
        hdr = le32toh(*((uint32_t *)msg));
-       scmi_rx_irq_callback(sc->base.dev, msg, hdr);
+       scmi_rx_irq_callback(sc->base.dev, msg, hdr, len);
 }
 
 static void *
@@ -225,7 +225,6 @@ scmi_virtio_poll_msg(device_t dev, struct scmi_msg *msg, 
unsigned int tmo_ms)
                }
 
                rx_msg = hdr_to_msg(rx_buf);
-               rx_msg->rx_len = rx_len;
                /* Complete the polling on any poll path */
                if (rx_msg->polling)
                        atomic_store_rel_int(&rx_msg->poll_done, 1);
@@ -242,7 +241,7 @@ scmi_virtio_poll_msg(device_t dev, struct scmi_msg *msg, 
unsigned int tmo_ms)
                    rx_msg->hdr, rx_msg->polling);
 
                if (!rx_msg->polling)
-                       scmi_rx_irq_callback(sc->base.dev, rx_msg, rx_msg->hdr);
+                       scmi_rx_irq_callback(sc->base.dev, rx_msg, rx_msg->hdr, 
rx_len);
        }
 
        return (tmo_loops > 0 ? 0 : ETIMEDOUT);

Reply via email to