[PATCH v2 0/4] firmware: cs_dsp: Some small coding improvements
Commit series that makes some small improvements to code and the kernel log messages.
--- Changes since V1: - Replaced commit #3 with one that keeps the wmfw format version message on its own line instead of merging it into the INFO text message. - Commit #4 rebased onto the new #3
Richard Fitzgerald (4): firmware: cs_dsp: Don't allocate temporary buffer for info text firmware: cs_dsp: Make wmfw and bin filename arguments const char * firmware: cs_dsp: Clarify wmfw format version log message firmware: cs_dsp: Rename fw_ver to wmfw_ver
drivers/firmware/cirrus/cs_dsp.c | 68 +++++++++----------------- include/linux/firmware/cirrus/cs_dsp.h | 10 ++-- sound/soc/codecs/wm_adsp.c | 2 +- 3 files changed, 29 insertions(+), 51 deletions(-)
Don't allocate a temporary buffer to hold a NUL-terminated copy of the NAME/INFO string from the wmfw/bin. It can be printed directly to the log. Also limit the maximum number of characters that will be logged from this string.
The NAME/INFO blocks in the firmware files are an array of characters with a length, not a NUL-terminated C string. The original code allocated a temporary buffer to make a NUL-terminated copy of the string and then passed that to dev_info(). There's no need for this: printf formatting can use "%.*s" to print a character array of a given length.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com --- No changes since V1 --- drivers/firmware/cirrus/cs_dsp.c | 35 +++++++------------------------- 1 file changed, 7 insertions(+), 28 deletions(-)
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 89fd63205a6e..bf25107a98ee 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -12,6 +12,7 @@ #include <linux/ctype.h> #include <linux/debugfs.h> #include <linux/delay.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/seq_file.h> @@ -1473,7 +1474,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, const struct wmfw_region *region; const struct cs_dsp_region *mem; const char *region_name; - char *text = NULL; struct cs_dsp_buf *buf; unsigned int reg; int regions = 0; @@ -1545,15 +1545,15 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
region_name = "Unknown"; reg = 0; - text = NULL; offset = le32_to_cpu(region->offset) & 0xffffff; type = be32_to_cpu(region->type) & 0xff;
switch (type) { + case WMFW_INFO_TEXT: case WMFW_NAME_TEXT: - region_name = "Firmware name"; - text = kzalloc(le32_to_cpu(region->len) + 1, - GFP_KERNEL); + region_name = "Info/Name"; + cs_dsp_info(dsp, "%s: %.*s\n", file, + min(le32_to_cpu(region->len), 100), region->data); break; case WMFW_ALGORITHM_DATA: region_name = "Algorithm"; @@ -1561,11 +1561,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, if (ret != 0) goto out_fw; break; - case WMFW_INFO_TEXT: - region_name = "Information"; - text = kzalloc(le32_to_cpu(region->len) + 1, - GFP_KERNEL); - break; case WMFW_ABSOLUTE: region_name = "Absolute"; reg = offset; @@ -1599,13 +1594,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, regions, le32_to_cpu(region->len), offset, region_name);
- if (text) { - memcpy(text, region->data, le32_to_cpu(region->len)); - cs_dsp_info(dsp, "%s: %s\n", file, text); - kfree(text); - text = NULL; - } - if (reg) { buf = cs_dsp_buf_alloc(region->data, le32_to_cpu(region->len), @@ -1647,7 +1635,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, out_fw: regmap_async_complete(regmap); cs_dsp_buf_free(&buf_list); - kfree(text);
if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2180,7 +2167,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware struct cs_dsp_alg_region *alg_region; const char *region_name; int ret, pos, blocks, type, offset, reg, version; - char *text = NULL; struct cs_dsp_buf *buf;
if (!firmware) @@ -2249,7 +2235,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware region_name = "Unknown"; switch (type) { case (WMFW_NAME_TEXT << 8): - text = kzalloc(le32_to_cpu(blk->len) + 1, GFP_KERNEL); + cs_dsp_info(dsp, "%s: %.*s\n", dsp->fw_name, + min(le32_to_cpu(blk->len), 100), blk->data); break; case (WMFW_INFO_TEXT << 8): case (WMFW_METADATA << 8): @@ -2321,13 +2308,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware break; }
- if (text) { - memcpy(text, blk->data, le32_to_cpu(blk->len)); - cs_dsp_info(dsp, "%s: %s\n", dsp->fw_name, text); - kfree(text); - text = NULL; - } - if (reg) { buf = cs_dsp_buf_alloc(blk->data, le32_to_cpu(blk->len), @@ -2367,7 +2347,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware out_fw: regmap_async_complete(regmap); cs_dsp_buf_free(&buf_list); - kfree(text);
if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file);
The wmfw_filename and bin_filename strings passed into cs_dsp_power_up() and cs_dsp_adsp1_power_up() should be const char *.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com --- No changes since V1 --- drivers/firmware/cirrus/cs_dsp.c | 8 ++++---- include/linux/firmware/cirrus/cs_dsp.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index bf25107a98ee..1bc2e0b6d40b 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -2413,8 +2413,8 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_init, FW_CS_DSP); * Return: Zero for success, a negative number on error. */ int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, + const struct firmware *wmfw_firmware, const char *wmfw_filename, + const struct firmware *coeff_firmware, const char *coeff_filename, const char *fw_name) { unsigned int val; @@ -2707,8 +2707,8 @@ static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) * Return: Zero for success, a negative number on error. */ int cs_dsp_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, + const struct firmware *wmfw_firmware, const char *wmfw_filename, + const struct firmware *coeff_firmware, const char *coeff_filename, const char *fw_name) { int ret; diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 82687e07a7c2..8078dc377948 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -213,13 +213,13 @@ int cs_dsp_adsp2_init(struct cs_dsp *dsp); int cs_dsp_halo_init(struct cs_dsp *dsp);
int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, + const struct firmware *wmfw_firmware, const char *wmfw_filename, + const struct firmware *coeff_firmware, const char *coeff_filename, const char *fw_name); void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); int cs_dsp_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, + const struct firmware *wmfw_firmware, const char *wmfw_filename, + const struct firmware *coeff_firmware, const char *coeff_filename, const char *fw_name); void cs_dsp_power_down(struct cs_dsp *dsp); int cs_dsp_run(struct cs_dsp *dsp);
Change the log message of the wmfw format version to include the file name, and change the message to say "format" instead of "Firmware version". Merge this with the message that logs the timestamp.
The wmfw format version is information that is useful to have logged because the behaviour of firmware controls depends on the wmfw format. So "unexpected" behaviour could be caused by having expectations based on one format of wmfw when a different format has been loaded.
But the original message was confusing. It reported the file format version but didn't actually log the name of the file it referred to. It also called it "Firmware version", which is confusing when a later message also logs a firmware version that is the version of the actual firmware within the wmfw.
The logging of the firmware timestamp has been merged into this. That was originally a dbg-only message, but as we are already logging a line of info, we might as well add a few extra characters to log the timestamp. The timestamp is now logged in hexadecimal - it's not particularly useful as a decimal value.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com --- Changes since V1: This is a completely different commit from the original V1 #3. The V1 commit merged the wmfw format version message into the INFO_TEXT message. The V2 commit keeps the wmfw format in its own message but clarifies the message, and merges it with a trivial message that logged the header timestamp. --- drivers/firmware/cirrus/cs_dsp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 1bc2e0b6d40b..cce81a3f68f9 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -1502,7 +1502,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, goto out_fw; }
- cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); dsp->fw_ver = header->ver;
if (header->core != dsp->type) { @@ -1526,8 +1525,8 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, goto out_fw; }
- cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, - le64_to_cpu(footer->timestamp)); + cs_dsp_info(dsp, "%s: format %d timestamp %#llx\n", file, header->ver, + le64_to_cpu(footer->timestamp));
while (pos < firmware->size) { /* Is there enough data for a complete block header? */
Rename the confusingly named struct member fw_ver to wmfw_ver. It contains the wmfw format version of the loaded wmfw file.
This commit also contains an update to wm_adsp for the new name.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com --- Changes since V1: Rebased onto the new commit #3. This removes a single-line change from this commit. The rest of this commit is the same as V1. --- drivers/firmware/cirrus/cs_dsp.c | 20 ++++++++++---------- include/linux/firmware/cirrus/cs_dsp.h | 2 +- sound/soc/codecs/wm_adsp.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index cce81a3f68f9..a7b56eff086f 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -1051,7 +1051,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp,
ctl->fw_name = dsp->fw_name; ctl->alg_region = *alg_region; - if (subname && dsp->fw_ver >= 2) { + if (subname && dsp->wmfw_ver >= 2) { ctl->subname_len = subname_len; ctl->subname = kasprintf(GFP_KERNEL, "%.*s", subname_len, subname); if (!ctl->subname) { @@ -1178,7 +1178,7 @@ static int cs_dsp_coeff_parse_alg(struct cs_dsp *dsp,
raw = (const struct wmfw_adsp_alg_data *)region->data;
- switch (dsp->fw_ver) { + switch (dsp->wmfw_ver) { case 0: case 1: if (sizeof(*raw) > data_len) @@ -1255,7 +1255,7 @@ static int cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, blk->offset = le16_to_cpu(raw->hdr.offset); blk->mem_type = le16_to_cpu(raw->hdr.type);
- switch (dsp->fw_ver) { + switch (dsp->wmfw_ver) { case 0: case 1: if (sizeof(*raw) > (data_len - pos)) @@ -1502,7 +1502,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, goto out_fw; }
- dsp->fw_ver = header->ver; + dsp->wmfw_ver = header->ver;
if (header->core != dsp->type) { cs_dsp_err(dsp, "%s: invalid core %d != %d\n", @@ -1782,7 +1782,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp,
list_add_tail(&alg_region->list, &dsp->alg_regions);
- if (dsp->fw_ver > 0) + if (dsp->wmfw_ver > 0) cs_dsp_ctl_fixup_base(dsp, alg_region);
return alg_region; @@ -1905,7 +1905,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) ret = PTR_ERR(alg_region); goto out; } - if (dsp->fw_ver == 0) { + if (dsp->wmfw_ver == 0) { if (i + 1 < n_algs) { len = be32_to_cpu(adsp1_alg[i + 1].dm); len -= be32_to_cpu(adsp1_alg[i].dm); @@ -1927,7 +1927,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) ret = PTR_ERR(alg_region); goto out; } - if (dsp->fw_ver == 0) { + if (dsp->wmfw_ver == 0) { if (i + 1 < n_algs) { len = be32_to_cpu(adsp1_alg[i + 1].zm); len -= be32_to_cpu(adsp1_alg[i].zm); @@ -2018,7 +2018,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) ret = PTR_ERR(alg_region); goto out; } - if (dsp->fw_ver == 0) { + if (dsp->wmfw_ver == 0) { if (i + 1 < n_algs) { len = be32_to_cpu(adsp2_alg[i + 1].xm); len -= be32_to_cpu(adsp2_alg[i].xm); @@ -2040,7 +2040,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) ret = PTR_ERR(alg_region); goto out; } - if (dsp->fw_ver == 0) { + if (dsp->wmfw_ver == 0) { if (i + 1 < n_algs) { len = be32_to_cpu(adsp2_alg[i + 1].ym); len -= be32_to_cpu(adsp2_alg[i].ym); @@ -2062,7 +2062,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) ret = PTR_ERR(alg_region); goto out; } - if (dsp->fw_ver == 0) { + if (dsp->wmfw_ver == 0) { if (i + 1 < n_algs) { len = be32_to_cpu(adsp2_alg[i + 1].zm); len -= be32_to_cpu(adsp2_alg[i].zm); diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index 8078dc377948..2e649810169f 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -167,7 +167,7 @@ struct cs_dsp { const struct cs_dsp_region *mem; int num_mems;
- int fw_ver; + int wmfw_ver;
bool booted; bool running; diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 68d2d6444533..9f8549b34e30 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -601,7 +601,7 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) return -EINVAL; }
- switch (cs_dsp->fw_ver) { + switch (cs_dsp->wmfw_ver) { case 0: case 1: ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
On Wed, Jul 10, 2024 at 11:36:36AM +0100, Richard Fitzgerald wrote:
Commit series that makes some small improvements to code and the kernel log messages.
Reviewed-by: Charles Keepax ckeepax@opensource.cirrus.com
Thanks, Charles
On Wed, 10 Jul 2024 11:36:36 +0100, Richard Fitzgerald wrote:
Commit series that makes some small improvements to code and the kernel log messages.
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] firmware: cs_dsp: Don't allocate temporary buffer for info text commit: bff92858dfb9897e4c06c11aab0322e1aab822f7 [2/4] firmware: cs_dsp: Make wmfw and bin filename arguments const char * commit: 584e86e14c59d36688633002613792923620d8c0 [3/4] firmware: cs_dsp: Clarify wmfw format version log message commit: a4939119055d5c97aff2cea040f1af8c4606bfa1 [4/4] firmware: cs_dsp: Rename fw_ver to wmfw_ver commit: dc0e5ca8856dc6a97e3b117879dfb2b52bda06b6
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (3)
-
Charles Keepax
-
Mark Brown
-
Richard Fitzgerald