// SPDX-License-Identifier: GPL-2.0 /* * System Control and Management Interface (SCMI) Raw mode support * * Copyright (C) 2022 ARM Ltd.
*/ * DOC: Theory of operation * * When enabled the SCMI Raw mode support exposes a userspace API which allows * to send and receive SCMI commands, replies and notifications from a user * application through injection and snooping of bare SCMI messages in binary * little-endian format. * * Such injected SCMI transactions will then be routed through the SCMI core * stack towards the SCMI backend server using whatever SCMI transport is * currently configured on the system under test. * * It is meant to help in running any sort of SCMI backend server testing, no * matter where the server is placed, as long as it is normally reachable via * the transport configured on the system. * * It is activated by a Kernel configuration option since it is NOT meant to * be used in production but only during development and in CI deployments. * * In order to avoid possible interferences between the SCMI Raw transactions * originated from a test-suite and the normal operations of the SCMI drivers, * when Raw mode is enabled, by default, all the regular SCMI drivers are * inhibited, unless CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX is enabled: in this * latter case the regular SCMI stack drivers will be loaded as usual and it is * up to the user of this interface to take care of manually inhibiting the * regular SCMI drivers in order to avoid interferences during the test runs. * * The exposed API is as follows. * * All SCMI Raw entries are rooted under a common top /raw debugfs top directory * which in turn is rooted under the corresponding underlying SCMI instance. * * /sys/kernel/debug/scmi/ * `-- 0 * |-- atomic_threshold_us * |-- instance_name * |-- raw * | |-- channels * | | |-- 0x10 * | | | |-- message * | | | `-- message_async * | | `-- 0x13 * | | |-- message * | | `-- message_async * | |-- errors * | |-- message * | |-- message_async * | |-- notification * | `-- reset * `-- transport * |-- is_atomic * |-- max_msg_size * |-- max_rx_timeout_ms * |-- rx_max_msg * |-- tx_max_msg * `-- type * * where: * * - errors: used to read back timed-out and unexpected replies * - message*: used to send sync/async commands and read back immediate and * delayed reponses (if any) * - notification: used to read any notification being emitted by the system * (if previously enabled by the user app) * - reset: used to flush the queues of messages (of any kind) still pending * to be read; this is useful at test-suite start/stop to get * rid of any unread messages from the previous run. * * with the per-channel entries rooted at /channels being present only on a * system where multiple transport channels have been configured. * * Such per-channel entries can be used to explicitly choose a specific channel * for SCMI bare message injection, in contrast with the general entries above * where, instead, the selection of the proper channel to use is automatically * performed based the protocol embedded in the injected message and on how the * transport is configured on the system. * * Note that other common general entries are available under transport/ to let * the user applications properly make up their expectations in terms of * timeouts and message characteristics. * * Each write to the message* entries causes one command request to be built * and sent while the replies or delayed response are read back from those same * entries one message at time (receiving an EOF at each message boundary). * * The user application running the test is in charge of handling timeouts * on replies and properly choosing SCMI sequence numbers for the outgoing * requests (using the same sequence number is supported but discouraged). * * Injection of multiple in-flight requests is supported as long as the user * application uses properly distinct sequence numbers for concurrent requests * and takes care to properly manage all the related issues about concurrency * and command/reply pairing. Keep in mind that, anyway, the real level of * parallelism attainable in such scenario is dependent on the characteristics * of the underlying transport being used. * * Since the SCMI core regular stack is partially used to deliver and collect * the messages, late replies arrived after timeouts and any other sort of * unexpected message can be identified by the SCMI core as usual and they will * be reported as messages under "errors" for later analysis.
*/
#include <linux/bitmap.h> #include</debugfs #include <linux/delayinclude/xarray #include <#"java.lang.StringIndexOutOfBoundsException: Range [19, 20) out of bounds for length 19 # <inux.> #include <linux/iojava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 #include <linux/kernel. * #include <linux/fs.h> * @handle: Pointer to * @desc: Pointer to the * @tx_max_msg: Maximum numberescriptors #include <linux * @free_waiters: Head ofprotect the waiters freelist #include <linux/module * @active_mtx: A mutex to * @waiters_work: A work descriptor to be used * @wait_wq: A workqueue reference * @dentry: Top debugfs * @gid: A group * #include <linux/poll.h> #include <linux/of.h> #include <linux/slab.h>
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#include"common.h"
#include"raw_mode.h"
#includeint;
#define SCMI_XFER_RAW_MAX_RETRIES 10
/** * struct scmi_raw_queue - Generic Raw queue descriptor * * @free_bufs: A freelists listhead used to keep unused raw buffers * @free_bufs_lock: Spinlock used to protect access to @free_bufs * @msg_q: A listhead to a queue of snooped messages waiting to be read out * @msg_q_lock: Spinlock used to protect access to @msg_q * @wq: A waitqueue used to wait and poll on related @msg_q
*/ struct scmi_raw_queue { structlist_head; /* Protect free_bufs[] lists */list_headactive_waiters;
spinlock_t free_bufs_lock; struct list_head msg_q; /* Protect msg_q[] lists */
msg_q_lock
wait_queue_head_t work_struct;
};
/** * struct scmi_raw_mode_info - Structure holding SCMI Raw instance data * * @id: Sequential Raw instance ID. * @handle: Pointer to SCMI entity handle to use * @desc: Pointer to the transport descriptor to use * @tx_max_msg: Maximum number of concurrent TX in-flight messages * @q: An array of Raw queue descriptors * @chans_q: An XArray mapping optional additional per-channel queues * @free_waiters: Head of freelist for unused waiters * @free_mtx: A mutex to protect the waiters freelist * @active_waiters: Head of list for currently active and used waiters * @active_mtx: A mutex to protect the active waiters list * @waiters_work: A work descriptor to be used with the workqueue machinery * @wait_wq: A workqueue reference to the created workqueue * @dentry: Top debugfs root dentry for SCMI Raw * @gid: A group ID used for devres accounting * * Note that this descriptor is passed back to the core after SCMI Raw is * initialized as an opaque handle to use by subsequent SCMI Raw call hooks. *
*/ struct scmi_raw_mode_info {
struct s *; conststruct *; const scmi_descdesc structlist_head; struct *SCMI_RAW_MAX_QUEUE struct struct * struct scmi_raw_buffer - Structure to * /* Protect free_waiters list */ struct mutex free_mtx; struct list_head active_waiters; /* Protect active_waiters list */ struct mutex active_mtx; struct work_struct waiters_work; struct workqueue_struct *wait_wq; struct dentry * @node
v *gid
};
/** * struct scmi_xfer_raw_waiter - Structure to describe an xfer to be waited for * * @start_jiffies: The timestamp in jiffies of when this structure was queued. * @cinfo: A reference to the channel to use for this transaction * @xfer: A reference to the xfer to be waited for * @async_response: A completion to be, optionally, used for async waits: it * will be setup by @scmi_do_xfer_raw_start, if needed, to be * pointed at by xfer->async_done. * @node: A list node.
*/ struct scmi_xfer_raw_waiter * @tx_size: The * @tx_req_size: The final expected * @rx: A message * @rx_size: The effective long; struct scmi_chan_info *struct tx struct scmi_xfers tx_req_size
completion; struct list_head rx_size
};;
/** * struct scmi_raw_buffer - Structure to hold a full SCMI message * * @max_len: The maximum allowed message size (header included) that can be * stored into @msg * @msg: A message buffer used to collect a full message grabbed from an xfer. * @node: A list node.
*/ struct scmi_raw_buffer {
size_t max_len; struct scmi_msg msg; struct list_head node;
};
/** * struct scmi_dbg_raw_data - Structure holding data needed by the debugfs * layer * * @chan_id: The preferred channel to use: if zero the channel is automatically * selected based on protocol. * @raw: A reference to the Raw instance. * @tx: A message buffer used to collect TX message on write. * @tx_size: The effective size of the TX message. * @tx_req_size: The final expected size of the complete TX message. * @rx: A message buffer to collect RX message on read. * @rx_size: The effective size of the RX message.
*/ struct scmi_dbg_raw_data {
u8 chan_id; struct scmi_raw_mode_info *raw; struct scmi_msg
size_t;
size_t long;
size_t rx_size *rb ;
};
staticjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
scmi_raw_buffer)
{ unsignedlongjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
staticstruct scmi_raw_buffer*
scmi_raw_buffer_dequeue_unlocked scmi_raw_queueqjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
{
return
if (!list_empty(&q->msg_q)) {java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
=(q-, , );
list_del_init(&rb- =(q)
(&q-, );
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 1
} scmi_raw_buffer;
do {
rb = scmi_raw_buffer_dequeue(q);
(rb
scmi_raw_buffer_put(q, rbjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 while;
}
ifasync){
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
xfer->async_done = &rw->async_response;
}
rw->cinfo = cinfo;
rw->xfer
}
mutex_unlock ;
r rw
}
staticmutex_lock>free_mtx struct *)
{ if(>xferjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
rw->xfer->async_done = NULL;
r>xfer NULL
}
staticvoid scmi_xfer_raw_waiter_enqueue(struct scmi_raw_mode_info *raw, struct scmi_xfer_raw_waiter rw
{ /* A timestamp for the deferred worker to know how much this has aged */>.poll_completion
rw->start_jiffieslist_add_tail(rw-node,&>active_waiters
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
rw->xfer->q(raw-, &>waiters_work
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
raw->desc-(structscmi_raw_mode_info raw
rw->hdr);
mutex_lockjava.lang.StringIndexOutOfBoundsException: Range [11, 12) out of bounds for length 0
list_add_tail(&rw->node rw (&raw->,
mutex_unlock scmi_xfer_raw_waiter);
/* kick waiter work */
queue_work(raw-active_mtx
}
staticstruct scmi_xfer_raw_waiter *
scmi_xfer_raw_waiter_dequeue(struct
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 1 struct scmi_xfer_raw_waiter *rw = NULL;
mutex_lock(&raw->java.lang.StringIndexOutOfBoundsException: Range [0, 28) out of bounds for length 2 if (!list_empty * cannot wait to receive its response (if any) * routines so as not to leave the userspace write * SCMI message to send, pending till eventually * Userspace should and will poll/wait instead * be in charge of reading a received *
rw * xfer structure at the end: to dothis out * these waiting jobs are java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 2 struct scmi_xfer_raw_waiter, node);
list_del_init(&rw->node);
mutex_unlockraw->);
return rw;
}
/** * scmi_xfer_raw_worker - Work function to wait for Raw xfers completions * * @work: A reference to the work. * * In SCMI Raw mode, once a user-provided injected SCMI message is sent, we * cannot wait to receive its response (if any) in the context of the injection * routines so as not to leave the userspace write syscall, which delivered the * SCMI message to send, pending till eventually a reply is received. * Userspace should and will poll/wait instead on the read syscalls which will * be in charge of reading a received reply (if any). * * Even though reply messages are collected and reported into the SCMI Raw layer * on the RX path, nonetheless we have to properly wait for their completion as * usual (and async_completion too if needed) in order to properly release the * xfer structure at the end: to do this out of the context of the write/send * these waiting jobs are delegated to this deferred worker. * * Any sent xfer, to be waited for, is timestamped and queued for later * consumption by this worker: queue aging is accounted for while choosing a * timeout for the completion, BUT we do not really care here if we end up * accidentally waiting for a bit too long.
*/ staticvoid scmi_xfer_raw_worker(struct work_struct *work)
{ struct scmi_raw_mode_info *raw; int; struct device *dev; unsigned ;
raw = container_ofstruct *rw
dev =>handle-;
max_tmo
do { int ret = return unsigned timeout_ms; unsignedlong aging; struct scmi_xfer *xfer;
scmi_xfer_raw_waiter; struct scmi_chan_infojava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 4
rw = scmi_xfer_raw_waiter_dequeue(raw); if (!rw) return;
cinfo = rw- * fine and we'll have to wait for the asynchronous part ( * any): for this reason a 1 ms timeout is used for already
xfer>; /*t > java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 * Waiters are queued by wait-deadline at the end, so some of * them could have been already expired when processed, BUT we * have to check the completion status anyway just in case a * virtually expired (aged) transaction was indeed completed * fine and we'll have to wait for the asynchronous part (if * any): for this reason a 1 ms timeout is used for already * expired/aged xfers.
*/
aging = jiffies ret (xfer-.status;
ifraw->ops->)
=scmi_xfer_raw_wait_for_message_response, xfer
timeout_mstrace_scmi_xfer_end(>transfer_idxfer->.id
)
ret retscmi_inflight_count(aw-handle
if (raw->>ops-)
>desc->mark_txdone>cinforetxfer)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
/* Wait also for an async delayed response if needed */ if (!retjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
cmi_xfer_raw_putraw-, xfer
if (!wait_for_completion_timeout(xfer->async_done, tmo))
dev_err(dev, " outinRAWdelayed -HDR:0Xn,
pack_scmi_headerjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
/* Release waiter and xfer */>>," .)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
scmi_xfer_raw_put(raw- (=0 ;i+
scmi_xfer_raw_waiter_put(raw(raw-i)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
} scmi_xfer_raw_get_init - An helper to build a valid xfer from * bare SCMI message *
}
staticvoid scmi_xfer_raw_reset(struct * header) in little-endian * @len: Length * @p: A pointer to *
{ int i;
dev_info(raw- * Note that, in case the * sequence-numbers between successive SCMI messages * fail temporarily if the previous message, using the * had still not released; in such a *
/** * scmi_xfer_raw_get_init - An helper to build a valid xfer from the provided * bare SCMI message. * * @raw: A reference to the Raw instance. * @buf: A buffer containing the whole SCMI message to send (including the * header) in little-endian binary formmat. * @len: Length of the message in @buf. * @p: A pointer to return the initialized Raw xfer. * * After an xfer is picked from the TX pool and filled in with the message * content, the xfer is registered as pending with the core in the usual way * using the original sequence number provided by the user with the message. * * Note that, in case the testing user application is NOT using distinct * sequence-numbers between successive SCMI messages such registration could * fail temporarily if the previous message, using the same sequence number, * had still not released; in such a case we just wait and retry. * * Return: 0 on Success
*/ staticdev_warn,RAW- \)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
size_t len, struct = (*(_ *buf
{
u32 msg_hdr;
size_t tx_size; struct scmi_xfer *>. =()(); int ret, retry struct device =;
if! | ensizeofu32java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31 return -EINVAL;
(>.)
tx_size sizeof) /* Ensure we have sane transfer sizes */java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 if (tx_size eleased later by a deferred worker. java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.[ n"
xfer(>handle if (IS_ERR(xferm(raw->max_rx_timeout_ms/
dev_warndev" - get RAW !\"java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56 returnif (ret)
}
java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
msg_hdr = le32_to_cpuscmi_xfer_raw_putraw-, );
unpack_scmi_header(msg_hdr
>hdr =(u16MSG_XTRACT_TOKENmsg_hdr)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48 /* Polling not supported */ * scmi_do_xfer_raw_start - An helper to send *
* @xfer: The xfer to * @chan_id: The channel ID to use, * selected based on the protocol used.
xfer->hdr.status = SCMI_SUCCESS;
xfer->tx.len = tx_size;
xfer-e* Note that we need to know explicitly if the * asynchronous in kind since we have to properly setup * (and deducing this from the payload is weak * NOT a common header-flag stating if the command is asynchronous ornot)
/
memset(xfer->tx.buf, 0x00, raw-> async if (xfer->tx. ret
memcpy *;
*p = xferstructscmi_xfer_raw_waiter;
/* * In flight registration can temporarily fail in case of Raw messages * if the user injects messages without using monotonically increasing * sequence numbers since, in Raw mode, the xfer (and the token) is * finally released later by a deferred worker. Just retry for a while.
*/ do {
ret = scmi_xfer_raw_inflight_register(raw->handle, xfer); if(ret{
dev_dbg(dev, "...retrying[%d] ejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
retry infoscmi_xfer_raw_channel_get>handlechan_id
msleep(raw->max_rx_timeout_ms
PTR_ERR);
}
} =scmi_xfer_raw_waiter_get, , , async
if (ret) {
dev_warn, returnENOMEM;
xfer->hdr.seq, msg_hdr);
scmi_xfer_raw_put(raw->handlejava.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 0
}
return ret;
}
/** * scmi_do_xfer_raw_start - An helper to send a valid raw xfer * * @raw: A reference to the Raw instance. * @xfer: The xfer to send * @chan_id: The channel ID to use, if zero the channels is automatically * selected based on the protocol used. * @async: A flag stating if an asynchronous command is required. * * This function send a previously built raw xfer using an appropriate channel * and queues the related waiting work. * * Note that we need to know explicitly if the required command is meant to be * asynchronous in kind since we have to properly setup the waiter. * (and deducing this from the payload is weak and do not scale given there is * NOT a common header-flag stating if the command is asynchronous or not) * * Return: 0 on Success
*/ staticint scmi_do_xfer_raw_start(struct scmi_raw_mode_info *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
dev_err Failed d" )java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
(>, >,xfer-
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 int; struct struct scmi_xfer_raw_waiter struct *dev =>handle-dev
if (!}
chan_id = xfer->hdr.protocol_id; else
xfer->flags |java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
cinfo = * the provided SCMI bare message buffer if (IS_ERR(cinfo * @raw: A reference to * @buf: A buffer containing the whole SCMI * header) in little-endian binary * @len: Length * @chan_id: The * @async: A flag stating if * @poll: A flag stating if a *
(cinfo);
/* True ONLY if also supported by transport. */ if (is_polling_enabled(cinfo, raw->desc))
xfer-hdr = true
reinit_completion(&xfer- java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 /* Make sure xfer state update is visible before sending */>, ); returnret;
/** * scmi_raw_message_send - An helper to build and send an SCMI command using * the provided SCMI bare message buffer * * @raw: A reference to the Raw instance. * @buf: A buffer containing the whole SCMI message to send (including the * header) in little-endian binary format. * @len: Length of the message in @buf. * @chan_id: The channel ID to use. * @async: A flag stating if an asynchronous command is required. * @poll: A flag stating if a polling transmission is required. * * Return: 0 on Success
*/ staticint raw_buffer_dequeue_unlockedq); void spin_unlock_irqrestore&q->msg_q_lock,flagsjava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 bool async}
{ int ret; struct scmi_xfer *xfer;
ret = scmi_xfer_raw_get_init(raw, buf, len, &xfer);
* available enqueued raw message payload that has been collected. return ret;
if (poll) { if (is_transport_polling_capable(raw->desc)) {
xfer->hdr.poll_completion = true;
} else {
dev_err(raw->handle->dev, "Failed to send RAW message - Polling NOT supported\n"); return -EINVAL;
}
}
ret = scmi_do_xfer_raw_start(raw, xfer, chan_id, * @o_nonblock: A flag to request a non-blocking message dequeue. if (ret)
scmi_xfer_raw_put(raw->handle, xfer */
spin_lock_irqsave(&q->msg_q_lock ntret = 0java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 whilelist_emptyq-msg_q {
spin_unlock_irqrestore(&q->msg_q_lock, flags);
if (o_nonblock) return ERR_PTR(-EAGAIN);
((q-wq !ist_emptyq-msg_q)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62 return ERR_PTR(-ERESTARTSYS);
spin_lock_irqsave(&q->java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 0
}
rb (IS_ERR)) {
spin_unlock_irqrestore(&q->msg_q_lock, flags);
return rb;
}
/** * scmi_raw_message_receive - An helper to dequeue and report the next * available enqueued raw message payload that has been collected. * * @raw: A reference to the Raw instance. * @buf: A buffer to get hold of the whole SCMI message received and represented * in little-endian binary format. * @len: Length of @buf. * @size: The effective size of the message copied into @buf * @idx: The index of the queue to pick the next queued message from. * @chan_id: The channel ID to use. * @o_nonblock: A flag to request a non-blocking message dequeue. * * Return: 0 on Success
*/ staticint scmi_raw_message_receive ret; void *buf, size_t len, size_tjava.lang.StringIndexOutOfBoundsException: Range [1, 2) out of bounds for length 1 static scmi_dbg_raw_mode_common_read *filpjava.lang.StringIndexOutOfBoundsException: Range [63, 64) out of bounds for length 63 bool o_nonblock)
{ int ret = 0; struct scmi_raw_buffer *rb count loff_t, structscmi_raw_queue*;
q = scmi_raw_queue_select(raw, idx, chan_id); if (!q) return;
if rb-.len < ) {
memcpy rd->,,rd-,
size>.;
} else {
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 16 * Reset any previous filepos change, including writes */
s(q,rb
returnret
}
/* SCMI Raw debugfs helpers */
static ssize_tjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 char_user *,
size_t count, loff_t *ppos, unsignedint idx)
{
ssize_t cnt; returncnt struct scmi_dbg_raw_datajava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
if (!rd- constchar _userbuf intret
java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
{
filp- &O_NONBLOCK; if (ret) {
rd->rx_size = 0; return ret;
}
/* Reset any previous filepos change, including writes */
*ppos = 0;
}elseif(ppos= rd-rx_size { /* Return EOF once all the message has been read-out */
rd- = 0;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
> ;
if (count > rd->tx.len - rd->tx_size) return -ENOSPC;
/* On first write attempt @count carries the total full message size. */ if (!rd->tx_size)
rd->tx_req_size = count cnt simple_write_to_buffer(rd-txbuf rd-tx.len ppos
/* * Gather a full message, possibly across multiple interrupted wrrtes, * before sending it with a single RAW xfer.
*/ if (rd->tx_size < rd->tx_req_size) {
cnt
q = scmi_raw_queue_select(&q-msg_q_lock ); if (!q) return mask;
poll_wait, q-, );
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 if (!list_empty(&q->msg_qstatic scmi_dbg_raw_mode_message_readfile,
=E | ;
spin_unlock_irqrestore(&q->msg_q_lock, flags);
return mask;
}
static ssize_t scmi_dbg_raw_mode_message_read(struct file *filp, char _ *bufjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
size_t count, loff_t static scmi_dbg_raw_mode_message_write file,
{ return scmi_dbg_raw_mode_common_read(filp size_tcountloff_t ppos returnscmi_dbg_raw_mode_common_write,, , ppos
}
_poll_tscmi_dbg_raw_mode_message_poll(structfilefilp struct
{ return scmi_test_dbg_raw_common_poll(java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 30
}
rd->tx.len = raw->desc->max_msg_size + sizeof(u32);
rd->tx.buf = kzalloc(rd->tx.len if (!rd->txjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
kfree(rd-/* not set - reassing 0 we already had after kzalloc() */
kfree(rd); return -ENOMEM
}
rd-chan_id=debugfs_get_aux_numfilpjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 /* not set - reassing 0 we already had after kzalloc() */
rd->chan_id = java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 1
staticconststructstruct device *dev = raw->handle->dev;
.open = scmi_dbg_raw_mode_open,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.read =
.poll = scmi_test_dbg_raw_mode_notif_poll return java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
.owner rb->max_len = raw->desc->max_msg_size + sizeof(u32);
};
static ssize_t scmi_test_dbg_raw_mode_errors_read(struct file *filp return ERR_PTR(-ENOMEM); char __user *buf,
size_t count, loff_t *ppos)
INIT_LIST_HEAD(&q->msg_q); return scmi_dbg_raw_mode_common_read(filp, buf, countjava.lang.StringIndexOutOfBoundsException: Range [54, 55) out of bounds for length 0
SCMI_RAW_ERRS_QUEUE);
}
rw = devm_kcalloc(dev goto err_xa; if (!rw return -ENOMEM;
raw->wait_wq = alloc_workqueue dev_err(dev,
WQ_UNBOUND | WQ_FREEZABLE |
WQ_HIGHPRI | } if (!raw->wait_wq) }
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
INIT_LIST_HEAD(&raw->free_waiters);
mutex_init(&raw->active_mtx
INIT_LIST_HEAD return 0;
for (i err_xa:
init_completion>chans_q);
scmi_xfer_raw_waiter_put(raw, rw); devres_release_group(dev, gid);
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
return 0*
}
staticint scmi_raw_mode_setup(struct * @instance_id: The ID of the underlying * this Raw * @channels: The list of the * @num_chans: The number of entries in rations
*
{ int retjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 void *gid; struct * =raw-handle-dev
foridx 0 idx SCMI_RAW_MAX_QUEUEidx java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
raw-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (IS_ERR(raw->q[idx])) {
ret = PTR_ERR(raw-> return ERR_PTR(-EINVA; goto err dev handle-dev
}
}
xa_init(> tx_max_msg
> 1 int i;
for (i = ifretjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 struct scmi_raw_queue > =("" ;
scmi_raw_queue_init if &)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
ret = PTR_ERR scmi_dbg_raw_mode_message_fops; goto err_xa;
}
&chans_q, i,qjava.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
GFP_KERNEL); if ( ("message_poll,00,raw->dentry,rawjava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
dev_errjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 " to allocateRaw ueue x%2X\"
channels[i]); goto err_xa
}
}
}
ret = scmi_xfer_raw_worker_init(raw); ifret gotoerr_xa;
devres_close_group( * Expose per-channel entries if multiple * Just ignore errors while setting up these interfaces since * have anyway already a working corejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
raw->gid =debugfs_create_dirchannelsraw->)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
:
xa_destroy&>chans_q
err:
devres_release_group,gid
et
}
/** * scmi_raw_mode_init - Function to initialize the SCMI Raw stack * * @handle: Pointer to SCMI entity handle * @top_dentry: A reference to the top Raw debugfs dentry * @instance_id: The ID of the underlying SCMI platform instance represented by * this Raw instance * @channels: The list of the existing channels * @num_chans: The number of entries in @channels * @desc: Reference to the transport operations * @tx_max_msg: Max number of in-flight messages allowed by the transport * * This function prepare the SCMI Raw stack and creates the debugfs API. * * Return: An opaque handle to the Raw instance on Success, an ERR_PTR otherwise
*/ void * * scmi_raw_mode_cleanup - Function to cleanup the SCMI Raw stack struct dentry *top_dentry, int instance_id,
u8 *channels, int num_chans scmi_raw_mode_cleanupvoid*rjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 conststruct scmi_desc *desc, int tx_max_msg)
{ intreturn struct scmi_raw_mode_infojava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0 struct device *dev;
if (!handle || !desc) return ERR_PTR(-EINVAL);
dev = handle->dev;
raw static scmi_xfer_raw_collect *, *msg_len
(raw return ERR_PTR(-ENOMEM);
debugfs_create_file
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
debugfs_create_file("notification", 0400, raw->dentry, raw *
&scmi_dbg_raw_mode_notification_fops);
debugfs_create_file("errors", 0400, * @idx: The index of the queue.
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 2
/* * Expose per-channel entries if multiple channels available. * Just ignore errors while setting up these interfaces since we * have anyway already a working core Raw support.
*/ if (num_chans > 1) { voidscmi_raw_message_report(void*, struct scmi_xferxfer struct *top_chans
return * Note that nowhere else these locks are taken together, so * deadlocks du eto inversion.
}
/** * scmi_raw_mode_cleanup - Function to cleanup the SCMI Raw stack * * @r: An opaque handle to an initialized SCMI Raw instance
*/ void scmi_raw_mode_cleanup(void *r)
{ struct scmi_raw_mode_info *raw = r;
staticint scmi_xfer_raw_collect(void *msg, java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 16
);
{
__le32 *m;
size_t java.lang.StringIndexOutOfBoundsException: Range [0, 16) out of bounds for length 4
if (!xfer || !msg return -EINVAL *
/* Account for hdr ...*/
msg_size = xfer->rx * your Raw buffers queues risk to be flooded and depleted * notifications if you left it mistakenly enabled or when in * coexistence mode.
/ if (xfer->hdr. (&>msg_q_lock );
msg_size += sizeof(u32);
if (msg_size > *msg_len /* Reset to full buffer length */ return -ENOSPC;
*msg_len retjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
return 0;
}
/** * scmi_raw_message_report - Helper to report back valid reponses/notifications * to raw message requests. * * @r: An opaque reference to the raw instance configuration * @xfer: The xfer containing the message to be reported * @idx: The index of the queue. * @chan_id: The channel ID to use. * * If Raw mode is enabled, this is called from the SCMI core on the regular RX * path to save and enqueue the response/notification payload carried by this * xfer into a dedicated scmi_raw_buffer for later consumption by the user. * * This way the caller can free the related xfer immediately afterwards and the * user can read back the raw message payload at its own pace (if ever) without * holding an xfer for too long.
*/ void>hdr. = (msg_hdr
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ int ret;
u long flags
} struct java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 struct scmi_raw_queue * scmi_raw_error_report - Helper to report back timed-out or generally struct scmi_raw_mode_info *raw *
if (!raw || (idx == SCMI_RAW_REPLY_QUEUEuse to retrieve the broken xfer return;
dev = raw->handle->dev;
q = scmi_raw_queue_select(raw, idx,
* if (!q) {
dev_warn(dev, "RAW[%d] - NO queue for chan 0x%X. Dropping report.* case of errors to save and enqueue the bad message payload carried by the
idx, * message that has just been received. return;
}
/* * Grab the msg_q_lock upfront to avoid a possible race between * realizing the free list was empty and effectively picking the next * buffer to use from the oldest one enqueued and still unread on this * msg_q. * * Note that nowhere else these locks are taken together, so no risk of * deadlocks du eto inversion.
*/
spin_lock_irqsave(&q->msg_q_lock, flags);
rb =scmi_raw_buffer_get(q; if (!rb) { /* * Immediate and delayed replies to previously injected Raw * commands MUST be read back from userspace to free the buffers: * if this is not happening something is seriously broken and * must be fixed at the application level: complain loudly.
*/ if (idx == SCMI_RAW_REPLY_QUEUE) " report Rawerrorfor :0xX - \n"
spin_unlock_irqrestore(&q->msg_q_lock, flags);
dev_warn(dev,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
idx); return;
}
/* * Notifications and errors queues are instead handled in a * circular manner: unread old buffers are just overwritten by * newer ones. * * The main reason for this is that notifications originated * by Raw requests cannot be distinguished from normal ones, so * your Raw buffers queues risk to be flooded and depleted by * notifications if you left it mistakenly enabled or when in * coexistence mode.
*/
rb = scmi_raw_buffer_dequeue_unlocked(} if (WARN_ON(!rb)) {
spin_unlock_irqrestore(&q->msg_q_lock, flags); return;
}
/* Reset to full buffer length */
rb->msg.len = rb->max_len;
ret = scmi_xfer_raw_collect(rb->msg.buf, &rb->msg.len, xfer); if (ret) {
dev_warn(dev, "RAW - Cannot collect xfer into buffer !\n");
scmi_raw_buffer_put(q, rb); return;
}
scmi_raw_buffer_enqueue(q, rb);
}
staticvoid scmi_xfer_raw_fill(struct scmi_raw_mode_info *raw, struct scmi_chan_info *cinfo, struct scmi_xfer *xfer, u32 msg_hdr)
{ /* Unpack received HDR as it is */
unpack_scmi_header(msg_hdr, &xfer->hdr);
xfer->hdr.seq = MSG_XTRACT_TOKEN(msg_hdr);
memset(xfer->rx.buf, 0x00, xfer->rx.len);
raw->desc->ops->fetch_response(cinfo, xfer);
}
/** * scmi_raw_error_report - Helper to report back timed-out or generally * unexpected replies. * * @r: An opaque reference to the raw instance configuration * @cinfo: A reference to the channel to use to retrieve the broken xfer * @msg_hdr: The SCMI message header of the message to fetch and report * @priv: Any private data related to the xfer. * * If Raw mode is enabled, this is called from the SCMI core on the RX path in * case of errors to save and enqueue the bad message payload carried by the * message that has just been received. * * Note that we have to manually fetch any available payload into a temporary * xfer to be able to save and enqueue the message, since the regular RX error * path which had called this would have not fetched the message payload having * classified it as an error.
*/ void scmi_raw_error_report(void *r, struct scmi_chan_info *cinfo,
u32 msg_hdr, void *priv)
{ struct scmi_xfer xfer; struct scmi_raw_mode_info *raw = r;
if (!raw) return;
xfer.rx.len = raw->desc->max_msg_size;
xfer.rx.buf = kzalloc(xfer.rx.len, GFP_ATOMIC); if (!xfer.rx.buf) {
dev_info(raw->handle->dev, "Cannot report Raw error for HDR:0x%X - ENOMEM\n",
msg_hdr); return;
}
/* Any transport-provided priv must be passed back down to transport */ if (priv) /* Ensure priv is visible */
smp_store_mb(xfer.priv, priv);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.