Commit 0df28607 authored by Daniel Scally's avatar Daniel Scally Committed by Greg Kroah-Hartman

usb: gadget: uvc: Generalise helper functions for reuse

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: default avatarDaniel Scally <dan.scally@ideasonboard.com>
Link: https://lore.kernel.org/r/20230206161802.892954-3-dan.scally@ideasonboard.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b3c839bd
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment