Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
0005  */
0006 
0007 #include <linux/string.h>
0008 #include "pvrusb2-debugifc.h"
0009 #include "pvrusb2-hdw.h"
0010 #include "pvrusb2-debug.h"
0011 
0012 struct debugifc_mask_item {
0013     const char *name;
0014     unsigned long msk;
0015 };
0016 
0017 
0018 static unsigned int debugifc_count_whitespace(const char *buf,
0019                           unsigned int count)
0020 {
0021     unsigned int scnt;
0022     char ch;
0023 
0024     for (scnt = 0; scnt < count; scnt++) {
0025         ch = buf[scnt];
0026         if (ch == ' ') continue;
0027         if (ch == '\t') continue;
0028         if (ch == '\n') continue;
0029         break;
0030     }
0031     return scnt;
0032 }
0033 
0034 
0035 static unsigned int debugifc_count_nonwhitespace(const char *buf,
0036                          unsigned int count)
0037 {
0038     unsigned int scnt;
0039     char ch;
0040 
0041     for (scnt = 0; scnt < count; scnt++) {
0042         ch = buf[scnt];
0043         if (ch == ' ') break;
0044         if (ch == '\t') break;
0045         if (ch == '\n') break;
0046     }
0047     return scnt;
0048 }
0049 
0050 
0051 static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
0052                       const char **wstrPtr,
0053                       unsigned int *wlenPtr)
0054 {
0055     const char *wptr;
0056     unsigned int consume_cnt = 0;
0057     unsigned int wlen;
0058     unsigned int scnt;
0059 
0060     wptr = NULL;
0061     wlen = 0;
0062     scnt = debugifc_count_whitespace(buf,count);
0063     consume_cnt += scnt; count -= scnt; buf += scnt;
0064     if (!count) goto done;
0065 
0066     scnt = debugifc_count_nonwhitespace(buf,count);
0067     if (!scnt) goto done;
0068     wptr = buf;
0069     wlen = scnt;
0070     consume_cnt += scnt; count -= scnt; buf += scnt;
0071 
0072  done:
0073     *wstrPtr = wptr;
0074     *wlenPtr = wlen;
0075     return consume_cnt;
0076 }
0077 
0078 
0079 static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
0080                       u32 *num_ptr)
0081 {
0082     u32 result = 0;
0083     int radix = 10;
0084     if ((count >= 2) && (buf[0] == '0') &&
0085         ((buf[1] == 'x') || (buf[1] == 'X'))) {
0086         radix = 16;
0087         count -= 2;
0088         buf += 2;
0089     } else if ((count >= 1) && (buf[0] == '0')) {
0090         radix = 8;
0091     }
0092 
0093     while (count--) {
0094         int val = hex_to_bin(*buf++);
0095         if (val < 0 || val >= radix)
0096             return -EINVAL;
0097         result *= radix;
0098         result += val;
0099     }
0100     *num_ptr = result;
0101     return 0;
0102 }
0103 
0104 
0105 static int debugifc_match_keyword(const char *buf,unsigned int count,
0106                   const char *keyword)
0107 {
0108     unsigned int kl;
0109     if (!keyword) return 0;
0110     kl = strlen(keyword);
0111     if (kl != count) return 0;
0112     return !memcmp(buf,keyword,kl);
0113 }
0114 
0115 
0116 int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
0117 {
0118     int bcnt = 0;
0119     int ccnt;
0120     ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
0121              pvr2_hdw_get_desc(hdw));
0122     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0123     ccnt = scnprintf(buf,acnt,"Driver state info:\n");
0124     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0125     ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
0126     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0127 
0128     return bcnt;
0129 }
0130 
0131 
0132 int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
0133                    char *buf,unsigned int acnt)
0134 {
0135     int bcnt = 0;
0136     int ccnt;
0137     int ret;
0138     u32 gpio_dir,gpio_in,gpio_out;
0139     struct pvr2_stream_stats stats;
0140     struct pvr2_stream *sp;
0141 
0142     ret = pvr2_hdw_is_hsm(hdw);
0143     ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
0144              (ret < 0 ? "FAIL" : (ret ? "high" : "full")));
0145     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0146 
0147     gpio_dir = 0; gpio_in = 0; gpio_out = 0;
0148     pvr2_hdw_gpio_get_dir(hdw,&gpio_dir);
0149     pvr2_hdw_gpio_get_out(hdw,&gpio_out);
0150     pvr2_hdw_gpio_get_in(hdw,&gpio_in);
0151     ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
0152              gpio_dir,gpio_in,gpio_out);
0153     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0154 
0155     ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
0156              pvr2_hdw_get_streaming(hdw) ? "on" : "off");
0157     bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0158 
0159 
0160     sp = pvr2_hdw_get_video_stream(hdw);
0161     if (sp) {
0162         pvr2_stream_get_stats(sp, &stats, 0);
0163         ccnt = scnprintf(
0164             buf,acnt,
0165             "Bytes streamed=%u URBs: queued=%u idle=%u ready=%u processed=%u failed=%u\n",
0166             stats.bytes_processed,
0167             stats.buffers_in_queue,
0168             stats.buffers_in_idle,
0169             stats.buffers_in_ready,
0170             stats.buffers_processed,
0171             stats.buffers_failed);
0172         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
0173     }
0174 
0175     return bcnt;
0176 }
0177 
0178 
0179 static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
0180                 unsigned int count)
0181 {
0182     const char *wptr;
0183     unsigned int wlen;
0184     unsigned int scnt;
0185 
0186     scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0187     if (!scnt) return 0;
0188     count -= scnt; buf += scnt;
0189     if (!wptr) return 0;
0190 
0191     pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr);
0192     if (debugifc_match_keyword(wptr,wlen,"reset")) {
0193         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0194         if (!scnt) return -EINVAL;
0195         count -= scnt; buf += scnt;
0196         if (!wptr) return -EINVAL;
0197         if (debugifc_match_keyword(wptr,wlen,"cpu")) {
0198             pvr2_hdw_cpureset_assert(hdw,!0);
0199             pvr2_hdw_cpureset_assert(hdw,0);
0200             return 0;
0201         } else if (debugifc_match_keyword(wptr,wlen,"bus")) {
0202             pvr2_hdw_device_reset(hdw);
0203         } else if (debugifc_match_keyword(wptr,wlen,"soft")) {
0204             return pvr2_hdw_cmd_powerup(hdw);
0205         } else if (debugifc_match_keyword(wptr,wlen,"deep")) {
0206             return pvr2_hdw_cmd_deep_reset(hdw);
0207         } else if (debugifc_match_keyword(wptr,wlen,"firmware")) {
0208             return pvr2_upload_firmware2(hdw);
0209         } else if (debugifc_match_keyword(wptr,wlen,"decoder")) {
0210             return pvr2_hdw_cmd_decoder_reset(hdw);
0211         } else if (debugifc_match_keyword(wptr,wlen,"worker")) {
0212             return pvr2_hdw_untrip(hdw);
0213         } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) {
0214             pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw),
0215                           NULL, !0);
0216             return 0;
0217         }
0218         return -EINVAL;
0219     } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
0220         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0221         if (!scnt) return -EINVAL;
0222         count -= scnt; buf += scnt;
0223         if (!wptr) return -EINVAL;
0224         if (debugifc_match_keyword(wptr,wlen,"fetch")) {
0225             scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0226             if (scnt && wptr) {
0227                 count -= scnt; buf += scnt;
0228                 if (debugifc_match_keyword(wptr, wlen,
0229                                "prom")) {
0230                     pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
0231                 } else if (debugifc_match_keyword(wptr, wlen,
0232                                   "ram8k")) {
0233                     pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
0234                 } else if (debugifc_match_keyword(wptr, wlen,
0235                                   "ram16k")) {
0236                     pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
0237                 } else {
0238                     return -EINVAL;
0239                 }
0240             }
0241             pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
0242             return 0;
0243         } else if (debugifc_match_keyword(wptr,wlen,"done")) {
0244             pvr2_hdw_cpufw_set_enabled(hdw,0,0);
0245             return 0;
0246         } else {
0247             return -EINVAL;
0248         }
0249     } else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
0250         int dir_fl = 0;
0251         int ret;
0252         u32 msk,val;
0253         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0254         if (!scnt) return -EINVAL;
0255         count -= scnt; buf += scnt;
0256         if (!wptr) return -EINVAL;
0257         if (debugifc_match_keyword(wptr,wlen,"dir")) {
0258             dir_fl = !0;
0259         } else if (!debugifc_match_keyword(wptr,wlen,"out")) {
0260             return -EINVAL;
0261         }
0262         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0263         if (!scnt) return -EINVAL;
0264         count -= scnt; buf += scnt;
0265         if (!wptr) return -EINVAL;
0266         ret = debugifc_parse_unsigned_number(wptr,wlen,&msk);
0267         if (ret) return ret;
0268         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
0269         if (wptr) {
0270             ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
0271             if (ret) return ret;
0272         } else {
0273             val = msk;
0274             msk = 0xffffffff;
0275         }
0276         if (dir_fl) {
0277             ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
0278         } else {
0279             ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
0280         }
0281         return ret;
0282     }
0283     pvr2_trace(PVR2_TRACE_DEBUGIFC,
0284            "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
0285     return -EINVAL;
0286 }
0287 
0288 
0289 int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
0290             unsigned int count)
0291 {
0292     unsigned int bcnt = 0;
0293     int ret;
0294 
0295     while (count) {
0296         for (bcnt = 0; bcnt < count; bcnt++) {
0297             if (buf[bcnt] == '\n') break;
0298         }
0299 
0300         ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
0301         if (ret < 0) return ret;
0302         if (bcnt < count) bcnt++;
0303         buf += bcnt;
0304         count -= bcnt;
0305     }
0306 
0307     return 0;
0308 }