root/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. debugifc_count_whitespace
  2. debugifc_count_nonwhitespace
  3. debugifc_isolate_word
  4. debugifc_parse_unsigned_number
  5. debugifc_match_keyword
  6. pvr2_debugifc_print_info
  7. pvr2_debugifc_print_status
  8. pvr2_debugifc_do1cmd
  9. pvr2_debugifc_docmd

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5  */
   6 
   7 #include <linux/string.h>
   8 #include "pvrusb2-debugifc.h"
   9 #include "pvrusb2-hdw.h"
  10 #include "pvrusb2-debug.h"
  11 
  12 struct debugifc_mask_item {
  13         const char *name;
  14         unsigned long msk;
  15 };
  16 
  17 
  18 static unsigned int debugifc_count_whitespace(const char *buf,
  19                                               unsigned int count)
  20 {
  21         unsigned int scnt;
  22         char ch;
  23 
  24         for (scnt = 0; scnt < count; scnt++) {
  25                 ch = buf[scnt];
  26                 if (ch == ' ') continue;
  27                 if (ch == '\t') continue;
  28                 if (ch == '\n') continue;
  29                 break;
  30         }
  31         return scnt;
  32 }
  33 
  34 
  35 static unsigned int debugifc_count_nonwhitespace(const char *buf,
  36                                                  unsigned int count)
  37 {
  38         unsigned int scnt;
  39         char ch;
  40 
  41         for (scnt = 0; scnt < count; scnt++) {
  42                 ch = buf[scnt];
  43                 if (ch == ' ') break;
  44                 if (ch == '\t') break;
  45                 if (ch == '\n') break;
  46         }
  47         return scnt;
  48 }
  49 
  50 
  51 static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
  52                                           const char **wstrPtr,
  53                                           unsigned int *wlenPtr)
  54 {
  55         const char *wptr;
  56         unsigned int consume_cnt = 0;
  57         unsigned int wlen;
  58         unsigned int scnt;
  59 
  60         wptr = NULL;
  61         wlen = 0;
  62         scnt = debugifc_count_whitespace(buf,count);
  63         consume_cnt += scnt; count -= scnt; buf += scnt;
  64         if (!count) goto done;
  65 
  66         scnt = debugifc_count_nonwhitespace(buf,count);
  67         if (!scnt) goto done;
  68         wptr = buf;
  69         wlen = scnt;
  70         consume_cnt += scnt; count -= scnt; buf += scnt;
  71 
  72  done:
  73         *wstrPtr = wptr;
  74         *wlenPtr = wlen;
  75         return consume_cnt;
  76 }
  77 
  78 
  79 static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
  80                                           u32 *num_ptr)
  81 {
  82         u32 result = 0;
  83         int radix = 10;
  84         if ((count >= 2) && (buf[0] == '0') &&
  85             ((buf[1] == 'x') || (buf[1] == 'X'))) {
  86                 radix = 16;
  87                 count -= 2;
  88                 buf += 2;
  89         } else if ((count >= 1) && (buf[0] == '0')) {
  90                 radix = 8;
  91         }
  92 
  93         while (count--) {
  94                 int val = hex_to_bin(*buf++);
  95                 if (val < 0 || val >= radix)
  96                         return -EINVAL;
  97                 result *= radix;
  98                 result += val;
  99         }
 100         *num_ptr = result;
 101         return 0;
 102 }
 103 
 104 
 105 static int debugifc_match_keyword(const char *buf,unsigned int count,
 106                                   const char *keyword)
 107 {
 108         unsigned int kl;
 109         if (!keyword) return 0;
 110         kl = strlen(keyword);
 111         if (kl != count) return 0;
 112         return !memcmp(buf,keyword,kl);
 113 }
 114 
 115 
 116 int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
 117 {
 118         int bcnt = 0;
 119         int ccnt;
 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;
 127 
 128         return bcnt;
 129 }
 130 
 131 
 132 int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
 133                                char *buf,unsigned int acnt)
 134 {
 135         int bcnt = 0;
 136         int ccnt;
 137         int ret;
 138         u32 gpio_dir,gpio_in,gpio_out;
 139         struct pvr2_stream_stats stats;
 140         struct pvr2_stream *sp;
 141 
 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;
 146 
 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;
 154 
 155         ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
 156                          pvr2_hdw_get_streaming(hdw) ? "on" : "off");
 157         bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 158 
 159 
 160         sp = pvr2_hdw_get_video_stream(hdw);
 161         if (sp) {
 162                 pvr2_stream_get_stats(sp, &stats, 0);
 163                 ccnt = scnprintf(
 164                         buf,acnt,
 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;
 173         }
 174 
 175         return bcnt;
 176 }
 177 
 178 
 179 static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
 180                                 unsigned int count)
 181 {
 182         const char *wptr;
 183         unsigned int wlen;
 184         unsigned int scnt;
 185 
 186         scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
 187         if (!scnt) return 0;
 188         count -= scnt; buf += scnt;
 189         if (!wptr) return 0;
 190 
 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);
 200                         return 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),
 215                                               NULL, !0);
 216                         return 0;
 217                 }
 218                 return -EINVAL;
 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);
 226                         if (scnt && wptr) {
 227                                 count -= scnt; buf += scnt;
 228                                 if (debugifc_match_keyword(wptr, wlen,
 229                                                            "prom")) {
 230                                         pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
 231                                 } else if (debugifc_match_keyword(wptr, wlen,
 232                                                                   "ram8k")) {
 233                                         pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
 234                                 } else if (debugifc_match_keyword(wptr, wlen,
 235                                                                   "ram16k")) {
 236                                         pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
 237                                 } else {
 238                                         return -EINVAL;
 239                                 }
 240                         }
 241                         pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
 242                         return 0;
 243                 } else if (debugifc_match_keyword(wptr,wlen,"done")) {
 244                         pvr2_hdw_cpufw_set_enabled(hdw,0,0);
 245                         return 0;
 246                 } else {
 247                         return -EINVAL;
 248                 }
 249         } else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
 250                 int dir_fl = 0;
 251                 int ret;
 252                 u32 msk,val;
 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")) {
 258                         dir_fl = !0;
 259                 } else if (!debugifc_match_keyword(wptr,wlen,"out")) {
 260                         return -EINVAL;
 261                 }
 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);
 267                 if (ret) return ret;
 268                 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
 269                 if (wptr) {
 270                         ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
 271                         if (ret) return ret;
 272                 } else {
 273                         val = msk;
 274                         msk = 0xffffffff;
 275                 }
 276                 if (dir_fl) {
 277                         ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
 278                 } else {
 279                         ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
 280                 }
 281                 return ret;
 282         }
 283         pvr2_trace(PVR2_TRACE_DEBUGIFC,
 284                    "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
 285         return -EINVAL;
 286 }
 287 
 288 
 289 int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
 290                         unsigned int count)
 291 {
 292         unsigned int bcnt = 0;
 293         int ret;
 294 
 295         while (count) {
 296                 for (bcnt = 0; bcnt < count; bcnt++) {
 297                         if (buf[bcnt] == '\n') break;
 298                 }
 299 
 300                 ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
 301                 if (ret < 0) return ret;
 302                 if (bcnt < count) bcnt++;
 303                 buf += bcnt;
 304                 count -= bcnt;
 305         }
 306 
 307         return 0;
 308 }

/* [<][>][^][v][top][bottom][index][help] */