|
19 | 19 | #include"sof-priv.h" |
20 | 20 | #include"ops.h" |
21 | 21 |
|
22 | | -#ifIS_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 | | - */ |
32 | | -staticint |
33 | | -strsplit_u32(char**buf, constchar*delim, u32**tkns, size_t*num_tkns) |
34 | | -{ |
35 | | -char*s; |
36 | | -u32*data, *tmp; |
37 | | -size_tcount=0; |
38 | | -size_tcap=32; |
39 | | -intret=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 | | - |
71 | | -exit: |
72 | | -kfree(data); |
73 | | -returnret; |
74 | | -} |
75 | | - |
76 | | -staticinttokenize_input(constchar__user*from, size_tcount, |
77 | | -loff_t*ppos, u32**tkns, size_t*num_tkns) |
78 | | -{ |
79 | | -char*buf; |
80 | | -intret; |
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); |
94 | | -exit: |
95 | | -kfree(buf); |
96 | | -returnret; |
97 | | -} |
98 | | - |
99 | | -staticssize_tprobe_points_read(structfile*file, |
100 | | -char__user*to, size_tcount, loff_t*ppos) |
101 | | -{ |
102 | | -structsnd_sof_dfsentry*dfse=file->private_data; |
103 | | -structsnd_sof_dev*sdev=dfse->sdev; |
104 | | -structsof_probe_point_desc*desc; |
105 | | -size_tnum_desc, len=0; |
106 | | -char*buf; |
107 | | -inti, 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); |
132 | | -free_desc: |
133 | | -kfree(desc); |
134 | | -exit: |
135 | | -kfree(buf); |
136 | | -returnret; |
137 | | -} |
138 | | - |
139 | | -staticssize_tprobe_points_write(structfile*file, |
140 | | -constchar__user*from, size_tcount, loff_t*ppos) |
141 | | -{ |
142 | | -structsnd_sof_dfsentry*dfse=file->private_data; |
143 | | -structsnd_sof_dev*sdev=dfse->sdev; |
144 | | -structsof_probe_point_desc*desc; |
145 | | -size_tnum_tkns, bytes; |
146 | | -u32*tkns; |
147 | | -intret; |
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 | | -returnret; |
157 | | -bytes=sizeof(*tkns) *num_tkns; |
158 | | -if (!num_tkns|| (bytes % sizeof(*desc))) { |
159 | | -ret=-EINVAL; |
160 | | - goto exit; |
161 | | - } |
162 | | - |
163 | | -desc= (structsof_probe_point_desc*)tkns; |
164 | | -ret=sof_ipc_probe_points_add(sdev, |
165 | | -desc, bytes / sizeof(*desc)); |
166 | | -if (!ret) |
167 | | -ret=count; |
168 | | -exit: |
169 | | -kfree(tkns); |
170 | | -returnret; |
171 | | -} |
172 | | - |
173 | | -staticconststructfile_operationsprobe_points_fops= { |
174 | | - .open=simple_open, |
175 | | - .read=probe_points_read, |
176 | | - .write=probe_points_write, |
177 | | - .llseek=default_llseek, |
178 | | -}; |
179 | | - |
180 | | -staticssize_tprobe_points_remove_write(structfile*file, |
181 | | -constchar__user*from, size_tcount, loff_t*ppos) |
182 | | -{ |
183 | | -structsnd_sof_dfsentry*dfse=file->private_data; |
184 | | -structsnd_sof_dev*sdev=dfse->sdev; |
185 | | -size_tnum_tkns; |
186 | | -u32*tkns; |
187 | | -intret; |
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 | | -returnret; |
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; |
205 | | -exit: |
206 | | -kfree(tkns); |
207 | | -returnret; |
208 | | -} |
209 | | - |
210 | | -staticconststructfile_operationsprobe_points_remove_fops= { |
211 | | - .open=simple_open, |
212 | | - .write=probe_points_remove_write, |
213 | | - .llseek=default_llseek, |
214 | | -}; |
215 | | - |
216 | | -staticintsnd_sof_debugfs_probe_item(structsnd_sof_dev*sdev, |
217 | | -constchar*name, mode_tmode, |
218 | | -conststructfile_operations*fops) |
219 | | -{ |
220 | | -structsnd_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 | | -return0; |
234 | | -} |
235 | | -#endif |
236 | | - |
237 | 22 | staticssize_tsof_dfsentry_write(structfile*file, constchar__user*buffer, |
238 | 23 | size_tcount, loff_t*ppos) |
239 | 24 | { |
@@ -569,17 +354,6 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev) |
569 | 354 | returnerr; |
570 | 355 | } |
571 | 356 |
|
572 | | -#ifIS_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 | | -returnerr; |
577 | | -err=snd_sof_debugfs_probe_item(sdev, "probe_points_remove", |
578 | | -0200, &probe_points_remove_fops); |
579 | | -if (err<0) |
580 | | -returnerr; |
581 | | -#endif |
582 | | - |
583 | 357 | return0; |
584 | 358 | } |
585 | 359 | EXPORT_SYMBOL_GPL(snd_sof_dbg_init); |
|
0 commit comments