]> Git Repo - linux.git/commitdiff
usb: gadget: uvc: Generalise helper functions for reuse
authorDaniel Scally <[email protected]>
Mon, 6 Feb 2023 16:17:53 +0000 (16:17 +0000)
committerGreg Kroah-Hartman <[email protected]>
Tue, 7 Feb 2023 07:46:36 +0000 (08:46 +0100)
The __uvcg_*frm_intrv() helper functions can be helpful when adding
support for similar attributes. Generalise the functions and
move them higher in the file for better coverage.

Signed-off-by: Daniel Scally <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/usb/gadget/function/uvc_configfs.c

index b52aae924d662e228aaf5b44b3dacbd690ee45b3..b32ecbdfd88d2a9f331d5e6ff49fd1a4a9fce4fd 100644 (file)
@@ -47,6 +47,71 @@ static int uvcg_config_compare_u32(const void *l, const void *r)
        return li < ri ? -1 : li == ri ? 0 : 1;
 }
 
+static inline int __uvcg_count_item_entries(char *buf, void *priv, unsigned int size)
+{
+       ++*((int *)priv);
+       return 0;
+}
+
+static inline int __uvcg_fill_item_entries(char *buf, void *priv, unsigned int size)
+{
+       unsigned int num;
+       u8 **values;
+       int ret;
+
+       ret = kstrtouint(buf, 0, &num);
+       if (ret)
+               return ret;
+
+       if (num != (num & GENMASK((size * 8) - 1, 0)))
+               return -ERANGE;
+
+       values = priv;
+       memcpy(*values, &num, size);
+       *values += size;
+
+       return 0;
+}
+
+static int __uvcg_iter_item_entries(const char *page, size_t len,
+                                   int (*fun)(char *, void *, unsigned int),
+                                   void *priv, unsigned int size)
+{
+       /* sign, base 2 representation, newline, terminator */
+       unsigned int bufsize = 1 + size * 8 + 1 + 1;
+       const char *pg = page;
+       int i, ret = 0;
+       char *buf;
+
+       if (!fun)
+               return -EINVAL;
+
+       buf = kzalloc(bufsize, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       while (pg - page < len) {
+               i = 0;
+               while (i < sizeof(buf) && (pg - page < len) &&
+                      *pg != '\0' && *pg != '\n')
+                       buf[i++] = *pg++;
+               if (i == sizeof(buf)) {
+                       ret = -EINVAL;
+                       goto out_free_buf;
+               }
+               while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
+                       ++pg;
+               buf[i] = '\0';
+               ret = fun(buf, priv, size);
+               if (ret)
+                       goto out_free_buf;
+       }
+
+out_free_buf:
+       kfree(buf);
+       return ret;
+}
+
 struct uvcg_config_group_type {
        struct config_item_type type;
        const char *name;
@@ -1336,57 +1401,6 @@ static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
        return result;
 }
 
-static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
-{
-       ++*((int *)priv);
-       return 0;
-}
-
-static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
-{
-       u32 num, **interv;
-       int ret;
-
-       ret = kstrtou32(buf, 0, &num);
-       if (ret)
-               return ret;
-
-       interv = priv;
-       **interv = num;
-       ++*interv;
-
-       return 0;
-}
-
-static int __uvcg_iter_frm_intrv(const char *page, size_t len,
-                                int (*fun)(char *, void *), void *priv)
-{
-       /* sign, base 2 representation, newline, terminator */
-       char buf[1 + sizeof(u32) * 8 + 1 + 1];
-       const char *pg = page;
-       int i, ret;
-
-       if (!fun)
-               return -EINVAL;
-
-       while (pg - page < len) {
-               i = 0;
-               while (i < sizeof(buf) && (pg - page < len) &&
-                               *pg != '\0' && *pg != '\n')
-                       buf[i++] = *pg++;
-               if (i == sizeof(buf))
-                       return -EINVAL;
-               while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
-                       ++pg;
-               buf[i] = '\0';
-               ret = fun(buf, priv);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
                                                  const char *page, size_t len)
 {
@@ -1410,7 +1424,7 @@ static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
                goto end;
        }
 
-       ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
+       ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, sizeof(u32));
        if (ret)
                goto end;
 
@@ -1420,7 +1434,7 @@ static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
                goto end;
        }
 
-       ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
+       ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, sizeof(u32));
        if (ret) {
                kfree(frm_intrv);
                goto end;
This page took 0.068692 seconds and 4 git commands to generate.