aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/f_fs.c132
-rw-r--r--drivers/usb/gadget/u_fs.h12
-rw-r--r--include/uapi/linux/usb/functionfs.h49
3 files changed, 91 insertions, 102 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 66f60b9a34a2..42f7a0e4be59 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1434,7 +1434,7 @@ static void ffs_data_clear(struct ffs_data *ffs)
1434 if (ffs->epfiles) 1434 if (ffs->epfiles)
1435 ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); 1435 ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);
1436 1436
1437 kfree(ffs->raw_descs); 1437 kfree(ffs->raw_descs_data);
1438 kfree(ffs->raw_strings); 1438 kfree(ffs->raw_strings);
1439 kfree(ffs->stringtabs); 1439 kfree(ffs->stringtabs);
1440} 1440}
@@ -1446,12 +1446,12 @@ static void ffs_data_reset(struct ffs_data *ffs)
1446 ffs_data_clear(ffs); 1446 ffs_data_clear(ffs);
1447 1447
1448 ffs->epfiles = NULL; 1448 ffs->epfiles = NULL;
1449 ffs->raw_descs_data = NULL;
1449 ffs->raw_descs = NULL; 1450 ffs->raw_descs = NULL;
1450 ffs->raw_strings = NULL; 1451 ffs->raw_strings = NULL;
1451 ffs->stringtabs = NULL; 1452 ffs->stringtabs = NULL;
1452 1453
1453 ffs->raw_fs_hs_descs_length = 0; 1454 ffs->raw_descs_length = 0;
1454 ffs->raw_ss_descs_length = 0;
1455 ffs->fs_descs_count = 0; 1455 ffs->fs_descs_count = 0;
1456 ffs->hs_descs_count = 0; 1456 ffs->hs_descs_count = 0;
1457 ffs->ss_descs_count = 0; 1457 ffs->ss_descs_count = 0;
@@ -1865,89 +1865,76 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
1865static int __ffs_data_got_descs(struct ffs_data *ffs, 1865static int __ffs_data_got_descs(struct ffs_data *ffs,
1866 char *const _data, size_t len) 1866 char *const _data, size_t len)
1867{ 1867{
1868 unsigned fs_count, hs_count, ss_count = 0; 1868 char *data = _data, *raw_descs;
1869 int fs_len, hs_len, ss_len, ret = -EINVAL; 1869 unsigned counts[3], flags;
1870 char *data = _data; 1870 int ret = -EINVAL, i;
1871 1871
1872 ENTER(); 1872 ENTER();
1873 1873
1874 if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_DESCRIPTORS_MAGIC || 1874 if (get_unaligned_le32(data + 4) != len)
1875 get_unaligned_le32(data + 4) != len))
1876 goto error; 1875 goto error;
1877 fs_count = get_unaligned_le32(data + 8);
1878 hs_count = get_unaligned_le32(data + 12);
1879
1880 data += 16;
1881 len -= 16;
1882 1876
1883 if (likely(fs_count)) { 1877 switch (get_unaligned_le32(data)) {
1884 fs_len = ffs_do_descs(fs_count, data, len, 1878 case FUNCTIONFS_DESCRIPTORS_MAGIC:
1885 __ffs_data_do_entity, ffs); 1879 flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
1886 if (unlikely(fs_len < 0)) { 1880 data += 8;
1887 ret = fs_len; 1881 len -= 8;
1882 break;
1883 case FUNCTIONFS_DESCRIPTORS_MAGIC_V2:
1884 flags = get_unaligned_le32(data + 8);
1885 if (flags & ~(FUNCTIONFS_HAS_FS_DESC |
1886 FUNCTIONFS_HAS_HS_DESC |
1887 FUNCTIONFS_HAS_SS_DESC)) {
1888 ret = -ENOSYS;
1888 goto error; 1889 goto error;
1889 } 1890 }
1890 1891 data += 12;
1891 data += fs_len; 1892 len -= 12;
1892 len -= fs_len; 1893 break;
1893 } else { 1894 default:
1894 fs_len = 0; 1895 goto error;
1895 } 1896 }
1896 1897
1897 if (likely(hs_count)) { 1898 /* Read fs_count, hs_count and ss_count (if present) */
1898 hs_len = ffs_do_descs(hs_count, data, len, 1899 for (i = 0; i < 3; ++i) {
1899 __ffs_data_do_entity, ffs); 1900 if (!(flags & (1 << i))) {
1900 if (unlikely(hs_len < 0)) { 1901 counts[i] = 0;
1901 ret = hs_len; 1902 } else if (len < 4) {
1902 goto error; 1903 goto error;
1904 } else {
1905 counts[i] = get_unaligned_le32(data);
1906 data += 4;
1907 len -= 4;
1903 } 1908 }
1904
1905 data += hs_len;
1906 len -= hs_len;
1907 } else {
1908 hs_len = 0;
1909 }
1910
1911 if (len >= 8) {
1912 /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */
1913 if (get_unaligned_le32(data) != FUNCTIONFS_SS_DESC_MAGIC)
1914 goto einval;
1915
1916 ss_count = get_unaligned_le32(data + 4);
1917 data += 8;
1918 len -= 8;
1919 } 1909 }
1920 1910
1921 if (!fs_count && !hs_count && !ss_count) 1911 /* Read descriptors */
1922 goto einval; 1912 raw_descs = data;
1923 1913 for (i = 0; i < 3; ++i) {
1924 if (ss_count) { 1914 if (!counts[i])
1925 ss_len = ffs_do_descs(ss_count, data, len, 1915 continue;
1916 ret = ffs_do_descs(counts[i], data, len,
1926 __ffs_data_do_entity, ffs); 1917 __ffs_data_do_entity, ffs);
1927 if (unlikely(ss_len < 0)) { 1918 if (ret < 0)
1928 ret = ss_len;
1929 goto error; 1919 goto error;
1930 } 1920 data += ret;
1931 ret = ss_len; 1921 len -= ret;
1932 } else {
1933 ss_len = 0;
1934 ret = 0;
1935 } 1922 }
1936 1923
1937 if (unlikely(len != ret)) 1924 if (raw_descs == data || len) {
1938 goto einval; 1925 ret = -EINVAL;
1926 goto error;
1927 }
1939 1928
1940 ffs->raw_fs_hs_descs_length = fs_len + hs_len; 1929 ffs->raw_descs_data = _data;
1941 ffs->raw_ss_descs_length = ss_len; 1930 ffs->raw_descs = raw_descs;
1942 ffs->raw_descs = _data; 1931 ffs->raw_descs_length = data - raw_descs;
1943 ffs->fs_descs_count = fs_count; 1932 ffs->fs_descs_count = counts[0];
1944 ffs->hs_descs_count = hs_count; 1933 ffs->hs_descs_count = counts[1];
1945 ffs->ss_descs_count = ss_count; 1934 ffs->ss_descs_count = counts[2];
1946 1935
1947 return 0; 1936 return 0;
1948 1937
1949einval:
1950 ret = -EINVAL;
1951error: 1938error:
1952 kfree(_data); 1939 kfree(_data);
1953 return ret; 1940 return ret;
@@ -2359,8 +2346,7 @@ static int _ffs_func_bind(struct usb_configuration *c,
2359 vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, 2346 vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs,
2360 super ? ffs->ss_descs_count + 1 : 0); 2347 super ? ffs->ss_descs_count + 1 : 0);
2361 vla_item_with_sz(d, short, inums, ffs->interfaces_count); 2348 vla_item_with_sz(d, short, inums, ffs->interfaces_count);
2362 vla_item_with_sz(d, char, raw_descs, 2349 vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length);
2363 ffs->raw_fs_hs_descs_length + ffs->raw_ss_descs_length);
2364 char *vlabuf; 2350 char *vlabuf;
2365 2351
2366 ENTER(); 2352 ENTER();
@@ -2376,15 +2362,9 @@ static int _ffs_func_bind(struct usb_configuration *c,
2376 2362
2377 /* Zero */ 2363 /* Zero */
2378 memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); 2364 memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz);
2379 /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */ 2365 /* Copy descriptors */
2380 memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16, 2366 memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs,
2381 ffs->raw_fs_hs_descs_length); 2367 ffs->raw_descs_length);
2382 /* Copy SS descs present @ header + hs_fs_descs + ss_magic + ss_count */
2383 if (func->ffs->ss_descs_count)
2384 memcpy(vla_ptr(vlabuf, d, raw_descs) +
2385 ffs->raw_fs_hs_descs_length,
2386 ffs->raw_descs + 16 + ffs->raw_fs_hs_descs_length + 8,
2387 ffs->raw_ss_descs_length);
2388 2368
2389 memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); 2369 memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
2390 for (ret = ffs->eps_count; ret; --ret) { 2370 for (ret = ffs->eps_count; ret; --ret) {
diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
index 0deb6d5f7c35..bf0ba375d459 100644
--- a/drivers/usb/gadget/u_fs.h
+++ b/drivers/usb/gadget/u_fs.h
@@ -206,15 +206,13 @@ struct ffs_data {
206 206
207 /* filled by __ffs_data_got_descs() */ 207 /* filled by __ffs_data_got_descs() */
208 /* 208 /*
209 * Real descriptors are 16 bytes after raw_descs (so you need 209 * raw_descs is what you kfree, real_descs points inside of raw_descs,
210 * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the 210 * where full speed, high speed and super speed descriptors start.
211 * first full speed descriptor). 211 * real_descs_length is the length of all those descriptors.
212 * raw_fs_hs_descs_length does not have those 16 bytes added.
213 * ss_descs are 8 bytes (ss_magic + count) pass the hs_descs
214 */ 212 */
213 const void *raw_descs_data;
215 const void *raw_descs; 214 const void *raw_descs;
216 unsigned raw_fs_hs_descs_length; 215 unsigned raw_descs_length;
217 unsigned raw_ss_descs_length;
218 unsigned fs_descs_count; 216 unsigned fs_descs_count;
219 unsigned hs_descs_count; 217 unsigned hs_descs_count;
220 unsigned ss_descs_count; 218 unsigned ss_descs_count;
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h
index 0f8f7be5b0d3..2a4b4a72a4f9 100644
--- a/include/uapi/linux/usb/functionfs.h
+++ b/include/uapi/linux/usb/functionfs.h
@@ -10,10 +10,15 @@
10 10
11enum { 11enum {
12 FUNCTIONFS_DESCRIPTORS_MAGIC = 1, 12 FUNCTIONFS_DESCRIPTORS_MAGIC = 1,
13 FUNCTIONFS_STRINGS_MAGIC = 2 13 FUNCTIONFS_STRINGS_MAGIC = 2,
14 FUNCTIONFS_DESCRIPTORS_MAGIC_V2 = 3,
14}; 15};
15 16
16#define FUNCTIONFS_SS_DESC_MAGIC 0x0055DE5C 17enum functionfs_flags {
18 FUNCTIONFS_HAS_FS_DESC = 1,
19 FUNCTIONFS_HAS_HS_DESC = 2,
20 FUNCTIONFS_HAS_SS_DESC = 4,
21};
17 22
18#ifndef __KERNEL__ 23#ifndef __KERNEL__
19 24
@@ -30,33 +35,39 @@ struct usb_endpoint_descriptor_no_audio {
30 35
31 36
32/* 37/*
33 * All numbers must be in little endian order.
34 */
35
36struct usb_functionfs_descs_head {
37 __le32 magic;
38 __le32 length;
39 __le32 fs_count;
40 __le32 hs_count;
41} __attribute__((packed));
42
43/*
44 * Descriptors format: 38 * Descriptors format:
45 * 39 *
46 * | off | name | type | description | 40 * | off | name | type | description |
47 * |-----+-----------+--------------+--------------------------------------| 41 * |-----+-----------+--------------+--------------------------------------|
48 * | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC | 42 * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 |
43 * | 4 | length | LE32 | length of the whole data chunk |
44 * | 8 | flags | LE32 | combination of functionfs_flags |
45 * | | fs_count | LE32 | number of full-speed descriptors |
46 * | | hs_count | LE32 | number of high-speed descriptors |
47 * | | ss_count | LE32 | number of super-speed descriptors |
48 * | | fs_descrs | Descriptor[] | list of full-speed descriptors |
49 * | | hs_descrs | Descriptor[] | list of high-speed descriptors |
50 * | | ss_descrs | Descriptor[] | list of super-speed descriptors |
51 *
52 * Depending on which flags are set, various fields may be missing in the
53 * structure. Any flags that are not recognised cause the whole block to be
54 * rejected with -ENOSYS.
55 *
56 * Legacy descriptors format:
57 *
58 * | off | name | type | description |
59 * |-----+-----------+--------------+--------------------------------------|
60 * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC |
49 * | 4 | length | LE32 | length of the whole data chunk | 61 * | 4 | length | LE32 | length of the whole data chunk |
50 * | 8 | fs_count | LE32 | number of full-speed descriptors | 62 * | 8 | fs_count | LE32 | number of full-speed descriptors |
51 * | 12 | hs_count | LE32 | number of high-speed descriptors | 63 * | 12 | hs_count | LE32 | number of high-speed descriptors |
52 * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | 64 * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors |
53 * | | hs_descrs | Descriptor[] | list of high-speed descriptors | 65 * | | hs_descrs | Descriptor[] | list of high-speed descriptors |
54 * | | ss_magic | LE32 | FUNCTIONFS_SS_DESC_MAGIC |
55 * | | ss_count | LE32 | number of super-speed descriptors |
56 * | | ss_descrs | Descriptor[] | list of super-speed descriptors |
57 * 66 *
58 * ss_magic: if present then it implies that SS_DESCs are also present 67 * All numbers must be in little endian order.
59 * descs are just valid USB descriptors and have the following format: 68 *
69 * Descriptor[] is an array of valid USB descriptors which have the following
70 * format:
60 * 71 *
61 * | off | name | type | description | 72 * | off | name | type | description |
62 * |-----+-----------------+------+--------------------------| 73 * |-----+-----------------+------+--------------------------|