1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
7 #include <linux/string.h>
8 #include "pvrusb2-debugifc.h"
9 #include "pvrusb2-hdw.h"
10 #include "pvrusb2-debug.h"
12 struct debugifc_mask_item
{
18 static unsigned int debugifc_count_whitespace(const char *buf
,
24 for (scnt
= 0; scnt
< count
; scnt
++) {
26 if (ch
== ' ') continue;
27 if (ch
== '\t') continue;
28 if (ch
== '\n') continue;
35 static unsigned int debugifc_count_nonwhitespace(const char *buf
,
41 for (scnt
= 0; scnt
< count
; scnt
++) {
44 if (ch
== '\t') break;
45 if (ch
== '\n') break;
51 static unsigned int debugifc_isolate_word(const char *buf
,unsigned int count
,
53 unsigned int *wlenPtr
)
56 unsigned int consume_cnt
= 0;
62 scnt
= debugifc_count_whitespace(buf
,count
);
63 consume_cnt
+= scnt
; count
-= scnt
; buf
+= scnt
;
64 if (!count
) goto done
;
66 scnt
= debugifc_count_nonwhitespace(buf
,count
);
70 consume_cnt
+= scnt
; count
-= scnt
; buf
+= scnt
;
79 static int debugifc_parse_unsigned_number(const char *buf
,unsigned int count
,
84 if ((count
>= 2) && (buf
[0] == '0') &&
85 ((buf
[1] == 'x') || (buf
[1] == 'X'))) {
89 } else if ((count
>= 1) && (buf
[0] == '0')) {
94 int val
= hex_to_bin(*buf
++);
95 if (val
< 0 || val
>= radix
)
105 static int debugifc_match_keyword(const char *buf
,unsigned int count
,
109 if (!keyword
) return 0;
110 kl
= strlen(keyword
);
111 if (kl
!= count
) return 0;
112 return !memcmp(buf
,keyword
,kl
);
116 int pvr2_debugifc_print_info(struct pvr2_hdw
*hdw
,char *buf
,unsigned int acnt
)
120 ccnt
= scnprintf(buf
, acnt
, "Driver hardware description: %s\n",
121 pvr2_hdw_get_desc(hdw
));
122 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
123 ccnt
= scnprintf(buf
,acnt
,"Driver state info:\n");
124 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
125 ccnt
= pvr2_hdw_state_report(hdw
,buf
,acnt
);
126 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
132 int pvr2_debugifc_print_status(struct pvr2_hdw
*hdw
,
133 char *buf
,unsigned int acnt
)
138 u32 gpio_dir
,gpio_in
,gpio_out
;
139 struct pvr2_stream_stats stats
;
140 struct pvr2_stream
*sp
;
142 ret
= pvr2_hdw_is_hsm(hdw
);
143 ccnt
= scnprintf(buf
,acnt
,"USB link speed: %s\n",
144 (ret
< 0 ? "FAIL" : (ret
? "high" : "full")));
145 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
147 gpio_dir
= 0; gpio_in
= 0; gpio_out
= 0;
148 pvr2_hdw_gpio_get_dir(hdw
,&gpio_dir
);
149 pvr2_hdw_gpio_get_out(hdw
,&gpio_out
);
150 pvr2_hdw_gpio_get_in(hdw
,&gpio_in
);
151 ccnt
= scnprintf(buf
,acnt
,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
152 gpio_dir
,gpio_in
,gpio_out
);
153 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
155 ccnt
= scnprintf(buf
,acnt
,"Streaming is %s\n",
156 pvr2_hdw_get_streaming(hdw
) ? "on" : "off");
157 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
160 sp
= pvr2_hdw_get_video_stream(hdw
);
162 pvr2_stream_get_stats(sp
, &stats
, 0);
165 "Bytes streamed=%u URBs: queued=%u idle=%u ready=%u processed=%u failed=%u\n",
166 stats
.bytes_processed
,
167 stats
.buffers_in_queue
,
168 stats
.buffers_in_idle
,
169 stats
.buffers_in_ready
,
170 stats
.buffers_processed
,
171 stats
.buffers_failed
);
172 bcnt
+= ccnt
; acnt
-= ccnt
; buf
+= ccnt
;
179 static int pvr2_debugifc_do1cmd(struct pvr2_hdw
*hdw
,const char *buf
,
186 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
188 count
-= scnt
; buf
+= scnt
;
191 pvr2_trace(PVR2_TRACE_DEBUGIFC
,"debugifc cmd: \"%.*s\"",wlen
,wptr
);
192 if (debugifc_match_keyword(wptr
,wlen
,"reset")) {
193 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
194 if (!scnt
) return -EINVAL
;
195 count
-= scnt
; buf
+= scnt
;
196 if (!wptr
) return -EINVAL
;
197 if (debugifc_match_keyword(wptr
,wlen
,"cpu")) {
198 pvr2_hdw_cpureset_assert(hdw
,!0);
199 pvr2_hdw_cpureset_assert(hdw
,0);
201 } else if (debugifc_match_keyword(wptr
,wlen
,"bus")) {
202 pvr2_hdw_device_reset(hdw
);
203 } else if (debugifc_match_keyword(wptr
,wlen
,"soft")) {
204 return pvr2_hdw_cmd_powerup(hdw
);
205 } else if (debugifc_match_keyword(wptr
,wlen
,"deep")) {
206 return pvr2_hdw_cmd_deep_reset(hdw
);
207 } else if (debugifc_match_keyword(wptr
,wlen
,"firmware")) {
208 return pvr2_upload_firmware2(hdw
);
209 } else if (debugifc_match_keyword(wptr
,wlen
,"decoder")) {
210 return pvr2_hdw_cmd_decoder_reset(hdw
);
211 } else if (debugifc_match_keyword(wptr
,wlen
,"worker")) {
212 return pvr2_hdw_untrip(hdw
);
213 } else if (debugifc_match_keyword(wptr
,wlen
,"usbstats")) {
214 pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw
),
219 } else if (debugifc_match_keyword(wptr
,wlen
,"cpufw")) {
220 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
221 if (!scnt
) return -EINVAL
;
222 count
-= scnt
; buf
+= scnt
;
223 if (!wptr
) return -EINVAL
;
224 if (debugifc_match_keyword(wptr
,wlen
,"fetch")) {
225 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
227 count
-= scnt
; buf
+= scnt
;
228 if (debugifc_match_keyword(wptr
, wlen
,
230 pvr2_hdw_cpufw_set_enabled(hdw
, 2, !0);
231 } else if (debugifc_match_keyword(wptr
, wlen
,
233 pvr2_hdw_cpufw_set_enabled(hdw
, 0, !0);
234 } else if (debugifc_match_keyword(wptr
, wlen
,
236 pvr2_hdw_cpufw_set_enabled(hdw
, 1, !0);
241 pvr2_hdw_cpufw_set_enabled(hdw
,0,!0);
243 } else if (debugifc_match_keyword(wptr
,wlen
,"done")) {
244 pvr2_hdw_cpufw_set_enabled(hdw
,0,0);
249 } else if (debugifc_match_keyword(wptr
,wlen
,"gpio")) {
253 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
254 if (!scnt
) return -EINVAL
;
255 count
-= scnt
; buf
+= scnt
;
256 if (!wptr
) return -EINVAL
;
257 if (debugifc_match_keyword(wptr
,wlen
,"dir")) {
259 } else if (!debugifc_match_keyword(wptr
,wlen
,"out")) {
262 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
263 if (!scnt
) return -EINVAL
;
264 count
-= scnt
; buf
+= scnt
;
265 if (!wptr
) return -EINVAL
;
266 ret
= debugifc_parse_unsigned_number(wptr
,wlen
,&msk
);
268 scnt
= debugifc_isolate_word(buf
,count
,&wptr
,&wlen
);
270 ret
= debugifc_parse_unsigned_number(wptr
,wlen
,&val
);
277 ret
= pvr2_hdw_gpio_chg_dir(hdw
,msk
,val
);
279 ret
= pvr2_hdw_gpio_chg_out(hdw
,msk
,val
);
283 pvr2_trace(PVR2_TRACE_DEBUGIFC
,
284 "debugifc failed to recognize cmd: \"%.*s\"",wlen
,wptr
);
289 int pvr2_debugifc_docmd(struct pvr2_hdw
*hdw
,const char *buf
,
292 unsigned int bcnt
= 0;
296 for (bcnt
= 0; bcnt
< count
; bcnt
++) {
297 if (buf
[bcnt
] == '\n') break;
300 ret
= pvr2_debugifc_do1cmd(hdw
,buf
,bcnt
);
301 if (ret
< 0) return ret
;
302 if (bcnt
< count
) bcnt
++;