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