History

usb: gadget: f_fs: Add flags to descriptors block

This reworks the way SuperSpeed descriptors are added and instead of having a magic after full and high speed descriptors, it reworks the whole descriptors block to include a flags field which lists which descriptors are present and makes future extensions possible.

Michal Nazarewicz committed 12 years ago

Commit ac8dde11 parent 8d4e8973 files · +91 −102Browse files

Unified · Split

3 files
  1. drivers/usb/gadget/f_fs.c +56 −76
  2. drivers/usb/gadget/u_fs.h +5 −7
  3. include/uapi/linux/usb/functionfs.h +30 −19
drivers/usb/gadget/f_fs.c+56−76
@@ -1434,7 +1434,7 @@ static void ffs_data_clear(struct ffs_data *ffs) · 1433 unmodified lines
14341434 if (ffs->epfiles)
14351435 ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);
14361436
1437− kfree(ffs->raw_descs);
1437+ kfree(ffs->raw_descs_data);
14381438 kfree(ffs->raw_strings);
14391439 kfree(ffs->stringtabs);
14401440 }
@@ -1446,12 +1446,12 @@ static void ffs_data_reset(struct ffs_data *ffs) · 5 unmodified lines
14461446 ffs_data_clear(ffs);
14471447
14481448 ffs->epfiles = NULL;
1449+ ffs->raw_descs_data = NULL;
14491450 ffs->raw_descs = NULL;
14501451 ffs->raw_strings = NULL;
14511452 ffs->stringtabs = NULL;
14521453
1453− ffs->raw_fs_hs_descs_length = 0;
1454− ffs->raw_ss_descs_length = 0;
1454+ ffs->raw_descs_length = 0;
14551455 ffs->fs_descs_count = 0;
14561456 ffs->hs_descs_count = 0;
14571457 ffs->ss_descs_count = 0;
@@ -1865,89 +1865,76 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, · 407 unmodified lines
18651865 static int __ffs_data_got_descs(struct ffs_data *ffs,
18661866 char *const _data, size_t len)
18671867 {
1868− unsigned fs_count, hs_count, ss_count = 0;
1869− int fs_len, hs_len, ss_len, ret = -EINVAL;
1870− char *data = _data;
1868+ char *data = _data, *raw_descs;
1869+ unsigned counts[3], flags;
1870+ int ret = -EINVAL, i;
18711871
18721872 ENTER();
18731873
1874− if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_DESCRIPTORS_MAGIC ||
1875− get_unaligned_le32(data + 4) != len))
1874+ if (get_unaligned_le32(data + 4) != len)
18761875 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;
18821876
1883− if (likely(fs_count)) {
1884− fs_len = ffs_do_descs(fs_count, data, len,
1885− __ffs_data_do_entity, ffs);
1886− if (unlikely(fs_len < 0)) {
1887− ret = fs_len;
1877+ switch (get_unaligned_le32(data)) {
1878+ case FUNCTIONFS_DESCRIPTORS_MAGIC:
1879+ flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
1880+ data += 8;
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;
18881889 goto error;
18891890 }
1890−
1891− data += fs_len;
1892− len -= fs_len;
1893− } else {
1894− fs_len = 0;
1891+ data += 12;
1892+ len -= 12;
1893+ break;
1894+ default:
1895+ goto error;
18951896 }
18961897
1897− if (likely(hs_count)) {
1898− hs_len = ffs_do_descs(hs_count, data, len,
1899− __ffs_data_do_entity, ffs);
1900− if (unlikely(hs_len < 0)) {
1901− ret = hs_len;
1898+ /* Read fs_count, hs_count and ss_count (if present) */
1899+ for (i = 0; i < 3; ++i) {
1900+ if (!(flags & (1 << i))) {
1901+ counts[i] = 0;
1902+ } else if (len < 4) {
19021903 goto error;
1904+ } else {
1905+ counts[i] = get_unaligned_le32(data);
1906+ data += 4;
1907+ len -= 4;
19031908 }
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;
19191909 }
19201910
1921− if (!fs_count && !hs_count && !ss_count)
1922− goto einval;
1923−
1924− if (ss_count) {
1925− ss_len = ffs_do_descs(ss_count, data, len,
1911+ /* Read descriptors */
1912+ raw_descs = data;
1913+ for (i = 0; i < 3; ++i) {
1914+ if (!counts[i])
1915+ continue;
1916+ ret = ffs_do_descs(counts[i], data, len,
19261917 __ffs_data_do_entity, ffs);
1927− if (unlikely(ss_len < 0)) {
1928− ret = ss_len;
1918+ if (ret < 0)
19291919 goto error;
1930− }
1931− ret = ss_len;
1932− } else {
1933− ss_len = 0;
1934− ret = 0;
1920+ data += ret;
1921+ len -= ret;
19351922 }
19361923
1937− if (unlikely(len != ret))
1938− goto einval;
1924+ if (raw_descs == data || len) {
1925+ ret = -EINVAL;
1926+ goto error;
1927+ }
19391928
1940− ffs->raw_fs_hs_descs_length = fs_len + hs_len;
1941− ffs->raw_ss_descs_length = ss_len;
1942− ffs->raw_descs = _data;
1943− ffs->fs_descs_count = fs_count;
1944− ffs->hs_descs_count = hs_count;
1945− ffs->ss_descs_count = ss_count;
1929+ ffs->raw_descs_data = _data;
1930+ ffs->raw_descs = raw_descs;
1931+ ffs->raw_descs_length = data - raw_descs;
1932+ ffs->fs_descs_count = counts[0];
1933+ ffs->hs_descs_count = counts[1];
1934+ ffs->ss_descs_count = counts[2];
19461935
19471936 return 0;
19481937
1949−einval:
1950− ret = -EINVAL;
19511938 error:
19521939 kfree(_data);
19531940 return ret;
@@ -2359,8 +2346,7 @@ static int _ffs_func_bind(struct usb_configuration *c, · 405 unmodified lines
23592346 vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs,
23602347 super ? ffs->ss_descs_count + 1 : 0);
23612348 vla_item_with_sz(d, short, inums, ffs->interfaces_count);
2362− vla_item_with_sz(d, char, raw_descs,
2363− ffs->raw_fs_hs_descs_length + ffs->raw_ss_descs_length);
2349+ vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length);
23642350 char *vlabuf;
23652351
23662352 ENTER();
@@ -2376,15 +2362,9 @@ static int _ffs_func_bind(struct usb_configuration *c, · 9 unmodified lines
23762362
23772363 /* Zero */
23782364 memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz);
2379− /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */
2380− memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16,
2381− ffs->raw_fs_hs_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);
2365+ /* Copy descriptors */
2366+ memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs,
2367+ ffs->raw_descs_length);
23882368
23892369 memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
23902370 for (ret = ffs->eps_count; ret; --ret) {
drivers/usb/gadget/u_fs.h+5−7
@@ -206,15 +206,13 @@ struct ffs_data { · 205 unmodified lines
206206
207207 /* filled by __ffs_data_got_descs() */
208208 /*
209− * Real descriptors are 16 bytes after raw_descs (so you need
210− * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the
211− * first full speed descriptor).
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
209+ * raw_descs is what you kfree, real_descs points inside of raw_descs,
210+ * where full speed, high speed and super speed descriptors start.
211+ * real_descs_length is the length of all those descriptors.
214212 */
213+ const void *raw_descs_data;
215214 const void *raw_descs;
216− unsigned raw_fs_hs_descs_length;
217− unsigned raw_ss_descs_length;
215+ unsigned raw_descs_length;
218216 unsigned fs_descs_count;
219217 unsigned hs_descs_count;
220218 unsigned ss_descs_count;
include/uapi/linux/usb/functionfs.h+30−19
@@ -10,10 +10,15 @@ · 9 unmodified lines
1010
1111 enum {
1212 FUNCTIONFS_DESCRIPTORS_MAGIC = 1,
13− FUNCTIONFS_STRINGS_MAGIC = 2
13+ FUNCTIONFS_STRINGS_MAGIC = 2,
14+ FUNCTIONFS_DESCRIPTORS_MAGIC_V2 = 3,
1415 };
1516
16−#define FUNCTIONFS_SS_DESC_MAGIC 0x0055DE5C
17+enum functionfs_flags {
18+ FUNCTIONFS_HAS_FS_DESC = 1,
19+ FUNCTIONFS_HAS_HS_DESC = 2,
20+ FUNCTIONFS_HAS_SS_DESC = 4,
21+};
1722
1823 #ifndef __KERNEL__
1924
@@ -29,34 +34,40 @@ struct usb_endpoint_descriptor_no_audio { · 9 unmodified lines
2934 } __attribute__((packed));
3035
3136
32−/*
33− * All numbers must be in little endian order.
34− */
35−
36−struct usb_functionfs_descs_head {
37− __le32 magic;
38− __le32 length;
39− __le32 fs_count;
40− __le32 hs_count;
41−} __attribute__((packed));
42−
4337 /*
4438 * Descriptors format:
4539 *
4640 * | off | name | type | description |
4741 * |-----+-----------+--------------+--------------------------------------|
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 |
4961 * | 4 | length | LE32 | length of the whole data chunk |
5062 * | 8 | fs_count | LE32 | number of full-speed descriptors |
5163 * | 12 | hs_count | LE32 | number of high-speed descriptors |
5264 * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors |
5365 * | | 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 |
5766 *
58− * ss_magic: if present then it implies that SS_DESCs are also present
59− * descs are just valid USB descriptors and have the following format:
67+ * All numbers must be in little endian order.
68+ *
69+ * Descriptor[] is an array of valid USB descriptors which have the following
70+ * format:
6071 *
6172 * | off | name | type | description |
6273 * |-----+-----------------+------+--------------------------|