Currently, ddebug_parse_flags accepts [+-=][pflmt_]+ as flag-spec
strings.  If we allow [pflmt_]*[+-=][pflmt_]+ instead, the (new) 1st
flagset can be used as a filter to select callsites, before applying
changes in the 2nd flagset.  1st step is to split out the flags-reader
so we can use it again.

The point of this is to allow user to compose an arbitrary set of
changes, by marking callsites with [fmlt] flags, and then to
activate that composed set in a single query.

 #> echo '=_' > control                 # clear all flags
 #> echo 'module usb* +fmlt' > control  # build the marked set, repeat
 #> echo 'fmlt+p' > control             # activate

Signed-off-by: Jim Cromie <jim.cro...@gmail.com>
---
 lib/dynamic_debug.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8f250c67acbe..005b8221a9d6 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -413,6 +413,26 @@ static int ddebug_parse_query(char *words[], int nwords,
        return 0;
 }
 
+static int ddebug_read_flags(const char *str, unsigned int *flags)
+{
+       int i;
+
+       for (; *str ; ++str) {
+               for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
+                       if (*str == opt_array[i].opt_char) {
+                               *flags |= opt_array[i].flag;
+                               break;
+                       }
+               }
+               if (i < 0) {
+                       pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
+                       return -EINVAL;
+               }
+       }
+       vpr_info("flags=0x%x\n", *flags);
+       return 0;
+}
+
 /*
  * Parse `str' as a flags specification, format [-+=][p]+.
  * Sets up *maskp and *flagsp to be used when changing the
@@ -423,7 +443,7 @@ static int ddebug_parse_flags(const char *str, unsigned int 
*flagsp,
                               unsigned int *maskp)
 {
        unsigned flags = 0;
-       int op = '=', i;
+       int op;
 
        switch (*str) {
        case '+':
@@ -437,19 +457,8 @@ static int ddebug_parse_flags(const char *str, unsigned 
int *flagsp,
        }
        vpr_info("op='%c'\n", op);
 
-       for (; *str ; ++str) {
-               for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
-                       if (*str == opt_array[i].opt_char) {
-                               flags |= opt_array[i].flag;
-                               break;
-                       }
-               }
-               if (i < 0) {
-                       pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
-                       return -EINVAL;
-               }
-       }
-       vpr_info("flags=0x%x\n", flags);
+       if (ddebug_read_flags(str, &flags))
+               return -EINVAL;
 
        /* calculate final *flagsp, *maskp according to mask and op */
        switch (op) {
-- 
2.26.2

Reply via email to