The branch main has been updated by andrew:

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

commit e887179d4bc032e79d0334371d613c5841989a41
Author:     Cristian Marussi <cristian.maru...@arm.com>
AuthorDate: 2025-01-23 13:23:28 +0000
Commit:     Andrew Turner <and...@freebsd.org>
CommitDate: 2025-01-23 17:26:26 +0000

    scmi: Add helper to manipulate scmi_msg descriptors
    
    Refactor allocation logic for scmi_req and introduce new helpers to be able
    to obtain an scmi_msg reference to a freshly allocated request.
    
    Tested on:      Arm Morello Board
    Reviewed by:    andrew
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D47423
    Signed-off-by: Cristian Marussi <cristian.maru...@arm.com>
---
 sys/dev/firmware/arm/scmi.c | 77 +++++++++++++++++++++++++++++++++++----------
 sys/dev/firmware/arm/scmi.h |  2 ++
 2 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
index cf5a678370fd..8104f4e10429 100644
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -132,9 +132,10 @@ static int         scmi_transport_init(struct scmi_softc 
*, phandle_t);
 static void            scmi_transport_cleanup(struct scmi_softc *);
 static struct scmi_reqs_pool *scmi_reqs_pool_allocate(const int, const int);
 static void            scmi_reqs_pool_free(struct scmi_reqs_pool *);
-static struct scmi_req *scmi_req_alloc(struct scmi_softc *, enum scmi_chan);
+static struct scmi_req *scmi_req_alloc(struct scmi_softc *, enum scmi_chan);
+static struct scmi_req *scmi_req_initialized_alloc(device_t, int, int);
 static void            scmi_req_free_unlocked(struct scmi_softc *,
-    enum scmi_chan, struct scmi_req *);
+                           enum scmi_chan, struct scmi_req *);
 static void            scmi_req_get(struct scmi_softc *, struct scmi_req *);
 static void            scmi_req_put(struct scmi_softc *, struct scmi_req *);
 static int             scmi_token_pick(struct scmi_softc *);
@@ -319,6 +320,32 @@ scmi_transport_cleanup(struct scmi_softc *sc)
        free(sc->trs, M_DEVBUF);
 }
 
+static struct scmi_req *
+scmi_req_initialized_alloc(device_t dev, int tx_payld_sz, int rx_payld_sz)
+{
+       struct scmi_softc *sc;
+       struct scmi_req *req;
+
+       sc = device_get_softc(dev);
+
+       if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE(sc) ||
+           rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE(sc)) {
+               device_printf(dev, "Unsupported payload size. Drop.\n");
+               return (NULL);
+       }
+
+       /* Pick one from free list */
+       req = scmi_req_alloc(sc, SCMI_CHAN_A2P);
+       if (req == NULL)
+               return (NULL);
+
+       req->msg.tx_len = sizeof(req->msg.hdr) + tx_payld_sz;
+       req->msg.rx_len = rx_payld_sz ?
+           rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE(sc);
+
+       return (req);
+}
+
 static struct scmi_req *
 scmi_req_alloc(struct scmi_softc *sc, enum scmi_chan ch_idx)
 {
@@ -374,6 +401,10 @@ scmi_req_put(struct scmi_softc *sc, struct scmi_req *req)
 {
        mtx_lock_spin(&req->mtx);
        if (!refcount_release_if_not_last(&req->cnt)) {
+               req->protocol_id = 0;
+               req->message_id = 0;
+               req->token = 0;
+               req->header = 0;
                bzero(&req->msg, sizeof(req->msg) + 
SCMI_MAX_MSG_PAYLD_SIZE(sc));
                scmi_req_free_unlocked(sc, SCMI_CHAN_A2P, req);
        }
@@ -604,27 +635,15 @@ void *
 scmi_buf_get(device_t dev, uint8_t protocol_id, uint8_t message_id,
     int tx_payld_sz, int rx_payld_sz)
 {
-       struct scmi_softc *sc;
        struct scmi_req *req;
 
-       sc = device_get_softc(dev);
-
-       if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE(sc) ||
-           rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE(sc)) {
-               device_printf(dev, "Unsupported payload size. Drop.\n");
-               return (NULL);
-       }
-
-       /* Pick one from free list */
-       req = scmi_req_alloc(sc, SCMI_CHAN_A2P);
+       /* Pick a pre-built req */
+       req = scmi_req_initialized_alloc(dev, tx_payld_sz, rx_payld_sz);
        if (req == NULL)
                return (NULL);
 
        req->protocol_id = protocol_id & SCMI_HDR_PROTOCOL_ID_BF;
        req->message_id = message_id & SCMI_HDR_MESSAGE_ID_BF;
-       req->msg.tx_len = sizeof(req->msg.hdr) + tx_payld_sz;
-       req->msg.rx_len = rx_payld_sz ?
-           rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE(sc);
 
        return (&req->msg.payld[0]);
 }
@@ -641,6 +660,32 @@ scmi_buf_put(device_t dev, void *buf)
        scmi_req_put(sc, req);
 }
 
+struct scmi_msg *
+scmi_msg_get(device_t dev, int tx_payld_sz, int rx_payld_sz)
+{
+       struct scmi_req *req;
+
+       /* Pick a pre-built req */
+       req = scmi_req_initialized_alloc(dev, tx_payld_sz, rx_payld_sz);
+       if (req == NULL)
+               return (NULL);
+
+       return (&req->msg);
+}
+
+void
+scmi_msg_put(device_t dev, struct scmi_msg *msg)
+{
+       struct scmi_softc *sc;
+       struct scmi_req *req;
+
+       sc = device_get_softc(dev);
+
+       req = msg_to_req(msg);
+
+       scmi_req_put(sc, req);
+}
+
 int
 scmi_request(device_t dev, void *in, void **out)
 {
diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h
index 135b49c3b05b..f6aa072caeca 100644
--- a/sys/dev/firmware/arm/scmi.h
+++ b/sys/dev/firmware/arm/scmi.h
@@ -80,6 +80,8 @@ struct scmi_msg {
 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);
+struct scmi_msg *scmi_msg_get(device_t dev, int tx_payld_sz, int rx_payld_sz);
+void scmi_msg_put(device_t dev, struct scmi_msg *msg);
 int scmi_request(device_t dev, void *in, void **);
 void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t 
rx_len);
 

Reply via email to