brintos

brintos / linux-shallow public Read only

0
0
Text · 41.0 KiB · 9e89a6a Raw
1451 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * System Control and Management Interface (SCMI) Raw mode support4 *5 * Copyright (C) 2022 ARM Ltd.6 */7/**8 * DOC: Theory of operation9 *10 * When enabled the SCMI Raw mode support exposes a userspace API which allows11 * to send and receive SCMI commands, replies and notifications from a user12 * application through injection and snooping of bare SCMI messages in binary13 * little-endian format.14 *15 * Such injected SCMI transactions will then be routed through the SCMI core16 * stack towards the SCMI backend server using whatever SCMI transport is17 * currently configured on the system under test.18 *19 * It is meant to help in running any sort of SCMI backend server testing, no20 * matter where the server is placed, as long as it is normally reachable via21 * the transport configured on the system.22 *23 * It is activated by a Kernel configuration option since it is NOT meant to24 * be used in production but only during development and in CI deployments.25 *26 * In order to avoid possible interferences between the SCMI Raw transactions27 * originated from a test-suite and the normal operations of the SCMI drivers,28 * when Raw mode is enabled, by default, all the regular SCMI drivers are29 * inhibited, unless CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX is enabled: in this30 * latter case the regular SCMI stack drivers will be loaded as usual and it is31 * up to the user of this interface to take care of manually inhibiting the32 * regular SCMI drivers in order to avoid interferences during the test runs.33 *34 * The exposed API is as follows.35 *36 * All SCMI Raw entries are rooted under a common top /raw debugfs top directory37 * which in turn is rooted under the corresponding underlying  SCMI instance.38 *39 * /sys/kernel/debug/scmi/40 * `-- 041 *     |-- atomic_threshold_us42 *     |-- instance_name43 *     |-- raw44 *     |   |-- channels45 *     |   |   |-- 0x1046 *     |   |   |   |-- message47 *     |   |   |   `-- message_async48 *     |   |   `-- 0x1349 *     |   |       |-- message50 *     |   |       `-- message_async51 *     |   |-- errors52 *     |   |-- message53 *     |   |-- message_async54 *     |   |-- notification55 *     |   `-- reset56 *     `-- transport57 *         |-- is_atomic58 *         |-- max_msg_size59 *         |-- max_rx_timeout_ms60 *         |-- rx_max_msg61 *         |-- tx_max_msg62 *         `-- type63 *64 * where:65 *66 *  - errors: used to read back timed-out and unexpected replies67 *  - message*: used to send sync/async commands and read back immediate and68 *		delayed reponses (if any)69 *  - notification: used to read any notification being emitted by the system70 *		    (if previously enabled by the user app)71 *  - reset: used to flush the queues of messages (of any kind) still pending72 *	     to be read; this is useful at test-suite start/stop to get73 *	     rid of any unread messages from the previous run.74 *75 * with the per-channel entries rooted at /channels being present only on a76 * system where multiple transport channels have been configured.77 *78 * Such per-channel entries can be used to explicitly choose a specific channel79 * for SCMI bare message injection, in contrast with the general entries above80 * where, instead, the selection of the proper channel to use is automatically81 * performed based the protocol embedded in the injected message and on how the82 * transport is configured on the system.83 *84 * Note that other common general entries are available under transport/ to let85 * the user applications properly make up their expectations in terms of86 * timeouts and message characteristics.87 *88 * Each write to the message* entries causes one command request to be built89 * and sent while the replies or delayed response are read back from those same90 * entries one message at time (receiving an EOF at each message boundary).91 *92 * The user application running the test is in charge of handling timeouts93 * on replies and properly choosing SCMI sequence numbers for the outgoing94 * requests (using the same sequence number is supported but discouraged).95 *96 * Injection of multiple in-flight requests is supported as long as the user97 * application uses properly distinct sequence numbers for concurrent requests98 * and takes care to properly manage all the related issues about concurrency99 * and command/reply pairing. Keep in mind that, anyway, the real level of100 * parallelism attainable in such scenario is dependent on the characteristics101 * of the underlying transport being used.102 *103 * Since the SCMI core regular stack is partially used to deliver and collect104 * the messages, late replies arrived after timeouts and any other sort of105 * unexpected message can be identified by the SCMI core as usual and they will106 * be reported as messages under "errors" for later analysis.107 */108 109#include <linux/bitmap.h>110#include <linux/debugfs.h>111#include <linux/delay.h>112#include <linux/device.h>113#include <linux/export.h>114#include <linux/io.h>115#include <linux/kernel.h>116#include <linux/fs.h>117#include <linux/list.h>118#include <linux/module.h>119#include <linux/poll.h>120#include <linux/of.h>121#include <linux/slab.h>122#include <linux/xarray.h>123 124#include "common.h"125 126#include "raw_mode.h"127 128#include <trace/events/scmi.h>129 130#define SCMI_XFER_RAW_MAX_RETRIES	10131 132/**133 * struct scmi_raw_queue  - Generic Raw queue descriptor134 *135 * @free_bufs: A freelists listhead used to keep unused raw buffers136 * @free_bufs_lock: Spinlock used to protect access to @free_bufs137 * @msg_q: A listhead to a queue of snooped messages waiting to be read out138 * @msg_q_lock: Spinlock used to protect access to @msg_q139 * @wq: A waitqueue used to wait and poll on related @msg_q140 */141struct scmi_raw_queue {142	struct list_head free_bufs;143	/* Protect free_bufs[] lists */144	spinlock_t free_bufs_lock;145	struct list_head msg_q;146	/* Protect msg_q[] lists */147	spinlock_t msg_q_lock;148	wait_queue_head_t wq;149};150 151/**152 * struct scmi_raw_mode_info  - Structure holding SCMI Raw instance data153 *154 * @id: Sequential Raw instance ID.155 * @handle: Pointer to SCMI entity handle to use156 * @desc: Pointer to the transport descriptor to use157 * @tx_max_msg: Maximum number of concurrent TX in-flight messages158 * @q: An array of Raw queue descriptors159 * @chans_q: An XArray mapping optional additional per-channel queues160 * @free_waiters: Head of freelist for unused waiters161 * @free_mtx: A mutex to protect the waiters freelist162 * @active_waiters: Head of list for currently active and used waiters163 * @active_mtx: A mutex to protect the active waiters list164 * @waiters_work: A work descriptor to be used with the workqueue machinery165 * @wait_wq: A workqueue reference to the created workqueue166 * @dentry: Top debugfs root dentry for SCMI Raw167 * @gid: A group ID used for devres accounting168 *169 * Note that this descriptor is passed back to the core after SCMI Raw is170 * initialized as an opaque handle to use by subsequent SCMI Raw call hooks.171 *172 */173struct scmi_raw_mode_info {174	unsigned int id;175	const struct scmi_handle *handle;176	const struct scmi_desc *desc;177	int tx_max_msg;178	struct scmi_raw_queue *q[SCMI_RAW_MAX_QUEUE];179	struct xarray chans_q;180	struct list_head free_waiters;181	/* Protect free_waiters list */182	struct mutex free_mtx;183	struct list_head active_waiters;184	/* Protect active_waiters list */185	struct mutex active_mtx;186	struct work_struct waiters_work;187	struct workqueue_struct	*wait_wq;188	struct dentry *dentry;189	void *gid;190};191 192/**193 * struct scmi_xfer_raw_waiter  - Structure to describe an xfer to be waited for194 *195 * @start_jiffies: The timestamp in jiffies of when this structure was queued.196 * @cinfo: A reference to the channel to use for this transaction197 * @xfer: A reference to the xfer to be waited for198 * @async_response: A completion to be, optionally, used for async waits: it199 *		    will be setup by @scmi_do_xfer_raw_start, if needed, to be200 *		    pointed at by xfer->async_done.201 * @node: A list node.202 */203struct scmi_xfer_raw_waiter {204	unsigned long start_jiffies;205	struct scmi_chan_info *cinfo;206	struct scmi_xfer *xfer;207	struct completion async_response;208	struct list_head node;209};210 211/**212 * struct scmi_raw_buffer  - Structure to hold a full SCMI message213 *214 * @max_len: The maximum allowed message size (header included) that can be215 *	     stored into @msg216 * @msg: A message buffer used to collect a full message grabbed from an xfer.217 * @node: A list node.218 */219struct scmi_raw_buffer {220	size_t max_len;221	struct scmi_msg msg;222	struct list_head node;223};224 225/**226 * struct scmi_dbg_raw_data  - Structure holding data needed by the debugfs227 * layer228 *229 * @chan_id: The preferred channel to use: if zero the channel is automatically230 *	     selected based on protocol.231 * @raw: A reference to the Raw instance.232 * @tx: A message buffer used to collect TX message on write.233 * @tx_size: The effective size of the TX message.234 * @tx_req_size: The final expected size of the complete TX message.235 * @rx: A message buffer to collect RX message on read.236 * @rx_size: The effective size of the RX message.237 */238struct scmi_dbg_raw_data {239	u8 chan_id;240	struct scmi_raw_mode_info *raw;241	struct scmi_msg tx;242	size_t tx_size;243	size_t tx_req_size;244	struct scmi_msg rx;245	size_t rx_size;246};247 248static struct scmi_raw_queue *249scmi_raw_queue_select(struct scmi_raw_mode_info *raw, unsigned int idx,250		      unsigned int chan_id)251{252	if (!chan_id)253		return raw->q[idx];254 255	return xa_load(&raw->chans_q, chan_id);256}257 258static struct scmi_raw_buffer *scmi_raw_buffer_get(struct scmi_raw_queue *q)259{260	unsigned long flags;261	struct scmi_raw_buffer *rb = NULL;262	struct list_head *head = &q->free_bufs;263 264	spin_lock_irqsave(&q->free_bufs_lock, flags);265	if (!list_empty(head)) {266		rb = list_first_entry(head, struct scmi_raw_buffer, node);267		list_del_init(&rb->node);268	}269	spin_unlock_irqrestore(&q->free_bufs_lock, flags);270 271	return rb;272}273 274static void scmi_raw_buffer_put(struct scmi_raw_queue *q,275				struct scmi_raw_buffer *rb)276{277	unsigned long flags;278 279	/* Reset to full buffer length */280	rb->msg.len = rb->max_len;281 282	spin_lock_irqsave(&q->free_bufs_lock, flags);283	list_add_tail(&rb->node, &q->free_bufs);284	spin_unlock_irqrestore(&q->free_bufs_lock, flags);285}286 287static void scmi_raw_buffer_enqueue(struct scmi_raw_queue *q,288				    struct scmi_raw_buffer *rb)289{290	unsigned long flags;291 292	spin_lock_irqsave(&q->msg_q_lock, flags);293	list_add_tail(&rb->node, &q->msg_q);294	spin_unlock_irqrestore(&q->msg_q_lock, flags);295 296	wake_up_interruptible(&q->wq);297}298 299static struct scmi_raw_buffer*300scmi_raw_buffer_dequeue_unlocked(struct scmi_raw_queue *q)301{302	struct scmi_raw_buffer *rb = NULL;303 304	if (!list_empty(&q->msg_q)) {305		rb = list_first_entry(&q->msg_q, struct scmi_raw_buffer, node);306		list_del_init(&rb->node);307	}308 309	return rb;310}311 312static struct scmi_raw_buffer *scmi_raw_buffer_dequeue(struct scmi_raw_queue *q)313{314	unsigned long flags;315	struct scmi_raw_buffer *rb;316 317	spin_lock_irqsave(&q->msg_q_lock, flags);318	rb = scmi_raw_buffer_dequeue_unlocked(q);319	spin_unlock_irqrestore(&q->msg_q_lock, flags);320 321	return rb;322}323 324static void scmi_raw_buffer_queue_flush(struct scmi_raw_queue *q)325{326	struct scmi_raw_buffer *rb;327 328	do {329		rb = scmi_raw_buffer_dequeue(q);330		if (rb)331			scmi_raw_buffer_put(q, rb);332	} while (rb);333}334 335static struct scmi_xfer_raw_waiter *336scmi_xfer_raw_waiter_get(struct scmi_raw_mode_info *raw, struct scmi_xfer *xfer,337			 struct scmi_chan_info *cinfo, bool async)338{339	struct scmi_xfer_raw_waiter *rw = NULL;340 341	mutex_lock(&raw->free_mtx);342	if (!list_empty(&raw->free_waiters)) {343		rw = list_first_entry(&raw->free_waiters,344				      struct scmi_xfer_raw_waiter, node);345		list_del_init(&rw->node);346 347		if (async) {348			reinit_completion(&rw->async_response);349			xfer->async_done = &rw->async_response;350		}351 352		rw->cinfo = cinfo;353		rw->xfer = xfer;354	}355	mutex_unlock(&raw->free_mtx);356 357	return rw;358}359 360static void scmi_xfer_raw_waiter_put(struct scmi_raw_mode_info *raw,361				     struct scmi_xfer_raw_waiter *rw)362{363	if (rw->xfer) {364		rw->xfer->async_done = NULL;365		rw->xfer = NULL;366	}367 368	mutex_lock(&raw->free_mtx);369	list_add_tail(&rw->node, &raw->free_waiters);370	mutex_unlock(&raw->free_mtx);371}372 373static void scmi_xfer_raw_waiter_enqueue(struct scmi_raw_mode_info *raw,374					 struct scmi_xfer_raw_waiter *rw)375{376	/* A timestamp for the deferred worker to know how much this has aged */377	rw->start_jiffies = jiffies;378 379	trace_scmi_xfer_response_wait(rw->xfer->transfer_id, rw->xfer->hdr.id,380				      rw->xfer->hdr.protocol_id,381				      rw->xfer->hdr.seq,382				      raw->desc->max_rx_timeout_ms,383				      rw->xfer->hdr.poll_completion);384 385	mutex_lock(&raw->active_mtx);386	list_add_tail(&rw->node, &raw->active_waiters);387	mutex_unlock(&raw->active_mtx);388 389	/* kick waiter work */390	queue_work(raw->wait_wq, &raw->waiters_work);391}392 393static struct scmi_xfer_raw_waiter *394scmi_xfer_raw_waiter_dequeue(struct scmi_raw_mode_info *raw)395{396	struct scmi_xfer_raw_waiter *rw = NULL;397 398	mutex_lock(&raw->active_mtx);399	if (!list_empty(&raw->active_waiters)) {400		rw = list_first_entry(&raw->active_waiters,401				      struct scmi_xfer_raw_waiter, node);402		list_del_init(&rw->node);403	}404	mutex_unlock(&raw->active_mtx);405 406	return rw;407}408 409/**410 * scmi_xfer_raw_worker  - Work function to wait for Raw xfers completions411 *412 * @work: A reference to the work.413 *414 * In SCMI Raw mode, once a user-provided injected SCMI message is sent, we415 * cannot wait to receive its response (if any) in the context of the injection416 * routines so as not to leave the userspace write syscall, which delivered the417 * SCMI message to send, pending till eventually a reply is received.418 * Userspace should and will poll/wait instead on the read syscalls which will419 * be in charge of reading a received reply (if any).420 *421 * Even though reply messages are collected and reported into the SCMI Raw layer422 * on the RX path, nonetheless we have to properly wait for their completion as423 * usual (and async_completion too if needed) in order to properly release the424 * xfer structure at the end: to do this out of the context of the write/send425 * these waiting jobs are delegated to this deferred worker.426 *427 * Any sent xfer, to be waited for, is timestamped and queued for later428 * consumption by this worker: queue aging is accounted for while choosing a429 * timeout for the completion, BUT we do not really care here if we end up430 * accidentally waiting for a bit too long.431 */432static void scmi_xfer_raw_worker(struct work_struct *work)433{434	struct scmi_raw_mode_info *raw;435	struct device *dev;436	unsigned long max_tmo;437 438	raw = container_of(work, struct scmi_raw_mode_info, waiters_work);439	dev = raw->handle->dev;440	max_tmo = msecs_to_jiffies(raw->desc->max_rx_timeout_ms);441 442	do {443		int ret = 0;444		unsigned int timeout_ms;445		unsigned long aging;446		struct scmi_xfer *xfer;447		struct scmi_xfer_raw_waiter *rw;448		struct scmi_chan_info *cinfo;449 450		rw = scmi_xfer_raw_waiter_dequeue(raw);451		if (!rw)452			return;453 454		cinfo = rw->cinfo;455		xfer = rw->xfer;456		/*457		 * Waiters are queued by wait-deadline at the end, so some of458		 * them could have been already expired when processed, BUT we459		 * have to check the completion status anyway just in case a460		 * virtually expired (aged) transaction was indeed completed461		 * fine and we'll have to wait for the asynchronous part (if462		 * any): for this reason a 1 ms timeout is used for already463		 * expired/aged xfers.464		 */465		aging = jiffies - rw->start_jiffies;466		timeout_ms = max_tmo > aging ?467			jiffies_to_msecs(max_tmo - aging) : 1;468 469		ret = scmi_xfer_raw_wait_for_message_response(cinfo, xfer,470							      timeout_ms);471		if (!ret && xfer->hdr.status)472			ret = scmi_to_linux_errno(xfer->hdr.status);473 474		if (raw->desc->ops->mark_txdone)475			raw->desc->ops->mark_txdone(rw->cinfo, ret, xfer);476 477		trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,478				    xfer->hdr.protocol_id, xfer->hdr.seq, ret);479 480		/* Wait also for an async delayed response if needed */481		if (!ret && xfer->async_done) {482			unsigned long tmo = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);483 484			if (!wait_for_completion_timeout(xfer->async_done, tmo))485				dev_err(dev,486					"timed out in RAW delayed resp - HDR:%08X\n",487					pack_scmi_header(&xfer->hdr));488		}489 490		/* Release waiter and xfer */491		scmi_xfer_raw_put(raw->handle, xfer);492		scmi_xfer_raw_waiter_put(raw, rw);493	} while (1);494}495 496static void scmi_xfer_raw_reset(struct scmi_raw_mode_info *raw)497{498	int i;499 500	dev_info(raw->handle->dev, "Resetting SCMI Raw stack.\n");501 502	for (i = 0; i < SCMI_RAW_MAX_QUEUE; i++)503		scmi_raw_buffer_queue_flush(raw->q[i]);504}505 506/**507 * scmi_xfer_raw_get_init  - An helper to build a valid xfer from the provided508 * bare SCMI message.509 *510 * @raw: A reference to the Raw instance.511 * @buf: A buffer containing the whole SCMI message to send (including the512 *	 header) in little-endian binary formmat.513 * @len: Length of the message in @buf.514 * @p: A pointer to return the initialized Raw xfer.515 *516 * After an xfer is picked from the TX pool and filled in with the message517 * content, the xfer is registered as pending with the core in the usual way518 * using the original sequence number provided by the user with the message.519 *520 * Note that, in case the testing user application is NOT using distinct521 * sequence-numbers between successive SCMI messages such registration could522 * fail temporarily if the previous message, using the same sequence number,523 * had still not released; in such a case we just wait and retry.524 *525 * Return: 0 on Success526 */527static int scmi_xfer_raw_get_init(struct scmi_raw_mode_info *raw, void *buf,528				  size_t len, struct scmi_xfer **p)529{530	u32 msg_hdr;531	size_t tx_size;532	struct scmi_xfer *xfer;533	int ret, retry = SCMI_XFER_RAW_MAX_RETRIES;534	struct device *dev = raw->handle->dev;535 536	if (!buf || len < sizeof(u32))537		return -EINVAL;538 539	tx_size = len - sizeof(u32);540	/* Ensure we have sane transfer sizes */541	if (tx_size > raw->desc->max_msg_size)542		return -ERANGE;543 544	xfer = scmi_xfer_raw_get(raw->handle);545	if (IS_ERR(xfer)) {546		dev_warn(dev, "RAW - Cannot get a free RAW xfer !\n");547		return PTR_ERR(xfer);548	}549 550	/* Build xfer from the provided SCMI bare LE message */551	msg_hdr = le32_to_cpu(*((__le32 *)buf));552	unpack_scmi_header(msg_hdr, &xfer->hdr);553	xfer->hdr.seq = (u16)MSG_XTRACT_TOKEN(msg_hdr);554	/* Polling not supported */555	xfer->hdr.poll_completion = false;556	xfer->hdr.status = SCMI_SUCCESS;557	xfer->tx.len = tx_size;558	xfer->rx.len = raw->desc->max_msg_size;559	/* Clear the whole TX buffer */560	memset(xfer->tx.buf, 0x00, raw->desc->max_msg_size);561	if (xfer->tx.len)562		memcpy(xfer->tx.buf, (u8 *)buf + sizeof(msg_hdr), xfer->tx.len);563	*p = xfer;564 565	/*566	 * In flight registration can temporarily fail in case of Raw messages567	 * if the user injects messages without using monotonically increasing568	 * sequence numbers since, in Raw mode, the xfer (and the token) is569	 * finally released later by a deferred worker. Just retry for a while.570	 */571	do {572		ret = scmi_xfer_raw_inflight_register(raw->handle, xfer);573		if (ret) {574			dev_dbg(dev,575				"...retrying[%d] inflight registration\n",576				retry);577			msleep(raw->desc->max_rx_timeout_ms /578			       SCMI_XFER_RAW_MAX_RETRIES);579		}580	} while (ret && --retry);581 582	if (ret) {583		dev_warn(dev,584			 "RAW - Could NOT register xfer %d in-flight HDR:0x%08X\n",585			 xfer->hdr.seq, msg_hdr);586		scmi_xfer_raw_put(raw->handle, xfer);587	}588 589	return ret;590}591 592/**593 * scmi_do_xfer_raw_start  - An helper to send a valid raw xfer594 *595 * @raw: A reference to the Raw instance.596 * @xfer: The xfer to send597 * @chan_id: The channel ID to use, if zero the channels is automatically598 *	     selected based on the protocol used.599 * @async: A flag stating if an asynchronous command is required.600 *601 * This function send a previously built raw xfer using an appropriate channel602 * and queues the related waiting work.603 *604 * Note that we need to know explicitly if the required command is meant to be605 * asynchronous in kind since we have to properly setup the waiter.606 * (and deducing this from the payload is weak and do not scale given there is607 *  NOT a common header-flag stating if the command is asynchronous or not)608 *609 * Return: 0 on Success610 */611static int scmi_do_xfer_raw_start(struct scmi_raw_mode_info *raw,612				  struct scmi_xfer *xfer, u8 chan_id,613				  bool async)614{615	int ret;616	struct scmi_chan_info *cinfo;617	struct scmi_xfer_raw_waiter *rw;618	struct device *dev = raw->handle->dev;619 620	if (!chan_id)621		chan_id = xfer->hdr.protocol_id;622	else623		xfer->flags |= SCMI_XFER_FLAG_CHAN_SET;624 625	cinfo = scmi_xfer_raw_channel_get(raw->handle, chan_id);626	if (IS_ERR(cinfo))627		return PTR_ERR(cinfo);628 629	rw = scmi_xfer_raw_waiter_get(raw, xfer, cinfo, async);630	if (!rw) {631		dev_warn(dev, "RAW - Cannot get a free waiter !\n");632		return -ENOMEM;633	}634 635	/* True ONLY if also supported by transport. */636	if (is_polling_enabled(cinfo, raw->desc))637		xfer->hdr.poll_completion = true;638 639	reinit_completion(&xfer->done);640	/* Make sure xfer state update is visible before sending */641	smp_store_mb(xfer->state, SCMI_XFER_SENT_OK);642 643	trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,644			      xfer->hdr.protocol_id, xfer->hdr.seq,645			      xfer->hdr.poll_completion);646 647	ret = raw->desc->ops->send_message(rw->cinfo, xfer);648	if (ret) {649		dev_err(dev, "Failed to send RAW message %d\n", ret);650		scmi_xfer_raw_waiter_put(raw, rw);651		return ret;652	}653 654	trace_scmi_msg_dump(raw->id, cinfo->id, xfer->hdr.protocol_id,655			    xfer->hdr.id, "cmnd", xfer->hdr.seq,656			    xfer->hdr.status,657			    xfer->tx.buf, xfer->tx.len);658 659	scmi_xfer_raw_waiter_enqueue(raw, rw);660 661	return ret;662}663 664/**665 * scmi_raw_message_send  - An helper to build and send an SCMI command using666 * the provided SCMI bare message buffer667 *668 * @raw: A reference to the Raw instance.669 * @buf: A buffer containing the whole SCMI message to send (including the670 *	 header) in little-endian binary format.671 * @len: Length of the message in @buf.672 * @chan_id: The channel ID to use.673 * @async: A flag stating if an asynchronous command is required.674 *675 * Return: 0 on Success676 */677static int scmi_raw_message_send(struct scmi_raw_mode_info *raw,678				 void *buf, size_t len, u8 chan_id, bool async)679{680	int ret;681	struct scmi_xfer *xfer;682 683	ret = scmi_xfer_raw_get_init(raw, buf, len, &xfer);684	if (ret)685		return ret;686 687	ret = scmi_do_xfer_raw_start(raw, xfer, chan_id, async);688	if (ret)689		scmi_xfer_raw_put(raw->handle, xfer);690 691	return ret;692}693 694static struct scmi_raw_buffer *695scmi_raw_message_dequeue(struct scmi_raw_queue *q, bool o_nonblock)696{697	unsigned long flags;698	struct scmi_raw_buffer *rb;699 700	spin_lock_irqsave(&q->msg_q_lock, flags);701	while (list_empty(&q->msg_q)) {702		spin_unlock_irqrestore(&q->msg_q_lock, flags);703 704		if (o_nonblock)705			return ERR_PTR(-EAGAIN);706 707		if (wait_event_interruptible(q->wq, !list_empty(&q->msg_q)))708			return ERR_PTR(-ERESTARTSYS);709 710		spin_lock_irqsave(&q->msg_q_lock, flags);711	}712 713	rb = scmi_raw_buffer_dequeue_unlocked(q);714 715	spin_unlock_irqrestore(&q->msg_q_lock, flags);716 717	return rb;718}719 720/**721 * scmi_raw_message_receive  - An helper to dequeue and report the next722 * available enqueued raw message payload that has been collected.723 *724 * @raw: A reference to the Raw instance.725 * @buf: A buffer to get hold of the whole SCMI message received and represented726 *	 in little-endian binary format.727 * @len: Length of @buf.728 * @size: The effective size of the message copied into @buf729 * @idx: The index of the queue to pick the next queued message from.730 * @chan_id: The channel ID to use.731 * @o_nonblock: A flag to request a non-blocking message dequeue.732 *733 * Return: 0 on Success734 */735static int scmi_raw_message_receive(struct scmi_raw_mode_info *raw,736				    void *buf, size_t len, size_t *size,737				    unsigned int idx, unsigned int chan_id,738				    bool o_nonblock)739{740	int ret = 0;741	struct scmi_raw_buffer *rb;742	struct scmi_raw_queue *q;743 744	q = scmi_raw_queue_select(raw, idx, chan_id);745	if (!q)746		return -ENODEV;747 748	rb = scmi_raw_message_dequeue(q, o_nonblock);749	if (IS_ERR(rb)) {750		dev_dbg(raw->handle->dev, "RAW - No message available!\n");751		return PTR_ERR(rb);752	}753 754	if (rb->msg.len <= len) {755		memcpy(buf, rb->msg.buf, rb->msg.len);756		*size = rb->msg.len;757	} else {758		ret = -ENOSPC;759	}760 761	scmi_raw_buffer_put(q, rb);762 763	return ret;764}765 766/* SCMI Raw debugfs helpers */767 768static ssize_t scmi_dbg_raw_mode_common_read(struct file *filp,769					     char __user *buf,770					     size_t count, loff_t *ppos,771					     unsigned int idx)772{773	ssize_t cnt;774	struct scmi_dbg_raw_data *rd = filp->private_data;775 776	if (!rd->rx_size) {777		int ret;778 779		ret = scmi_raw_message_receive(rd->raw, rd->rx.buf, rd->rx.len,780					       &rd->rx_size, idx, rd->chan_id,781					       filp->f_flags & O_NONBLOCK);782		if (ret) {783			rd->rx_size = 0;784			return ret;785		}786 787		/* Reset any previous filepos change, including writes */788		*ppos = 0;789	} else if (*ppos == rd->rx_size) {790		/* Return EOF once all the message has been read-out */791		rd->rx_size = 0;792		return 0;793	}794 795	cnt = simple_read_from_buffer(buf, count, ppos,796				      rd->rx.buf, rd->rx_size);797 798	return cnt;799}800 801static ssize_t scmi_dbg_raw_mode_common_write(struct file *filp,802					      const char __user *buf,803					      size_t count, loff_t *ppos,804					      bool async)805{806	int ret;807	struct scmi_dbg_raw_data *rd = filp->private_data;808 809	if (count > rd->tx.len - rd->tx_size)810		return -ENOSPC;811 812	/* On first write attempt @count carries the total full message size. */813	if (!rd->tx_size)814		rd->tx_req_size = count;815 816	/*817	 * Gather a full message, possibly across multiple interrupted wrrtes,818	 * before sending it with a single RAW xfer.819	 */820	if (rd->tx_size < rd->tx_req_size) {821		ssize_t cnt;822 823		cnt = simple_write_to_buffer(rd->tx.buf, rd->tx.len, ppos,824					     buf, count);825		if (cnt < 0)826			return cnt;827 828		rd->tx_size += cnt;829		if (cnt < count)830			return cnt;831	}832 833	ret = scmi_raw_message_send(rd->raw, rd->tx.buf, rd->tx_size,834				    rd->chan_id, async);835 836	/* Reset ppos for next message ... */837	rd->tx_size = 0;838	*ppos = 0;839 840	return ret ?: count;841}842 843static __poll_t scmi_test_dbg_raw_common_poll(struct file *filp,844					      struct poll_table_struct *wait,845					      unsigned int idx)846{847	unsigned long flags;848	struct scmi_dbg_raw_data *rd = filp->private_data;849	struct scmi_raw_queue *q;850	__poll_t mask = 0;851 852	q = scmi_raw_queue_select(rd->raw, idx, rd->chan_id);853	if (!q)854		return mask;855 856	poll_wait(filp, &q->wq, wait);857 858	spin_lock_irqsave(&q->msg_q_lock, flags);859	if (!list_empty(&q->msg_q))860		mask = EPOLLIN | EPOLLRDNORM;861	spin_unlock_irqrestore(&q->msg_q_lock, flags);862 863	return mask;864}865 866static ssize_t scmi_dbg_raw_mode_message_read(struct file *filp,867					      char __user *buf,868					      size_t count, loff_t *ppos)869{870	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,871					     SCMI_RAW_REPLY_QUEUE);872}873 874static ssize_t scmi_dbg_raw_mode_message_write(struct file *filp,875					       const char __user *buf,876					       size_t count, loff_t *ppos)877{878	return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, false);879}880 881static __poll_t scmi_dbg_raw_mode_message_poll(struct file *filp,882					       struct poll_table_struct *wait)883{884	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_REPLY_QUEUE);885}886 887static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp)888{889	u8 id;890	struct scmi_raw_mode_info *raw;891	struct scmi_dbg_raw_data *rd;892	const char *id_str = filp->f_path.dentry->d_parent->d_name.name;893 894	if (!inode->i_private)895		return -ENODEV;896 897	raw = inode->i_private;898	rd = kzalloc(sizeof(*rd), GFP_KERNEL);899	if (!rd)900		return -ENOMEM;901 902	rd->rx.len = raw->desc->max_msg_size + sizeof(u32);903	rd->rx.buf = kzalloc(rd->rx.len, GFP_KERNEL);904	if (!rd->rx.buf) {905		kfree(rd);906		return -ENOMEM;907	}908 909	rd->tx.len = raw->desc->max_msg_size + sizeof(u32);910	rd->tx.buf = kzalloc(rd->tx.len, GFP_KERNEL);911	if (!rd->tx.buf) {912		kfree(rd->rx.buf);913		kfree(rd);914		return -ENOMEM;915	}916 917	/* Grab channel ID from debugfs entry naming if any */918	if (!kstrtou8(id_str, 16, &id))919		rd->chan_id = id;920 921	rd->raw = raw;922	filp->private_data = rd;923 924	return nonseekable_open(inode, filp);925}926 927static int scmi_dbg_raw_mode_release(struct inode *inode, struct file *filp)928{929	struct scmi_dbg_raw_data *rd = filp->private_data;930 931	kfree(rd->rx.buf);932	kfree(rd->tx.buf);933	kfree(rd);934 935	return 0;936}937 938static ssize_t scmi_dbg_raw_mode_reset_write(struct file *filp,939					     const char __user *buf,940					     size_t count, loff_t *ppos)941{942	struct scmi_dbg_raw_data *rd = filp->private_data;943 944	scmi_xfer_raw_reset(rd->raw);945 946	return count;947}948 949static const struct file_operations scmi_dbg_raw_mode_reset_fops = {950	.open = scmi_dbg_raw_mode_open,951	.release = scmi_dbg_raw_mode_release,952	.write = scmi_dbg_raw_mode_reset_write,953	.owner = THIS_MODULE,954};955 956static const struct file_operations scmi_dbg_raw_mode_message_fops = {957	.open = scmi_dbg_raw_mode_open,958	.release = scmi_dbg_raw_mode_release,959	.read = scmi_dbg_raw_mode_message_read,960	.write = scmi_dbg_raw_mode_message_write,961	.poll = scmi_dbg_raw_mode_message_poll,962	.owner = THIS_MODULE,963};964 965static ssize_t scmi_dbg_raw_mode_message_async_write(struct file *filp,966						     const char __user *buf,967						     size_t count, loff_t *ppos)968{969	return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, true);970}971 972static const struct file_operations scmi_dbg_raw_mode_message_async_fops = {973	.open = scmi_dbg_raw_mode_open,974	.release = scmi_dbg_raw_mode_release,975	.read = scmi_dbg_raw_mode_message_read,976	.write = scmi_dbg_raw_mode_message_async_write,977	.poll = scmi_dbg_raw_mode_message_poll,978	.owner = THIS_MODULE,979};980 981static ssize_t scmi_test_dbg_raw_mode_notif_read(struct file *filp,982						 char __user *buf,983						 size_t count, loff_t *ppos)984{985	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,986					     SCMI_RAW_NOTIF_QUEUE);987}988 989static __poll_t990scmi_test_dbg_raw_mode_notif_poll(struct file *filp,991				  struct poll_table_struct *wait)992{993	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_NOTIF_QUEUE);994}995 996static const struct file_operations scmi_dbg_raw_mode_notification_fops = {997	.open = scmi_dbg_raw_mode_open,998	.release = scmi_dbg_raw_mode_release,999	.read = scmi_test_dbg_raw_mode_notif_read,1000	.poll = scmi_test_dbg_raw_mode_notif_poll,1001	.owner = THIS_MODULE,1002};1003 1004static ssize_t scmi_test_dbg_raw_mode_errors_read(struct file *filp,1005						  char __user *buf,1006						  size_t count, loff_t *ppos)1007{1008	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,1009					     SCMI_RAW_ERRS_QUEUE);1010}1011 1012static __poll_t1013scmi_test_dbg_raw_mode_errors_poll(struct file *filp,1014				   struct poll_table_struct *wait)1015{1016	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_ERRS_QUEUE);1017}1018 1019static const struct file_operations scmi_dbg_raw_mode_errors_fops = {1020	.open = scmi_dbg_raw_mode_open,1021	.release = scmi_dbg_raw_mode_release,1022	.read = scmi_test_dbg_raw_mode_errors_read,1023	.poll = scmi_test_dbg_raw_mode_errors_poll,1024	.owner = THIS_MODULE,1025};1026 1027static struct scmi_raw_queue *1028scmi_raw_queue_init(struct scmi_raw_mode_info *raw)1029{1030	int i;1031	struct scmi_raw_buffer *rb;1032	struct device *dev = raw->handle->dev;1033	struct scmi_raw_queue *q;1034 1035	q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);1036	if (!q)1037		return ERR_PTR(-ENOMEM);1038 1039	rb = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rb), GFP_KERNEL);1040	if (!rb)1041		return ERR_PTR(-ENOMEM);1042 1043	spin_lock_init(&q->free_bufs_lock);1044	INIT_LIST_HEAD(&q->free_bufs);1045	for (i = 0; i < raw->tx_max_msg; i++, rb++) {1046		rb->max_len = raw->desc->max_msg_size + sizeof(u32);1047		rb->msg.buf = devm_kzalloc(dev, rb->max_len, GFP_KERNEL);1048		if (!rb->msg.buf)1049			return ERR_PTR(-ENOMEM);1050		scmi_raw_buffer_put(q, rb);1051	}1052 1053	spin_lock_init(&q->msg_q_lock);1054	INIT_LIST_HEAD(&q->msg_q);1055	init_waitqueue_head(&q->wq);1056 1057	return q;1058}1059 1060static int scmi_xfer_raw_worker_init(struct scmi_raw_mode_info *raw)1061{1062	int i;1063	struct scmi_xfer_raw_waiter *rw;1064	struct device *dev = raw->handle->dev;1065 1066	rw = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rw), GFP_KERNEL);1067	if (!rw)1068		return -ENOMEM;1069 1070	raw->wait_wq = alloc_workqueue("scmi-raw-wait-wq-%d",1071				       WQ_UNBOUND | WQ_FREEZABLE |1072				       WQ_HIGHPRI | WQ_SYSFS, 0, raw->id);1073	if (!raw->wait_wq)1074		return -ENOMEM;1075 1076	mutex_init(&raw->free_mtx);1077	INIT_LIST_HEAD(&raw->free_waiters);1078	mutex_init(&raw->active_mtx);1079	INIT_LIST_HEAD(&raw->active_waiters);1080 1081	for (i = 0; i < raw->tx_max_msg; i++, rw++) {1082		init_completion(&rw->async_response);1083		scmi_xfer_raw_waiter_put(raw, rw);1084	}1085	INIT_WORK(&raw->waiters_work, scmi_xfer_raw_worker);1086 1087	return 0;1088}1089 1090static int scmi_raw_mode_setup(struct scmi_raw_mode_info *raw,1091			       u8 *channels, int num_chans)1092{1093	int ret, idx;1094	void *gid;1095	struct device *dev = raw->handle->dev;1096 1097	gid = devres_open_group(dev, NULL, GFP_KERNEL);1098	if (!gid)1099		return -ENOMEM;1100 1101	for (idx = 0; idx < SCMI_RAW_MAX_QUEUE; idx++) {1102		raw->q[idx] = scmi_raw_queue_init(raw);1103		if (IS_ERR(raw->q[idx])) {1104			ret = PTR_ERR(raw->q[idx]);1105			goto err;1106		}1107	}1108 1109	xa_init(&raw->chans_q);1110	if (num_chans > 1) {1111		int i;1112 1113		for (i = 0; i < num_chans; i++) {1114			struct scmi_raw_queue *q;1115 1116			q = scmi_raw_queue_init(raw);1117			if (IS_ERR(q)) {1118				ret = PTR_ERR(q);1119				goto err_xa;1120			}1121 1122			ret = xa_insert(&raw->chans_q, channels[i], q,1123					GFP_KERNEL);1124			if (ret) {1125				dev_err(dev,1126					"Fail to allocate Raw queue 0x%02X\n",1127					channels[i]);1128				goto err_xa;1129			}1130		}1131	}1132 1133	ret = scmi_xfer_raw_worker_init(raw);1134	if (ret)1135		goto err_xa;1136 1137	devres_close_group(dev, gid);1138	raw->gid = gid;1139 1140	return 0;1141 1142err_xa:1143	xa_destroy(&raw->chans_q);1144err:1145	devres_release_group(dev, gid);1146	return ret;1147}1148 1149/**1150 * scmi_raw_mode_init  - Function to initialize the SCMI Raw stack1151 *1152 * @handle: Pointer to SCMI entity handle1153 * @top_dentry: A reference to the top Raw debugfs dentry1154 * @instance_id: The ID of the underlying SCMI platform instance represented by1155 *		 this Raw instance1156 * @channels: The list of the existing channels1157 * @num_chans: The number of entries in @channels1158 * @desc: Reference to the transport operations1159 * @tx_max_msg: Max number of in-flight messages allowed by the transport1160 *1161 * This function prepare the SCMI Raw stack and creates the debugfs API.1162 *1163 * Return: An opaque handle to the Raw instance on Success, an ERR_PTR otherwise1164 */1165void *scmi_raw_mode_init(const struct scmi_handle *handle,1166			 struct dentry *top_dentry, int instance_id,1167			 u8 *channels, int num_chans,1168			 const struct scmi_desc *desc, int tx_max_msg)1169{1170	int ret;1171	struct scmi_raw_mode_info *raw;1172	struct device *dev;1173 1174	if (!handle || !desc)1175		return ERR_PTR(-EINVAL);1176 1177	dev = handle->dev;1178	raw = devm_kzalloc(dev, sizeof(*raw), GFP_KERNEL);1179	if (!raw)1180		return ERR_PTR(-ENOMEM);1181 1182	raw->handle = handle;1183	raw->desc = desc;1184	raw->tx_max_msg = tx_max_msg;1185	raw->id = instance_id;1186 1187	ret = scmi_raw_mode_setup(raw, channels, num_chans);1188	if (ret) {1189		devm_kfree(dev, raw);1190		return ERR_PTR(ret);1191	}1192 1193	raw->dentry = debugfs_create_dir("raw", top_dentry);1194 1195	debugfs_create_file("reset", 0200, raw->dentry, raw,1196			    &scmi_dbg_raw_mode_reset_fops);1197 1198	debugfs_create_file("message", 0600, raw->dentry, raw,1199			    &scmi_dbg_raw_mode_message_fops);1200 1201	debugfs_create_file("message_async", 0600, raw->dentry, raw,1202			    &scmi_dbg_raw_mode_message_async_fops);1203 1204	debugfs_create_file("notification", 0400, raw->dentry, raw,1205			    &scmi_dbg_raw_mode_notification_fops);1206 1207	debugfs_create_file("errors", 0400, raw->dentry, raw,1208			    &scmi_dbg_raw_mode_errors_fops);1209 1210	/*1211	 * Expose per-channel entries if multiple channels available.1212	 * Just ignore errors while setting up these interfaces since we1213	 * have anyway already a working core Raw support.1214	 */1215	if (num_chans > 1) {1216		int i;1217		struct dentry *top_chans;1218 1219		top_chans = debugfs_create_dir("channels", raw->dentry);1220 1221		for (i = 0; i < num_chans; i++) {1222			char cdir[8];1223			struct dentry *chd;1224 1225			snprintf(cdir, 8, "0x%02X", channels[i]);1226			chd = debugfs_create_dir(cdir, top_chans);1227 1228			debugfs_create_file("message", 0600, chd, raw,1229					    &scmi_dbg_raw_mode_message_fops);1230 1231			debugfs_create_file("message_async", 0600, chd, raw,1232					    &scmi_dbg_raw_mode_message_async_fops);1233		}1234	}1235 1236	dev_info(dev, "SCMI RAW Mode initialized for instance %d\n", raw->id);1237 1238	return raw;1239}1240 1241/**1242 * scmi_raw_mode_cleanup  - Function to cleanup the SCMI Raw stack1243 *1244 * @r: An opaque handle to an initialized SCMI Raw instance1245 */1246void scmi_raw_mode_cleanup(void *r)1247{1248	struct scmi_raw_mode_info *raw = r;1249 1250	if (!raw)1251		return;1252 1253	debugfs_remove_recursive(raw->dentry);1254 1255	cancel_work_sync(&raw->waiters_work);1256	destroy_workqueue(raw->wait_wq);1257	xa_destroy(&raw->chans_q);1258}1259 1260static int scmi_xfer_raw_collect(void *msg, size_t *msg_len,1261				 struct scmi_xfer *xfer)1262{1263	__le32 *m;1264	size_t msg_size;1265 1266	if (!xfer || !msg || !msg_len)1267		return -EINVAL;1268 1269	/* Account for hdr ...*/1270	msg_size = xfer->rx.len + sizeof(u32);1271	/* ... and status if needed */1272	if (xfer->hdr.type != MSG_TYPE_NOTIFICATION)1273		msg_size += sizeof(u32);1274 1275	if (msg_size > *msg_len)1276		return -ENOSPC;1277 1278	m = msg;1279	*m = cpu_to_le32(pack_scmi_header(&xfer->hdr));1280	if (xfer->hdr.type != MSG_TYPE_NOTIFICATION)1281		*++m = cpu_to_le32(xfer->hdr.status);1282 1283	memcpy(++m, xfer->rx.buf, xfer->rx.len);1284 1285	*msg_len = msg_size;1286 1287	return 0;1288}1289 1290/**1291 * scmi_raw_message_report  - Helper to report back valid reponses/notifications1292 * to raw message requests.1293 *1294 * @r: An opaque reference to the raw instance configuration1295 * @xfer: The xfer containing the message to be reported1296 * @idx: The index of the queue.1297 * @chan_id: The channel ID to use.1298 *1299 * If Raw mode is enabled, this is called from the SCMI core on the regular RX1300 * path to save and enqueue the response/notification payload carried by this1301 * xfer into a dedicated scmi_raw_buffer for later consumption by the user.1302 *1303 * This way the caller can free the related xfer immediately afterwards and the1304 * user can read back the raw message payload at its own pace (if ever) without1305 * holding an xfer for too long.1306 */1307void scmi_raw_message_report(void *r, struct scmi_xfer *xfer,1308			     unsigned int idx, unsigned int chan_id)1309{1310	int ret;1311	unsigned long flags;1312	struct scmi_raw_buffer *rb;1313	struct device *dev;1314	struct scmi_raw_queue *q;1315	struct scmi_raw_mode_info *raw = r;1316 1317	if (!raw || (idx == SCMI_RAW_REPLY_QUEUE && !SCMI_XFER_IS_RAW(xfer)))1318		return;1319 1320	dev = raw->handle->dev;1321	q = scmi_raw_queue_select(raw, idx,1322				  SCMI_XFER_IS_CHAN_SET(xfer) ? chan_id : 0);1323	if (!q) {1324		dev_warn(dev,1325			 "RAW[%d] - NO queue for chan 0x%X. Dropping report.\n",1326			 idx, chan_id);1327		return;1328	}1329 1330	/*1331	 * Grab the msg_q_lock upfront to avoid a possible race between1332	 * realizing the free list was empty and effectively picking the next1333	 * buffer to use from the oldest one enqueued and still unread on this1334	 * msg_q.1335	 *1336	 * Note that nowhere else these locks are taken together, so no risk of1337	 * deadlocks du eto inversion.1338	 */1339	spin_lock_irqsave(&q->msg_q_lock, flags);1340	rb = scmi_raw_buffer_get(q);1341	if (!rb) {1342		/*1343		 * Immediate and delayed replies to previously injected Raw1344		 * commands MUST be read back from userspace to free the buffers:1345		 * if this is not happening something is seriously broken and1346		 * must be fixed at the application level: complain loudly.1347		 */1348		if (idx == SCMI_RAW_REPLY_QUEUE) {1349			spin_unlock_irqrestore(&q->msg_q_lock, flags);1350			dev_warn(dev,1351				 "RAW[%d] - Buffers exhausted. Dropping report.\n",1352				 idx);1353			return;1354		}1355 1356		/*1357		 * Notifications and errors queues are instead handled in a1358		 * circular manner: unread old buffers are just overwritten by1359		 * newer ones.1360		 *1361		 * The main reason for this is that notifications originated1362		 * by Raw requests cannot be distinguished from normal ones, so1363		 * your Raw buffers queues risk to be flooded and depleted by1364		 * notifications if you left it mistakenly enabled or when in1365		 * coexistence mode.1366		 */1367		rb = scmi_raw_buffer_dequeue_unlocked(q);1368		if (WARN_ON(!rb)) {1369			spin_unlock_irqrestore(&q->msg_q_lock, flags);1370			return;1371		}1372 1373		/* Reset to full buffer length */1374		rb->msg.len = rb->max_len;1375 1376		dev_warn_once(dev,1377			      "RAW[%d] - Buffers exhausted. Re-using oldest.\n",1378			      idx);1379	}1380	spin_unlock_irqrestore(&q->msg_q_lock, flags);1381 1382	ret = scmi_xfer_raw_collect(rb->msg.buf, &rb->msg.len, xfer);1383	if (ret) {1384		dev_warn(dev, "RAW - Cannot collect xfer into buffer !\n");1385		scmi_raw_buffer_put(q, rb);1386		return;1387	}1388 1389	scmi_raw_buffer_enqueue(q, rb);1390}1391 1392static void scmi_xfer_raw_fill(struct scmi_raw_mode_info *raw,1393			       struct scmi_chan_info *cinfo,1394			       struct scmi_xfer *xfer, u32 msg_hdr)1395{1396	/* Unpack received HDR as it is */1397	unpack_scmi_header(msg_hdr, &xfer->hdr);1398	xfer->hdr.seq = MSG_XTRACT_TOKEN(msg_hdr);1399 1400	memset(xfer->rx.buf, 0x00, xfer->rx.len);1401 1402	raw->desc->ops->fetch_response(cinfo, xfer);1403}1404 1405/**1406 * scmi_raw_error_report  - Helper to report back timed-out or generally1407 * unexpected replies.1408 *1409 * @r: An opaque reference to the raw instance configuration1410 * @cinfo: A reference to the channel to use to retrieve the broken xfer1411 * @msg_hdr: The SCMI message header of the message to fetch and report1412 * @priv: Any private data related to the xfer.1413 *1414 * If Raw mode is enabled, this is called from the SCMI core on the RX path in1415 * case of errors to save and enqueue the bad message payload carried by the1416 * message that has just been received.1417 *1418 * Note that we have to manually fetch any available payload into a temporary1419 * xfer to be able to save and enqueue the message, since the regular RX error1420 * path which had called this would have not fetched the message payload having1421 * classified it as an error.1422 */1423void scmi_raw_error_report(void *r, struct scmi_chan_info *cinfo,1424			   u32 msg_hdr, void *priv)1425{1426	struct scmi_xfer xfer;1427	struct scmi_raw_mode_info *raw = r;1428 1429	if (!raw)1430		return;1431 1432	xfer.rx.len = raw->desc->max_msg_size;1433	xfer.rx.buf = kzalloc(xfer.rx.len, GFP_ATOMIC);1434	if (!xfer.rx.buf) {1435		dev_info(raw->handle->dev,1436			 "Cannot report Raw error for HDR:0x%X - ENOMEM\n",1437			 msg_hdr);1438		return;1439	}1440 1441	/* Any transport-provided priv must be passed back down to transport */1442	if (priv)1443		/* Ensure priv is visible */1444		smp_store_mb(xfer.priv, priv);1445 1446	scmi_xfer_raw_fill(raw, cinfo, &xfer, msg_hdr);1447	scmi_raw_message_report(raw, &xfer, SCMI_RAW_ERRS_QUEUE, 0);1448 1449	kfree(xfer.rx.buf);1450}1451