debug.c (cac0b0887e5304bddfda91a4a7106f9328c31318) | debug.c (3dc0d709177828a22dfc9d0072e3ac937ef90d06) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> --- 5 unchanged lines hidden (view full) --- 14#include <linux/debugfs.h> 15#include <linux/io.h> 16#include <linux/pm_runtime.h> 17#include <sound/sof/ext_manifest.h> 18#include <sound/sof/debug.h> 19#include "sof-priv.h" 20#include "ops.h" 21 | 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> --- 5 unchanged lines hidden (view full) --- 14#include <linux/debugfs.h> 15#include <linux/io.h> 16#include <linux/pm_runtime.h> 17#include <sound/sof/ext_manifest.h> 18#include <sound/sof/debug.h> 19#include "sof-priv.h" 20#include "ops.h" 21 |
22#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 23#include "sof-probes.h" 24 25/** 26 * strsplit_u32 - Split string into sequence of u32 tokens 27 * @buf: String to split into tokens. 28 * @delim: String containing delimiter characters. 29 * @tkns: Returned u32 sequence pointer. 30 * @num_tkns: Returned number of tokens obtained. 31 */ 32static int 33strsplit_u32(char **buf, const char *delim, u32 **tkns, size_t *num_tkns) 34{ 35 char *s; 36 u32 *data, *tmp; 37 size_t count = 0; 38 size_t cap = 32; 39 int ret = 0; 40 41 *tkns = NULL; 42 *num_tkns = 0; 43 data = kcalloc(cap, sizeof(*data), GFP_KERNEL); 44 if (!data) 45 return -ENOMEM; 46 47 while ((s = strsep(buf, delim)) != NULL) { 48 ret = kstrtouint(s, 0, data + count); 49 if (ret) 50 goto exit; 51 if (++count >= cap) { 52 cap *= 2; 53 tmp = krealloc(data, cap * sizeof(*data), GFP_KERNEL); 54 if (!tmp) { 55 ret = -ENOMEM; 56 goto exit; 57 } 58 data = tmp; 59 } 60 } 61 62 if (!count) 63 goto exit; 64 *tkns = kmemdup(data, count * sizeof(*data), GFP_KERNEL); 65 if (*tkns == NULL) { 66 ret = -ENOMEM; 67 goto exit; 68 } 69 *num_tkns = count; 70 71exit: 72 kfree(data); 73 return ret; 74} 75 76static int tokenize_input(const char __user *from, size_t count, 77 loff_t *ppos, u32 **tkns, size_t *num_tkns) 78{ 79 char *buf; 80 int ret; 81 82 buf = kmalloc(count + 1, GFP_KERNEL); 83 if (!buf) 84 return -ENOMEM; 85 86 ret = simple_write_to_buffer(buf, count, ppos, from, count); 87 if (ret != count) { 88 ret = ret >= 0 ? -EIO : ret; 89 goto exit; 90 } 91 92 buf[count] = '\0'; 93 ret = strsplit_u32((char **)&buf, ",", tkns, num_tkns); 94exit: 95 kfree(buf); 96 return ret; 97} 98 99static ssize_t probe_points_read(struct file *file, 100 char __user *to, size_t count, loff_t *ppos) 101{ 102 struct snd_sof_dfsentry *dfse = file->private_data; 103 struct snd_sof_dev *sdev = dfse->sdev; 104 struct sof_probe_point_desc *desc; 105 size_t num_desc, len = 0; 106 char *buf; 107 int i, ret; 108 109 if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 110 dev_warn(sdev->dev, "no extractor stream running\n"); 111 return -ENOENT; 112 } 113 114 buf = kzalloc(PAGE_SIZE, GFP_KERNEL); 115 if (!buf) 116 return -ENOMEM; 117 118 ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc); 119 if (ret < 0) 120 goto exit; 121 122 for (i = 0; i < num_desc; i++) { 123 ret = snprintf(buf + len, PAGE_SIZE - len, 124 "Id: %#010x Purpose: %d Node id: %#x\n", 125 desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); 126 if (ret < 0) 127 goto free_desc; 128 len += ret; 129 } 130 131 ret = simple_read_from_buffer(to, count, ppos, buf, len); 132free_desc: 133 kfree(desc); 134exit: 135 kfree(buf); 136 return ret; 137} 138 139static ssize_t probe_points_write(struct file *file, 140 const char __user *from, size_t count, loff_t *ppos) 141{ 142 struct snd_sof_dfsentry *dfse = file->private_data; 143 struct snd_sof_dev *sdev = dfse->sdev; 144 struct sof_probe_point_desc *desc; 145 size_t num_tkns, bytes; 146 u32 *tkns; 147 int ret; 148 149 if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 150 dev_warn(sdev->dev, "no extractor stream running\n"); 151 return -ENOENT; 152 } 153 154 ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); 155 if (ret < 0) 156 return ret; 157 bytes = sizeof(*tkns) * num_tkns; 158 if (!num_tkns || (bytes % sizeof(*desc))) { 159 ret = -EINVAL; 160 goto exit; 161 } 162 163 desc = (struct sof_probe_point_desc *)tkns; 164 ret = sof_ipc_probe_points_add(sdev, 165 desc, bytes / sizeof(*desc)); 166 if (!ret) 167 ret = count; 168exit: 169 kfree(tkns); 170 return ret; 171} 172 173static const struct file_operations probe_points_fops = { 174 .open = simple_open, 175 .read = probe_points_read, 176 .write = probe_points_write, 177 .llseek = default_llseek, 178}; 179 180static ssize_t probe_points_remove_write(struct file *file, 181 const char __user *from, size_t count, loff_t *ppos) 182{ 183 struct snd_sof_dfsentry *dfse = file->private_data; 184 struct snd_sof_dev *sdev = dfse->sdev; 185 size_t num_tkns; 186 u32 *tkns; 187 int ret; 188 189 if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 190 dev_warn(sdev->dev, "no extractor stream running\n"); 191 return -ENOENT; 192 } 193 194 ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); 195 if (ret < 0) 196 return ret; 197 if (!num_tkns) { 198 ret = -EINVAL; 199 goto exit; 200 } 201 202 ret = sof_ipc_probe_points_remove(sdev, tkns, num_tkns); 203 if (!ret) 204 ret = count; 205exit: 206 kfree(tkns); 207 return ret; 208} 209 210static const struct file_operations probe_points_remove_fops = { 211 .open = simple_open, 212 .write = probe_points_remove_write, 213 .llseek = default_llseek, 214}; 215 216static int snd_sof_debugfs_probe_item(struct snd_sof_dev *sdev, 217 const char *name, mode_t mode, 218 const struct file_operations *fops) 219{ 220 struct snd_sof_dfsentry *dfse; 221 222 dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); 223 if (!dfse) 224 return -ENOMEM; 225 226 dfse->type = SOF_DFSENTRY_TYPE_BUF; 227 dfse->sdev = sdev; 228 229 debugfs_create_file(name, mode, sdev->debugfs_root, dfse, fops); 230 /* add to dfsentry list */ 231 list_add(&dfse->list, &sdev->dfsentry_list); 232 233 return 0; 234} 235#endif 236 | |
237static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer, 238 size_t count, loff_t *ppos) 239{ 240 size_t size; 241 char *string; 242 int ret; 243 244 string = kzalloc(count+1, GFP_KERNEL); --- 319 unchanged lines hidden (view full) --- 564 err = snd_sof_debugfs_io_item(sdev, sdev->bar[map->bar] + 565 map->offset, map->size, 566 map->name, map->access_type); 567 /* errors are only due to memory allocation, not debugfs */ 568 if (err < 0) 569 return err; 570 } 571 | 22static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer, 23 size_t count, loff_t *ppos) 24{ 25 size_t size; 26 char *string; 27 int ret; 28 29 string = kzalloc(count+1, GFP_KERNEL); --- 319 unchanged lines hidden (view full) --- 349 err = snd_sof_debugfs_io_item(sdev, sdev->bar[map->bar] + 350 map->offset, map->size, 351 map->name, map->access_type); 352 /* errors are only due to memory allocation, not debugfs */ 353 if (err < 0) 354 return err; 355 } 356 |
572#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 573 err = snd_sof_debugfs_probe_item(sdev, "probe_points", 574 0644, &probe_points_fops); 575 if (err < 0) 576 return err; 577 err = snd_sof_debugfs_probe_item(sdev, "probe_points_remove", 578 0200, &probe_points_remove_fops); 579 if (err < 0) 580 return err; 581#endif 582 | |
583 return 0; 584} 585EXPORT_SYMBOL_GPL(snd_sof_dbg_init); 586 587void snd_sof_free_debug(struct snd_sof_dev *sdev) 588{ 589 debugfs_remove_recursive(sdev->debugfs_root); 590} --- 85 unchanged lines hidden --- | 357 return 0; 358} 359EXPORT_SYMBOL_GPL(snd_sof_dbg_init); 360 361void snd_sof_free_debug(struct snd_sof_dev *sdev) 362{ 363 debugfs_remove_recursive(sdev->debugfs_root); 364} --- 85 unchanged lines hidden --- |