Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144789768
D43043.1776498063.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D43043.1776498063.diff
View Options
diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -91,18 +91,25 @@
ret = SCMI_XFER_MSG(sc->dev);
if (ret != 0)
- return (ret);
+ goto out;
/* Read header. */
ret = scmi_shmem_read_msg_header(sc->a2p_dev, &reply_header);
if (ret != 0)
- return (ret);
+ goto out;
+
+ if (reply_header != req->msg_header) {
+ ret = EPROTO;
+ goto out;
+ }
+
+ ret = scmi_shmem_read_msg_payload(sc->a2p_dev, req->out_buf,
+ req->out_size);
- if (reply_header != req->msg_header)
- return (EPROTO);
+out:
+ scmi_shmem_tx_complete(sc->a2p_dev);
- return (scmi_shmem_read_msg_payload(sc->a2p_dev, req->out_buf,
- req->out_size));
+ return (ret);
}
int
diff --git a/sys/dev/firmware/arm/scmi_shmem.h b/sys/dev/firmware/arm/scmi_shmem.h
--- a/sys/dev/firmware/arm/scmi_shmem.h
+++ b/sys/dev/firmware/arm/scmi_shmem.h
@@ -68,5 +68,6 @@
bool scmi_shmem_poll_msg(device_t);
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);
+void scmi_shmem_tx_complete(device_t);
#endif /* !_ARM64_SCMI_SCMI_SHMEM_H_ */
diff --git a/sys/dev/firmware/arm/scmi_shmem.c b/sys/dev/firmware/arm/scmi_shmem.c
--- a/sys/dev/firmware/arm/scmi_shmem.c
+++ b/sys/dev/firmware/arm/scmi_shmem.c
@@ -36,6 +36,8 @@
#include <sys/kernel.h>
#include <sys/module.h>
+#include <machine/atomic.h>
+
#include <dev/fdt/simplebus.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -45,15 +47,21 @@
#include "scmi_shmem.h"
#include "scmi.h"
+#define INFLIGHT_NONE 0
+#define INFLIGHT_REQ 1
+
struct shmem_softc {
device_t dev;
device_t parent;
int reg;
+ int inflight;
};
static void scmi_shmem_read(device_t, bus_size_t, void *, bus_size_t);
static void scmi_shmem_write(device_t, bus_size_t, const void *,
bus_size_t);
+static void scmi_shmem_acquire_channel(struct shmem_softc *);
+static void scmi_shmem_release_channel(struct shmem_softc *);
static int shmem_probe(device_t);
static int shmem_attach(device_t);
@@ -94,6 +102,7 @@
dprintf("%s: reg %x\n", __func__, reg);
sc->reg = reg;
+ atomic_store_rel_int(&sc->inflight, INFLIGHT_NONE);
OF_device_register_xref(OF_xref_from_node(node), dev);
@@ -167,16 +176,39 @@
return (shmem_dev);
}
+static void
+scmi_shmem_acquire_channel(struct shmem_softc *sc)
+{
+
+ while ((atomic_cmpset_acq_int(&sc->inflight, INFLIGHT_NONE,
+ INFLIGHT_REQ)) == 0)
+ DELAY(1000);
+}
+
+static void
+scmi_shmem_release_channel(struct shmem_softc *sc)
+{
+
+ atomic_store_rel_int(&sc->inflight, INFLIGHT_NONE);
+}
+
int
scmi_shmem_prepare_msg(device_t dev, struct scmi_req *req, bool polling)
{
+ struct shmem_softc *sc;
struct scmi_smt_header hdr = {};
uint32_t channel_status;
+ sc = device_get_softc(dev);
+
+ /* Get exclusive write access to channel */
+ scmi_shmem_acquire_channel(sc);
+
/* Read channel status */
scmi_shmem_read(dev, SMT_OFFSET_CHAN_STATUS, &channel_status,
SMT_SIZE_CHAN_STATUS);
if ((channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) == 0) {
+ scmi_shmem_release_channel(sc);
device_printf(dev, "Shmem channel busy. Abort !.\n");
return (1);
}
@@ -242,6 +274,15 @@
return (0);
}
+void
+scmi_shmem_tx_complete(device_t dev)
+{
+ struct shmem_softc *sc;
+
+ sc = device_get_softc(dev);
+ scmi_shmem_release_channel(sc);
+}
+
bool scmi_shmem_poll_msg(device_t dev)
{
uint32_t status;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 18, 7:41 AM (1 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28374403
Default Alt Text
D43043.1776498063.diff (3 KB)
Attached To
Mode
D43043: scmi: Protect SCMI/SMT channels from concurrent transmissions
Attached
Detach File
Event Timeline
Log In to Comment