From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Cristian Marussi <cristian.marussi@arm.com>
Cc: james.quinlan@broadcom.com, lukasz.luba@arm.com,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, sudeep.holla@arm.com
Subject: Re: [RFC PATCH 03/11] firmware: arm_scmi: Add support for notifications message processing
Date: Mon, 27 Jan 2020 17:32:32 +0000 [thread overview]
Message-ID: <20200127173232.000045ac@Huawei.com> (raw)
In-Reply-To: <20200120122333.46217-4-cristian.marussi@arm.com>
On Mon, 20 Jan 2020 12:23:25 +0000
Cristian Marussi <cristian.marussi@arm.com> wrote:
> From: Sudeep Holla <sudeep.holla@arm.com>
>
> Add the mechanisms to distinguish notifications from delayed responses and
> to properly fetch notification messages upon reception: notifications
> processing does not continue further after the fetch phase.
>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Couple of bits that seem more interesting than expected inline...
> ---
> drivers/firmware/arm_scmi/driver.c | 92 +++++++++++++++++++++---------
> 1 file changed, 65 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 9611e8037d77..28ed1f0cb417 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -212,6 +212,15 @@ static void scmi_fetch_response(struct scmi_xfer *xfer,
> memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
> }
>
> +static void scmi_fetch_notification(struct scmi_xfer *xfer, size_t max_len,
> + struct scmi_shared_mem __iomem *mem)
> +{
> + /* Skip only length of header in payload area i.e 4 bytes */
> + xfer->rx.len = min_t(size_t, max_len, ioread32(&mem->length) - 4);
> +
> + memcpy_fromio(xfer->rx.buf, mem->msg_payload, xfer->rx.len);
> +}
> +
> /**
> * pack_scmi_header() - packs and returns 32-bit header
> *
> @@ -339,6 +348,58 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
> spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> }
>
> +static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
> +{
> + struct scmi_xfer *xfer;
> + struct device *dev = cinfo->dev;
> + struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> + struct scmi_xfers_info *minfo = &info->rx_minfo;
> + struct scmi_shared_mem __iomem *mem = cinfo->payload;
> +
> + xfer = scmi_xfer_get(cinfo->handle, minfo);
> + if (IS_ERR(xfer)) {
> + dev_err(dev, "failed to get free message slot (%ld)\n",
> + PTR_ERR(xfer));
> + iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE,
> + &mem->channel_status);
> + return;
> + }
> +
> + unpack_scmi_header(msg_hdr, &xfer->hdr);
> + scmi_dump_header_dbg(dev, &xfer->hdr);
> + scmi_fetch_notification(xfer, info->desc->max_msg_size, mem);
> + __scmi_xfer_put(minfo, xfer);
> +
> + iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE, &mem->channel_status);
> +}
> +
> +static void scmi_handle_xfer_delayed_resp(struct scmi_chan_info *cinfo,
> + u16 xfer_id, bool delayed_resp)
Hmm. A function called *_delayed_resp that takes a boolean to say if
it is a delayed_resp is in the category of non obvious.... Needs a rename
at the very least.
> +{
> + struct scmi_xfer *xfer;
> + struct device *dev = cinfo->dev;
> + struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> + struct scmi_xfers_info *minfo = &info->tx_minfo;
> + struct scmi_shared_mem __iomem *mem = cinfo->payload;
> +
> + /* Are we even expecting this? */
> + if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
> + dev_err(dev, "message for %d is not expected!\n", xfer_id);
> + return;
> + }
> +
> + xfer = &minfo->xfer_block[xfer_id];
> +
> + scmi_dump_header_dbg(dev, &xfer->hdr);
> +
> + scmi_fetch_response(xfer, mem);
> +
> + if (delayed_resp)
> + complete(xfer->async_done);
> + else
> + complete(&xfer->done);
> +}
> +
> /**
> * scmi_rx_callback() - mailbox client callback for receive messages
> *
> @@ -355,41 +416,18 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m)
> {
> u8 msg_type;
> u32 msg_hdr;
> - u16 xfer_id;
> - struct scmi_xfer *xfer;
> struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
> - struct device *dev = cinfo->dev;
> - struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> - struct scmi_xfers_info *minfo = &info->tx_minfo;
> struct scmi_shared_mem __iomem *mem = cinfo->payload;
>
> msg_hdr = ioread32(&mem->msg_header);
> msg_type = MSG_XTRACT_TYPE(msg_hdr);
> - xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
>
> if (msg_type == MSG_TYPE_NOTIFICATION)
> - return; /* Notifications not yet supported */
> -
> - /* Are we even expecting this? */
> - if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
> - dev_err(dev, "message for %d is not expected!\n", xfer_id);
> - return;
> - }
> -
> - xfer = &minfo->xfer_block[xfer_id];
> -
> - scmi_dump_header_dbg(dev, &xfer->hdr);
> -
> - scmi_fetch_response(xfer, mem);
> -
> - trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
> - xfer->hdr.protocol_id, xfer->hdr.seq,
> - msg_type);
> -
> - if (msg_type == MSG_TYPE_DELAYED_RESP)
> - complete(xfer->async_done);
> + scmi_handle_notification(cinfo, msg_hdr);
> else
> - complete(&xfer->done);
> + scmi_handle_xfer_delayed_resp(cinfo, MSG_XTRACT_TOKEN(msg_hdr),
> + msg_type);
First I wondered why this wasn't a switch which would make a clear distinction
between notification path and delayed response...
However, it seems delayed_resp path also handles other values of msg_type,
though only 0 which is a command I think...
Passing a enum that I think can take 4 values, only 3 of which are defined
into a function as a boolean is 'interesting'. Don't do that.
> +
> }
>
> /**
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Cristian Marussi <cristian.marussi@arm.com>
Cc: <linux-kernel@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<james.quinlan@broadcom.com>, <lukasz.luba@arm.com>,
<sudeep.holla@arm.com>
Subject: Re: [RFC PATCH 03/11] firmware: arm_scmi: Add support for notifications message processing
Date: Mon, 27 Jan 2020 17:32:32 +0000 [thread overview]
Message-ID: <20200127173232.000045ac@Huawei.com> (raw)
In-Reply-To: <20200120122333.46217-4-cristian.marussi@arm.com>
On Mon, 20 Jan 2020 12:23:25 +0000
Cristian Marussi <cristian.marussi@arm.com> wrote:
> From: Sudeep Holla <sudeep.holla@arm.com>
>
> Add the mechanisms to distinguish notifications from delayed responses and
> to properly fetch notification messages upon reception: notifications
> processing does not continue further after the fetch phase.
>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Couple of bits that seem more interesting than expected inline...
> ---
> drivers/firmware/arm_scmi/driver.c | 92 +++++++++++++++++++++---------
> 1 file changed, 65 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 9611e8037d77..28ed1f0cb417 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -212,6 +212,15 @@ static void scmi_fetch_response(struct scmi_xfer *xfer,
> memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len);
> }
>
> +static void scmi_fetch_notification(struct scmi_xfer *xfer, size_t max_len,
> + struct scmi_shared_mem __iomem *mem)
> +{
> + /* Skip only length of header in payload area i.e 4 bytes */
> + xfer->rx.len = min_t(size_t, max_len, ioread32(&mem->length) - 4);
> +
> + memcpy_fromio(xfer->rx.buf, mem->msg_payload, xfer->rx.len);
> +}
> +
> /**
> * pack_scmi_header() - packs and returns 32-bit header
> *
> @@ -339,6 +348,58 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
> spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> }
>
> +static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
> +{
> + struct scmi_xfer *xfer;
> + struct device *dev = cinfo->dev;
> + struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> + struct scmi_xfers_info *minfo = &info->rx_minfo;
> + struct scmi_shared_mem __iomem *mem = cinfo->payload;
> +
> + xfer = scmi_xfer_get(cinfo->handle, minfo);
> + if (IS_ERR(xfer)) {
> + dev_err(dev, "failed to get free message slot (%ld)\n",
> + PTR_ERR(xfer));
> + iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE,
> + &mem->channel_status);
> + return;
> + }
> +
> + unpack_scmi_header(msg_hdr, &xfer->hdr);
> + scmi_dump_header_dbg(dev, &xfer->hdr);
> + scmi_fetch_notification(xfer, info->desc->max_msg_size, mem);
> + __scmi_xfer_put(minfo, xfer);
> +
> + iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE, &mem->channel_status);
> +}
> +
> +static void scmi_handle_xfer_delayed_resp(struct scmi_chan_info *cinfo,
> + u16 xfer_id, bool delayed_resp)
Hmm. A function called *_delayed_resp that takes a boolean to say if
it is a delayed_resp is in the category of non obvious.... Needs a rename
at the very least.
> +{
> + struct scmi_xfer *xfer;
> + struct device *dev = cinfo->dev;
> + struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> + struct scmi_xfers_info *minfo = &info->tx_minfo;
> + struct scmi_shared_mem __iomem *mem = cinfo->payload;
> +
> + /* Are we even expecting this? */
> + if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
> + dev_err(dev, "message for %d is not expected!\n", xfer_id);
> + return;
> + }
> +
> + xfer = &minfo->xfer_block[xfer_id];
> +
> + scmi_dump_header_dbg(dev, &xfer->hdr);
> +
> + scmi_fetch_response(xfer, mem);
> +
> + if (delayed_resp)
> + complete(xfer->async_done);
> + else
> + complete(&xfer->done);
> +}
> +
> /**
> * scmi_rx_callback() - mailbox client callback for receive messages
> *
> @@ -355,41 +416,18 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m)
> {
> u8 msg_type;
> u32 msg_hdr;
> - u16 xfer_id;
> - struct scmi_xfer *xfer;
> struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
> - struct device *dev = cinfo->dev;
> - struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> - struct scmi_xfers_info *minfo = &info->tx_minfo;
> struct scmi_shared_mem __iomem *mem = cinfo->payload;
>
> msg_hdr = ioread32(&mem->msg_header);
> msg_type = MSG_XTRACT_TYPE(msg_hdr);
> - xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
>
> if (msg_type == MSG_TYPE_NOTIFICATION)
> - return; /* Notifications not yet supported */
> -
> - /* Are we even expecting this? */
> - if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
> - dev_err(dev, "message for %d is not expected!\n", xfer_id);
> - return;
> - }
> -
> - xfer = &minfo->xfer_block[xfer_id];
> -
> - scmi_dump_header_dbg(dev, &xfer->hdr);
> -
> - scmi_fetch_response(xfer, mem);
> -
> - trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
> - xfer->hdr.protocol_id, xfer->hdr.seq,
> - msg_type);
> -
> - if (msg_type == MSG_TYPE_DELAYED_RESP)
> - complete(xfer->async_done);
> + scmi_handle_notification(cinfo, msg_hdr);
> else
> - complete(&xfer->done);
> + scmi_handle_xfer_delayed_resp(cinfo, MSG_XTRACT_TOKEN(msg_hdr),
> + msg_type);
First I wondered why this wasn't a switch which would make a clear distinction
between notification path and delayed response...
However, it seems delayed_resp path also handles other values of msg_type,
though only 0 which is a command I think...
Passing a enum that I think can take 4 values, only 3 of which are defined
into a function as a boolean is 'interesting'. Don't do that.
> +
> }
>
> /**
next prev parent reply other threads:[~2020-01-27 17:32 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-20 12:23 [RFC PATCH 00/11] SCMI Notifications Support Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 01/11] firmware: arm_scmi: Add receive buffer support for notifications Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-27 17:07 ` Jonathan Cameron
2020-01-27 17:07 ` Jonathan Cameron
2020-02-14 15:25 ` Cristian Marussi
2020-02-14 15:25 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 02/11] firmware: arm_scmi: Update protocol commands and notification list Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 03/11] firmware: arm_scmi: Add support for notifications message processing Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
[not found] ` <4c59008e-6010-fb98-d7bf-8677454d1e4f@broadcom.com>
2020-01-23 10:58 ` Cristian Marussi
2020-01-23 10:58 ` Cristian Marussi
2020-01-27 17:32 ` Jonathan Cameron [this message]
2020-01-27 17:32 ` Jonathan Cameron
2020-02-14 15:28 ` Cristian Marussi
2020-02-14 15:28 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 04/11] firmware: arm_scmi: Add core notifications support Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-21 17:43 ` Cristian Marussi
2020-01-21 17:43 ` Cristian Marussi
2020-01-27 18:11 ` Jonathan Cameron
2020-01-27 18:11 ` Jonathan Cameron
2020-01-27 18:52 ` Cristian Marussi
2020-01-27 18:52 ` Cristian Marussi
2020-02-14 15:32 ` Cristian Marussi
2020-02-14 15:32 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 05/11] firmware: arm_scmi: Add notifications anti-tampering Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 06/11] firmware: arm_scmi: Enable core notifications Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 07/11] firmware: arm_scmi: Add Power notifications support Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 08/11] firmware: arm_scmi: Add Perf " Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 09/11] firmware: arm_scmi: Add Sensor " Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 10/11] firmware: arm_scmi: Add Reset " Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-20 12:23 ` [RFC PATCH 11/11] firmware: arm_scmi: Add Base " Cristian Marussi
2020-01-20 12:23 ` Cristian Marussi
2020-01-23 11:02 ` [RFC PATCH 00/11] SCMI Notifications Support Cristian Marussi
2020-01-23 11:02 ` Cristian Marussi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200127173232.000045ac@Huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=cristian.marussi@arm.com \
--cc=james.quinlan@broadcom.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lukasz.luba@arm.com \
--cc=sudeep.holla@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.