]> Git Repo - linux.git/blob - drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
Linux 6.14-rc3
[linux.git] / drivers / media / usb / pvrusb2 / pvrusb2-debugifc.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *
4  *  Copyright (C) 2005 Mike Isely <[email protected]>
5  */
6
7 #include <linux/string.h>
8 #include "pvrusb2-debugifc.h"
9 #include "pvrusb2-hdw.h"
10 #include "pvrusb2-debug.h"
11
12
13 static unsigned int debugifc_count_whitespace(const char *buf,
14                                               unsigned int count)
15 {
16         unsigned int scnt;
17         char ch;
18
19         for (scnt = 0; scnt < count; scnt++) {
20                 ch = buf[scnt];
21                 if (ch == ' ') continue;
22                 if (ch == '\t') continue;
23                 if (ch == '\n') continue;
24                 break;
25         }
26         return scnt;
27 }
28
29
30 static unsigned int debugifc_count_nonwhitespace(const char *buf,
31                                                  unsigned int count)
32 {
33         unsigned int scnt;
34         char ch;
35
36         for (scnt = 0; scnt < count; scnt++) {
37                 ch = buf[scnt];
38                 if (ch == ' ') break;
39                 if (ch == '\t') break;
40                 if (ch == '\n') break;
41         }
42         return scnt;
43 }
44
45
46 static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
47                                           const char **wstrPtr,
48                                           unsigned int *wlenPtr)
49 {
50         const char *wptr;
51         unsigned int consume_cnt = 0;
52         unsigned int wlen;
53         unsigned int scnt;
54
55         wptr = NULL;
56         wlen = 0;
57         scnt = debugifc_count_whitespace(buf,count);
58         consume_cnt += scnt; count -= scnt; buf += scnt;
59         if (!count) goto done;
60
61         scnt = debugifc_count_nonwhitespace(buf,count);
62         if (!scnt) goto done;
63         wptr = buf;
64         wlen = scnt;
65         consume_cnt += scnt; count -= scnt; buf += scnt;
66
67  done:
68         *wstrPtr = wptr;
69         *wlenPtr = wlen;
70         return consume_cnt;
71 }
72
73
74 static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
75                                           u32 *num_ptr)
76 {
77         u32 result = 0;
78         int radix = 10;
79         if ((count >= 2) && (buf[0] == '0') &&
80             ((buf[1] == 'x') || (buf[1] == 'X'))) {
81                 radix = 16;
82                 count -= 2;
83                 buf += 2;
84         } else if ((count >= 1) && (buf[0] == '0')) {
85                 radix = 8;
86         }
87
88         while (count--) {
89                 int val = hex_to_bin(*buf++);
90                 if (val < 0 || val >= radix)
91                         return -EINVAL;
92                 result *= radix;
93                 result += val;
94         }
95         *num_ptr = result;
96         return 0;
97 }
98
99
100 static int debugifc_match_keyword(const char *buf,unsigned int count,
101                                   const char *keyword)
102 {
103         unsigned int kl;
104         if (!keyword) return 0;
105         kl = strlen(keyword);
106         if (kl != count) return 0;
107         return !memcmp(buf,keyword,kl);
108 }
109
110
111 int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
112 {
113         int bcnt = 0;
114         int ccnt;
115         ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
116                          pvr2_hdw_get_desc(hdw));
117         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
118         ccnt = scnprintf(buf,acnt,"Driver state info:\n");
119         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
120         ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
121         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
122
123         return bcnt;
124 }
125
126
127 int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
128                                char *buf,unsigned int acnt)
129 {
130         int bcnt = 0;
131         int ccnt;
132         int ret;
133         u32 gpio_dir,gpio_in,gpio_out;
134         struct pvr2_stream_stats stats;
135         struct pvr2_stream *sp;
136
137         ret = pvr2_hdw_is_hsm(hdw);
138         ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
139                          (ret < 0 ? "FAIL" : (ret ? "high" : "full")));
140         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
141
142         gpio_dir = 0; gpio_in = 0; gpio_out = 0;
143         pvr2_hdw_gpio_get_dir(hdw,&gpio_dir);
144         pvr2_hdw_gpio_get_out(hdw,&gpio_out);
145         pvr2_hdw_gpio_get_in(hdw,&gpio_in);
146         ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
147                          gpio_dir,gpio_in,gpio_out);
148         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
149
150         ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
151                          pvr2_hdw_get_streaming(hdw) ? "on" : "off");
152         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
153
154
155         sp = pvr2_hdw_get_video_stream(hdw);
156         if (sp) {
157                 pvr2_stream_get_stats(sp, &stats, 0);
158                 ccnt = scnprintf(
159                         buf,acnt,
160                         "Bytes streamed=%u URBs: queued=%u idle=%u ready=%u processed=%u failed=%u\n",
161                         stats.bytes_processed,
162                         stats.buffers_in_queue,
163                         stats.buffers_in_idle,
164                         stats.buffers_in_ready,
165                         stats.buffers_processed,
166                         stats.buffers_failed);
167                 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
168         }
169
170         return bcnt;
171 }
172
173
174 static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
175                                 unsigned int count)
176 {
177         const char *wptr;
178         unsigned int wlen;
179         unsigned int scnt;
180
181         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
182         if (!scnt) return 0;
183         count -= scnt; buf += scnt;
184         if (!wptr) return 0;
185
186         pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr);
187         if (debugifc_match_keyword(wptr,wlen,"reset")) {
188                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
189                 if (!scnt) return -EINVAL;
190                 count -= scnt; buf += scnt;
191                 if (!wptr) return -EINVAL;
192                 if (debugifc_match_keyword(wptr,wlen,"cpu")) {
193                         pvr2_hdw_cpureset_assert(hdw,!0);
194                         pvr2_hdw_cpureset_assert(hdw,0);
195                         return 0;
196                 } else if (debugifc_match_keyword(wptr,wlen,"bus")) {
197                         pvr2_hdw_device_reset(hdw);
198                 } else if (debugifc_match_keyword(wptr,wlen,"soft")) {
199                         return pvr2_hdw_cmd_powerup(hdw);
200                 } else if (debugifc_match_keyword(wptr,wlen,"deep")) {
201                         return pvr2_hdw_cmd_deep_reset(hdw);
202                 } else if (debugifc_match_keyword(wptr,wlen,"firmware")) {
203                         return pvr2_upload_firmware2(hdw);
204                 } else if (debugifc_match_keyword(wptr,wlen,"decoder")) {
205                         return pvr2_hdw_cmd_decoder_reset(hdw);
206                 } else if (debugifc_match_keyword(wptr,wlen,"worker")) {
207                         return pvr2_hdw_untrip(hdw);
208                 } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) {
209                         pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw),
210                                               NULL, !0);
211                         return 0;
212                 }
213                 return -EINVAL;
214         } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
215                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
216                 if (!scnt) return -EINVAL;
217                 count -= scnt; buf += scnt;
218                 if (!wptr) return -EINVAL;
219                 if (debugifc_match_keyword(wptr,wlen,"fetch")) {
220                         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
221                         if (scnt && wptr) {
222                                 count -= scnt; buf += scnt;
223                                 if (debugifc_match_keyword(wptr, wlen,
224                                                            "prom")) {
225                                         pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
226                                 } else if (debugifc_match_keyword(wptr, wlen,
227                                                                   "ram8k")) {
228                                         pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
229                                 } else if (debugifc_match_keyword(wptr, wlen,
230                                                                   "ram16k")) {
231                                         pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
232                                 } else {
233                                         return -EINVAL;
234                                 }
235                         }
236                         pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
237                         return 0;
238                 } else if (debugifc_match_keyword(wptr,wlen,"done")) {
239                         pvr2_hdw_cpufw_set_enabled(hdw,0,0);
240                         return 0;
241                 } else {
242                         return -EINVAL;
243                 }
244         } else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
245                 int dir_fl = 0;
246                 int ret;
247                 u32 msk,val;
248                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
249                 if (!scnt) return -EINVAL;
250                 count -= scnt; buf += scnt;
251                 if (!wptr) return -EINVAL;
252                 if (debugifc_match_keyword(wptr,wlen,"dir")) {
253                         dir_fl = !0;
254                 } else if (!debugifc_match_keyword(wptr,wlen,"out")) {
255                         return -EINVAL;
256                 }
257                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
258                 if (!scnt) return -EINVAL;
259                 count -= scnt; buf += scnt;
260                 if (!wptr) return -EINVAL;
261                 ret = debugifc_parse_unsigned_number(wptr,wlen,&msk);
262                 if (ret) return ret;
263                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
264                 if (wptr) {
265                         ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
266                         if (ret) return ret;
267                 } else {
268                         val = msk;
269                         msk = 0xffffffff;
270                 }
271                 if (dir_fl) {
272                         ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
273                 } else {
274                         ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
275                 }
276                 return ret;
277         }
278         pvr2_trace(PVR2_TRACE_DEBUGIFC,
279                    "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
280         return -EINVAL;
281 }
282
283
284 int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
285                         unsigned int count)
286 {
287         unsigned int bcnt = 0;
288         int ret;
289
290         while (count) {
291                 for (bcnt = 0; bcnt < count; bcnt++) {
292                         if (buf[bcnt] == '\n') break;
293                 }
294
295                 ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
296                 if (ret < 0) return ret;
297                 if (bcnt < count) bcnt++;
298                 buf += bcnt;
299                 count -= bcnt;
300         }
301
302         return 0;
303 }
This page took 0.049909 seconds and 4 git commands to generate.