aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorManu Gautam <mgautam@codeaurora.org>2014-02-28 06:20:22 -0500
committerFelipe Balbi <balbi@ti.com>2014-03-05 15:40:10 -0500
commit8d4e897bd0150fab594a871484e554472ee01452 (patch)
tree4dd06a720883cb617afd64df0146285a22d70282 /drivers/usb/gadget
parentd8eb6c653ef6b323d630de3c5685478469e248bc (diff)
usb: gadget: f_fs: Add support for SuperSpeed Mode
Allow userspace to pass SuperSpeed descriptors and handle them in the driver accordingly. This change doesn't modify existing desc_header and thereby keeps the ABI changes backward compatible i.e. existing userspace drivers compiled with old header (functionfs.h) would continue to work with the updated kernel. Signed-off-by: Manu Gautam <mgautam@codeaurora.org> Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/f_fs.c182
-rw-r--r--drivers/usb/gadget/u_fs.h10
2 files changed, 142 insertions, 50 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 1ae741fdace0..66f60b9a34a2 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -134,8 +134,8 @@ struct ffs_ep {
134 struct usb_ep *ep; /* P: ffs->eps_lock */ 134 struct usb_ep *ep; /* P: ffs->eps_lock */
135 struct usb_request *req; /* P: epfile->mutex */ 135 struct usb_request *req; /* P: epfile->mutex */
136 136
137 /* [0]: full speed, [1]: high speed */ 137 /* [0]: full speed, [1]: high speed, [2]: super speed */
138 struct usb_endpoint_descriptor *descs[2]; 138 struct usb_endpoint_descriptor *descs[3];
139 139
140 u8 num; 140 u8 num;
141 141
@@ -1450,10 +1450,11 @@ static void ffs_data_reset(struct ffs_data *ffs)
1450 ffs->raw_strings = NULL; 1450 ffs->raw_strings = NULL;
1451 ffs->stringtabs = NULL; 1451 ffs->stringtabs = NULL;
1452 1452
1453 ffs->raw_descs_length = 0; 1453 ffs->raw_fs_hs_descs_length = 0;
1454 ffs->raw_fs_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 1458
1458 ffs->strings_count = 0; 1459 ffs->strings_count = 0;
1459 ffs->interfaces_count = 0; 1460 ffs->interfaces_count = 0;
@@ -1596,7 +1597,24 @@ static int ffs_func_eps_enable(struct ffs_function *func)
1596 spin_lock_irqsave(&func->ffs->eps_lock, flags); 1597 spin_lock_irqsave(&func->ffs->eps_lock, flags);
1597 do { 1598 do {
1598 struct usb_endpoint_descriptor *ds; 1599 struct usb_endpoint_descriptor *ds;
1599 ds = ep->descs[ep->descs[1] ? 1 : 0]; 1600 int desc_idx;
1601
1602 if (ffs->gadget->speed == USB_SPEED_SUPER)
1603 desc_idx = 2;
1604 else if (ffs->gadget->speed == USB_SPEED_HIGH)
1605 desc_idx = 1;
1606 else
1607 desc_idx = 0;
1608
1609 /* fall-back to lower speed if desc missing for current speed */
1610 do {
1611 ds = ep->descs[desc_idx];
1612 } while (!ds && --desc_idx >= 0);
1613
1614 if (!ds) {
1615 ret = -EINVAL;
1616 break;
1617 }
1600 1618
1601 ep->ep->driver_data = ep; 1619 ep->ep->driver_data = ep;
1602 ep->ep->desc = ds; 1620 ep->ep->desc = ds;
@@ -1731,6 +1749,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
1731 } 1749 }
1732 break; 1750 break;
1733 1751
1752 case USB_DT_SS_ENDPOINT_COMP:
1753 pr_vdebug("EP SS companion descriptor\n");
1754 if (length != sizeof(struct usb_ss_ep_comp_descriptor))
1755 goto inv_length;
1756 break;
1757
1734 case USB_DT_OTHER_SPEED_CONFIG: 1758 case USB_DT_OTHER_SPEED_CONFIG:
1735 case USB_DT_INTERFACE_POWER: 1759 case USB_DT_INTERFACE_POWER:
1736 case USB_DT_DEBUG: 1760 case USB_DT_DEBUG:
@@ -1841,8 +1865,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
1841static int __ffs_data_got_descs(struct ffs_data *ffs, 1865static int __ffs_data_got_descs(struct ffs_data *ffs,
1842 char *const _data, size_t len) 1866 char *const _data, size_t len)
1843{ 1867{
1844 unsigned fs_count, hs_count; 1868 unsigned fs_count, hs_count, ss_count = 0;
1845 int fs_len, ret = -EINVAL; 1869 int fs_len, hs_len, ss_len, ret = -EINVAL;
1846 char *data = _data; 1870 char *data = _data;
1847 1871
1848 ENTER(); 1872 ENTER();
@@ -1853,9 +1877,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
1853 fs_count = get_unaligned_le32(data + 8); 1877 fs_count = get_unaligned_le32(data + 8);
1854 hs_count = get_unaligned_le32(data + 12); 1878 hs_count = get_unaligned_le32(data + 12);
1855 1879
1856 if (!fs_count && !hs_count)
1857 goto einval;
1858
1859 data += 16; 1880 data += 16;
1860 len -= 16; 1881 len -= 16;
1861 1882
@@ -1874,22 +1895,54 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
1874 } 1895 }
1875 1896
1876 if (likely(hs_count)) { 1897 if (likely(hs_count)) {
1877 ret = ffs_do_descs(hs_count, data, len, 1898 hs_len = ffs_do_descs(hs_count, data, len,
1878 __ffs_data_do_entity, ffs); 1899 __ffs_data_do_entity, ffs);
1879 if (unlikely(ret < 0)) 1900 if (unlikely(hs_len < 0)) {
1901 ret = hs_len;
1902 goto error;
1903 }
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 }
1920
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,
1926 __ffs_data_do_entity, ffs);
1927 if (unlikely(ss_len < 0)) {
1928 ret = ss_len;
1880 goto error; 1929 goto error;
1930 }
1931 ret = ss_len;
1881 } else { 1932 } else {
1933 ss_len = 0;
1882 ret = 0; 1934 ret = 0;
1883 } 1935 }
1884 1936
1885 if (unlikely(len != ret)) 1937 if (unlikely(len != ret))
1886 goto einval; 1938 goto einval;
1887 1939
1888 ffs->raw_fs_descs_length = fs_len; 1940 ffs->raw_fs_hs_descs_length = fs_len + hs_len;
1889 ffs->raw_descs_length = fs_len + ret; 1941 ffs->raw_ss_descs_length = ss_len;
1890 ffs->raw_descs = _data; 1942 ffs->raw_descs = _data;
1891 ffs->fs_descs_count = fs_count; 1943 ffs->fs_descs_count = fs_count;
1892 ffs->hs_descs_count = hs_count; 1944 ffs->hs_descs_count = hs_count;
1945 ffs->ss_descs_count = ss_count;
1893 1946
1894 return 0; 1947 return 0;
1895 1948
@@ -2112,21 +2165,28 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
2112 struct usb_endpoint_descriptor *ds = (void *)desc; 2165 struct usb_endpoint_descriptor *ds = (void *)desc;
2113 struct ffs_function *func = priv; 2166 struct ffs_function *func = priv;
2114 struct ffs_ep *ffs_ep; 2167 struct ffs_ep *ffs_ep;
2115 2168 unsigned ep_desc_id, idx;
2116 /* 2169 static const char *speed_names[] = { "full", "high", "super" };
2117 * If hs_descriptors is not NULL then we are reading hs
2118 * descriptors now
2119 */
2120 const int isHS = func->function.hs_descriptors != NULL;
2121 unsigned idx;
2122 2170
2123 if (type != FFS_DESCRIPTOR) 2171 if (type != FFS_DESCRIPTOR)
2124 return 0; 2172 return 0;
2125 2173
2126 if (isHS) 2174 /*
2175 * If ss_descriptors is not NULL, we are reading super speed
2176 * descriptors; if hs_descriptors is not NULL, we are reading high
2177 * speed descriptors; otherwise, we are reading full speed
2178 * descriptors.
2179 */
2180 if (func->function.ss_descriptors) {
2181 ep_desc_id = 2;
2182 func->function.ss_descriptors[(long)valuep] = desc;
2183 } else if (func->function.hs_descriptors) {
2184 ep_desc_id = 1;
2127 func->function.hs_descriptors[(long)valuep] = desc; 2185 func->function.hs_descriptors[(long)valuep] = desc;
2128 else 2186 } else {
2187 ep_desc_id = 0;
2129 func->function.fs_descriptors[(long)valuep] = desc; 2188 func->function.fs_descriptors[(long)valuep] = desc;
2189 }
2130 2190
2131 if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) 2191 if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
2132 return 0; 2192 return 0;
@@ -2134,13 +2194,13 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
2134 idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; 2194 idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1;
2135 ffs_ep = func->eps + idx; 2195 ffs_ep = func->eps + idx;
2136 2196
2137 if (unlikely(ffs_ep->descs[isHS])) { 2197 if (unlikely(ffs_ep->descs[ep_desc_id])) {
2138 pr_vdebug("two %sspeed descriptors for EP %d\n", 2198 pr_err("two %sspeed descriptors for EP %d\n",
2139 isHS ? "high" : "full", 2199 speed_names[ep_desc_id],
2140 ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); 2200 ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
2141 return -EINVAL; 2201 return -EINVAL;
2142 } 2202 }
2143 ffs_ep->descs[isHS] = ds; 2203 ffs_ep->descs[ep_desc_id] = ds;
2144 2204
2145 ffs_dump_mem(": Original ep desc", ds, ds->bLength); 2205 ffs_dump_mem(": Original ep desc", ds, ds->bLength);
2146 if (ffs_ep->ep) { 2206 if (ffs_ep->ep) {
@@ -2284,8 +2344,10 @@ static int _ffs_func_bind(struct usb_configuration *c,
2284 const int full = !!func->ffs->fs_descs_count; 2344 const int full = !!func->ffs->fs_descs_count;
2285 const int high = gadget_is_dualspeed(func->gadget) && 2345 const int high = gadget_is_dualspeed(func->gadget) &&
2286 func->ffs->hs_descs_count; 2346 func->ffs->hs_descs_count;
2347 const int super = gadget_is_superspeed(func->gadget) &&
2348 func->ffs->ss_descs_count;
2287 2349
2288 int ret; 2350 int fs_len, hs_len, ret;
2289 2351
2290 /* Make it a single chunk, less management later on */ 2352 /* Make it a single chunk, less management later on */
2291 vla_group(d); 2353 vla_group(d);
@@ -2294,15 +2356,17 @@ static int _ffs_func_bind(struct usb_configuration *c,
2294 full ? ffs->fs_descs_count + 1 : 0); 2356 full ? ffs->fs_descs_count + 1 : 0);
2295 vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs, 2357 vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs,
2296 high ? ffs->hs_descs_count + 1 : 0); 2358 high ? ffs->hs_descs_count + 1 : 0);
2359 vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs,
2360 super ? ffs->ss_descs_count + 1 : 0);
2297 vla_item_with_sz(d, short, inums, ffs->interfaces_count); 2361 vla_item_with_sz(d, short, inums, ffs->interfaces_count);
2298 vla_item_with_sz(d, char, raw_descs, 2362 vla_item_with_sz(d, char, raw_descs,
2299 high ? ffs->raw_descs_length : ffs->raw_fs_descs_length); 2363 ffs->raw_fs_hs_descs_length + ffs->raw_ss_descs_length);
2300 char *vlabuf; 2364 char *vlabuf;
2301 2365
2302 ENTER(); 2366 ENTER();
2303 2367
2304 /* Only high speed but not supported by gadget? */ 2368 /* Has descriptors only for speeds gadget does not support */
2305 if (unlikely(!(full | high))) 2369 if (unlikely(!(full | high | super)))
2306 return -ENOTSUPP; 2370 return -ENOTSUPP;
2307 2371
2308 /* Allocate a single chunk, less management later on */ 2372 /* Allocate a single chunk, less management later on */
@@ -2312,8 +2376,16 @@ static int _ffs_func_bind(struct usb_configuration *c,
2312 2376
2313 /* Zero */ 2377 /* Zero */
2314 memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); 2378 memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz);
2379 /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */
2315 memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16, 2380 memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16,
2316 d_raw_descs__sz); 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);
2388
2317 memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); 2389 memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
2318 for (ret = ffs->eps_count; ret; --ret) { 2390 for (ret = ffs->eps_count; ret; --ret) {
2319 struct ffs_ep *ptr; 2391 struct ffs_ep *ptr;
@@ -2335,22 +2407,38 @@ static int _ffs_func_bind(struct usb_configuration *c,
2335 */ 2407 */
2336 if (likely(full)) { 2408 if (likely(full)) {
2337 func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs); 2409 func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs);
2338 ret = ffs_do_descs(ffs->fs_descs_count, 2410 fs_len = ffs_do_descs(ffs->fs_descs_count,
2339 vla_ptr(vlabuf, d, raw_descs), 2411 vla_ptr(vlabuf, d, raw_descs),
2340 d_raw_descs__sz, 2412 d_raw_descs__sz,
2341 __ffs_func_bind_do_descs, func); 2413 __ffs_func_bind_do_descs, func);
2342 if (unlikely(ret < 0)) 2414 if (unlikely(fs_len < 0)) {
2415 ret = fs_len;
2343 goto error; 2416 goto error;
2417 }
2344 } else { 2418 } else {
2345 ret = 0; 2419 fs_len = 0;
2346 } 2420 }
2347 2421
2348 if (likely(high)) { 2422 if (likely(high)) {
2349 func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs); 2423 func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs);
2350 ret = ffs_do_descs(ffs->hs_descs_count, 2424 hs_len = ffs_do_descs(ffs->hs_descs_count,
2351 vla_ptr(vlabuf, d, raw_descs) + ret, 2425 vla_ptr(vlabuf, d, raw_descs) + fs_len,
2352 d_raw_descs__sz - ret, 2426 d_raw_descs__sz - fs_len,
2353 __ffs_func_bind_do_descs, func); 2427 __ffs_func_bind_do_descs, func);
2428 if (unlikely(hs_len < 0)) {
2429 ret = hs_len;
2430 goto error;
2431 }
2432 } else {
2433 hs_len = 0;
2434 }
2435
2436 if (likely(super)) {
2437 func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs);
2438 ret = ffs_do_descs(ffs->ss_descs_count,
2439 vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len,
2440 d_raw_descs__sz - fs_len - hs_len,
2441 __ffs_func_bind_do_descs, func);
2354 if (unlikely(ret < 0)) 2442 if (unlikely(ret < 0))
2355 goto error; 2443 goto error;
2356 } 2444 }
@@ -2361,7 +2449,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
2361 * now. 2449 * now.
2362 */ 2450 */
2363 ret = ffs_do_descs(ffs->fs_descs_count + 2451 ret = ffs_do_descs(ffs->fs_descs_count +
2364 (high ? ffs->hs_descs_count : 0), 2452 (high ? ffs->hs_descs_count : 0) +
2453 (super ? ffs->ss_descs_count : 0),
2365 vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz, 2454 vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz,
2366 __ffs_func_bind_do_nums, func); 2455 __ffs_func_bind_do_nums, func);
2367 if (unlikely(ret < 0)) 2456 if (unlikely(ret < 0))
@@ -2708,6 +2797,7 @@ static void ffs_func_unbind(struct usb_configuration *c,
2708 */ 2797 */
2709 func->function.fs_descriptors = NULL; 2798 func->function.fs_descriptors = NULL;
2710 func->function.hs_descriptors = NULL; 2799 func->function.hs_descriptors = NULL;
2800 func->function.ss_descriptors = NULL;
2711 func->interfaces_nums = NULL; 2801 func->interfaces_nums = NULL;
2712 2802
2713 ffs_event_add(ffs, FUNCTIONFS_UNBIND); 2803 ffs_event_add(ffs, FUNCTIONFS_UNBIND);
diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
index c39e805025b9..0deb6d5f7c35 100644
--- a/drivers/usb/gadget/u_fs.h
+++ b/drivers/usb/gadget/u_fs.h
@@ -208,14 +208,16 @@ struct ffs_data {
208 /* 208 /*
209 * Real descriptors are 16 bytes after raw_descs (so you need 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 210 * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the
211 * first full speed descriptor). raw_descs_length and 211 * first full speed descriptor).
212 * raw_fs_descs_length do not have those 16 bytes added. 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
213 */ 214 */
214 const void *raw_descs; 215 const void *raw_descs;
215 unsigned raw_descs_length; 216 unsigned raw_fs_hs_descs_length;
216 unsigned raw_fs_descs_length; 217 unsigned raw_ss_descs_length;
217 unsigned fs_descs_count; 218 unsigned fs_descs_count;
218 unsigned hs_descs_count; 219 unsigned hs_descs_count;
220 unsigned ss_descs_count;
219 221
220 unsigned short strings_count; 222 unsigned short strings_count;
221 unsigned short interfaces_count; 223 unsigned short interfaces_count;