Skip to content

Commit 0df2860

Browse files
djrscallygregkh
authored andcommitted
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: Daniel Scally <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b3c839b commit 0df2860

File tree

1 file changed

+67
-53
lines changed

1 file changed

+67
-53
lines changed

drivers/usb/gadget/function/uvc_configfs.c

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,71 @@ static int uvcg_config_compare_u32(const void *l, const void *r)
4747
return li < ri ? -1 : li == ri ? 0 : 1;
4848
}
4949

50+
static inline int __uvcg_count_item_entries(char *buf, void *priv, unsigned int size)
51+
{
52+
++*((int *)priv);
53+
return 0;
54+
}
55+
56+
static inline int __uvcg_fill_item_entries(char *buf, void *priv, unsigned int size)
57+
{
58+
unsigned int num;
59+
u8 **values;
60+
int ret;
61+
62+
ret = kstrtouint(buf, 0, &num);
63+
if (ret)
64+
return ret;
65+
66+
if (num != (num & GENMASK((size * 8) - 1, 0)))
67+
return -ERANGE;
68+
69+
values = priv;
70+
memcpy(*values, &num, size);
71+
*values += size;
72+
73+
return 0;
74+
}
75+
76+
static int __uvcg_iter_item_entries(const char *page, size_t len,
77+
int (*fun)(char *, void *, unsigned int),
78+
void *priv, unsigned int size)
79+
{
80+
/* sign, base 2 representation, newline, terminator */
81+
unsigned int bufsize = 1 + size * 8 + 1 + 1;
82+
const char *pg = page;
83+
int i, ret = 0;
84+
char *buf;
85+
86+
if (!fun)
87+
return -EINVAL;
88+
89+
buf = kzalloc(bufsize, GFP_KERNEL);
90+
if (!buf)
91+
return -ENOMEM;
92+
93+
while (pg - page < len) {
94+
i = 0;
95+
while (i < sizeof(buf) && (pg - page < len) &&
96+
*pg != '\0' && *pg != '\n')
97+
buf[i++] = *pg++;
98+
if (i == sizeof(buf)) {
99+
ret = -EINVAL;
100+
goto out_free_buf;
101+
}
102+
while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
103+
++pg;
104+
buf[i] = '\0';
105+
ret = fun(buf, priv, size);
106+
if (ret)
107+
goto out_free_buf;
108+
}
109+
110+
out_free_buf:
111+
kfree(buf);
112+
return ret;
113+
}
114+
50115
struct uvcg_config_group_type {
51116
struct config_item_type type;
52117
const char *name;
@@ -1336,57 +1401,6 @@ static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
13361401
return result;
13371402
}
13381403

1339-
static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1340-
{
1341-
++*((int *)priv);
1342-
return 0;
1343-
}
1344-
1345-
static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
1346-
{
1347-
u32 num, **interv;
1348-
int ret;
1349-
1350-
ret = kstrtou32(buf, 0, &num);
1351-
if (ret)
1352-
return ret;
1353-
1354-
interv = priv;
1355-
**interv = num;
1356-
++*interv;
1357-
1358-
return 0;
1359-
}
1360-
1361-
static int __uvcg_iter_frm_intrv(const char *page, size_t len,
1362-
int (*fun)(char *, void *), void *priv)
1363-
{
1364-
/* sign, base 2 representation, newline, terminator */
1365-
char buf[1 + sizeof(u32) * 8 + 1 + 1];
1366-
const char *pg = page;
1367-
int i, ret;
1368-
1369-
if (!fun)
1370-
return -EINVAL;
1371-
1372-
while (pg - page < len) {
1373-
i = 0;
1374-
while (i < sizeof(buf) && (pg - page < len) &&
1375-
*pg != '\0' && *pg != '\n')
1376-
buf[i++] = *pg++;
1377-
if (i == sizeof(buf))
1378-
return -EINVAL;
1379-
while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
1380-
++pg;
1381-
buf[i] = '\0';
1382-
ret = fun(buf, priv);
1383-
if (ret)
1384-
return ret;
1385-
}
1386-
1387-
return 0;
1388-
}
1389-
13901404
static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
13911405
const char *page, size_t len)
13921406
{
@@ -1410,7 +1424,7 @@ static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
14101424
goto end;
14111425
}
14121426

1413-
ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
1427+
ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, sizeof(u32));
14141428
if (ret)
14151429
goto end;
14161430

@@ -1420,7 +1434,7 @@ static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
14201434
goto end;
14211435
}
14221436

1423-
ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
1437+
ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, sizeof(u32));
14241438
if (ret) {
14251439
kfree(frm_intrv);
14261440
goto end;

0 commit comments

Comments
 (0)