diff options
Diffstat (limited to 'patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch')
-rw-r--r-- | patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch b/patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch new file mode 100644 index 00000000000..8b16186c25f --- /dev/null +++ b/patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch @@ -0,0 +1,220 @@ +From 07849f42588dc9517c871579cd0a3f7f373e0a7c Mon Sep 17 00:00:00 2001 +From: Andrzej Pietrasiewicz <andrzej.p@samsung.com> +Date: Tue, 3 Dec 2013 15:15:30 +0100 +Subject: [PATCH 1169/1302] usb: gadget: FunctionFS: Remove VLAIS usage from + gadget code + +The use of variable length arrays in structs (VLAIS) in the Linux Kernel code +precludes the use of compilers which don't implement VLAIS (for instance the +Clang compiler). This alternate patch calculates offsets into the kmalloc-ed +memory buffer using macros. The previous patch required multiple kmalloc and +kfree calls. This version uses "group" vs "struct" since it really is not a +struct and is essentially a group of VLA in a common allocated block. This +version also fixes the issues pointed out by Andrzej Pietrasiewicz and +Michal Nazarewicz. + +Signed-off-by: Mark Charlebois <charlebm@gmail.com> +Signed-off-by: Behan Webster <behanw@converseincode.com> + +[elimination of miexed declaration and code, checkpatch cleanup] +[fixes after Michal's review] +Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> +Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> +Acked-by: Michal Nazarewicz <mina86@mina86.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> + +Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com> +--- + drivers/usb/gadget/f_fs.c | 116 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 76 insertions(+), 40 deletions(-) + +diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c +index 6453304..609ed50 100644 +--- a/drivers/usb/gadget/f_fs.c ++++ b/drivers/usb/gadget/f_fs.c +@@ -30,6 +30,31 @@ + + #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ + ++/* Variable Length Array Macros **********************************************/ ++#define vla_group(groupname) size_t groupname##__next = 0 ++#define vla_group_size(groupname) groupname##__next ++ ++#define vla_item(groupname, type, name, n) \ ++ size_t groupname##_##name##__offset = ({ \ ++ size_t align_mask = __alignof__(type) - 1; \ ++ size_t offset = (groupname##__next + align_mask) & ~align_mask;\ ++ size_t size = (n) * sizeof(type); \ ++ groupname##__next = offset + size; \ ++ offset; \ ++ }) ++ ++#define vla_item_with_sz(groupname, type, name, n) \ ++ size_t groupname##_##name##__sz = (n) * sizeof(type); \ ++ size_t groupname##_##name##__offset = ({ \ ++ size_t align_mask = __alignof__(type) - 1; \ ++ size_t offset = (groupname##__next + align_mask) & ~align_mask;\ ++ size_t size = groupname##_##name##__sz; \ ++ groupname##__next = offset + size; \ ++ offset; \ ++ }) ++ ++#define vla_ptr(ptr, groupname, name) \ ++ ((void *) ((char *)ptr + groupname##_##name##__offset)) + + /* Debugging ****************************************************************/ + +@@ -1902,30 +1927,34 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, + + /* Allocate everything in one chunk so there's less maintenance. */ + { +- struct { +- struct usb_gadget_strings *stringtabs[lang_count + 1]; +- struct usb_gadget_strings stringtab[lang_count]; +- struct usb_string strings[lang_count*(needed_count+1)]; +- } *d; + unsigned i = 0; ++ vla_group(d); ++ vla_item(d, struct usb_gadget_strings *, stringtabs, ++ lang_count + 1); ++ vla_item(d, struct usb_gadget_strings, stringtab, lang_count); ++ vla_item(d, struct usb_string, strings, ++ lang_count*(needed_count+1)); + +- d = kmalloc(sizeof *d, GFP_KERNEL); +- if (unlikely(!d)) { ++ char *vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL); ++ ++ if (unlikely(!vlabuf)) { + kfree(_data); + return -ENOMEM; + } + +- stringtabs = d->stringtabs; +- t = d->stringtab; ++ /* Initialize the VLA pointers */ ++ stringtabs = vla_ptr(vlabuf, d, stringtabs); ++ t = vla_ptr(vlabuf, d, stringtab); + i = lang_count; + do { + *stringtabs++ = t++; + } while (--i); + *stringtabs = NULL; + +- stringtabs = d->stringtabs; +- t = d->stringtab; +- s = d->strings; ++ /* stringtabs = vlabuf = d_stringtabs for later kfree */ ++ stringtabs = vla_ptr(vlabuf, d, stringtabs); ++ t = vla_ptr(vlabuf, d, stringtab); ++ s = vla_ptr(vlabuf, d, strings); + strings = s; + } + +@@ -2201,16 +2230,16 @@ static int ffs_func_bind(struct usb_configuration *c, + int ret; + + /* Make it a single chunk, less management later on */ +- struct { +- struct ffs_ep eps[ffs->eps_count]; +- struct usb_descriptor_header +- *fs_descs[full ? ffs->fs_descs_count + 1 : 0]; +- struct usb_descriptor_header +- *hs_descs[high ? ffs->hs_descs_count + 1 : 0]; +- short inums[ffs->interfaces_count]; +- char raw_descs[high ? ffs->raw_descs_length +- : ffs->raw_fs_descs_length]; +- } *data; ++ vla_group(d); ++ vla_item_with_sz(d, struct ffs_ep, eps, ffs->eps_count); ++ vla_item_with_sz(d, struct usb_descriptor_header *, fs_descs, ++ full ? ffs->fs_descs_count + 1 : 0); ++ vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs, ++ high ? ffs->hs_descs_count + 1 : 0); ++ vla_item_with_sz(d, short, inums, ffs->interfaces_count); ++ vla_item_with_sz(d, char, raw_descs, ++ high ? ffs->raw_descs_length : ffs->raw_fs_descs_length); ++ char *vlabuf; + + ENTER(); + +@@ -2218,21 +2247,28 @@ static int ffs_func_bind(struct usb_configuration *c, + if (unlikely(!(full | high))) + return -ENOTSUPP; + +- /* Allocate */ +- data = kmalloc(sizeof *data, GFP_KERNEL); +- if (unlikely(!data)) ++ /* Allocate a single chunk, less management later on */ ++ vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL); ++ if (unlikely(!vlabuf)) + return -ENOMEM; + + /* Zero */ +- memset(data->eps, 0, sizeof data->eps); +- memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs); +- memset(data->inums, 0xff, sizeof data->inums); +- for (ret = ffs->eps_count; ret; --ret) +- data->eps[ret].num = -1; ++ memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); ++ memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16, ++ d_raw_descs__sz); ++ memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); ++ for (ret = ffs->eps_count; ret; --ret) { ++ struct ffs_ep *ptr; ++ ++ ptr = vla_ptr(vlabuf, d, eps); ++ ptr[ret].num = -1; ++ } + +- /* Save pointers */ +- func->eps = data->eps; +- func->interfaces_nums = data->inums; ++ /* Save pointers ++ * d_eps == vlabuf, func->eps used to kfree vlabuf later ++ */ ++ func->eps = vla_ptr(vlabuf, d, eps); ++ func->interfaces_nums = vla_ptr(vlabuf, d, inums); + + /* + * Go through all the endpoint descriptors and allocate +@@ -2240,10 +2276,10 @@ static int ffs_func_bind(struct usb_configuration *c, + * numbers without worrying that it may be described later on. + */ + if (likely(full)) { +- func->function.fs_descriptors = data->fs_descs; ++ func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs); + ret = ffs_do_descs(ffs->fs_descs_count, +- data->raw_descs, +- sizeof data->raw_descs, ++ vla_ptr(vlabuf, d, raw_descs), ++ d_raw_descs__sz, + __ffs_func_bind_do_descs, func); + if (unlikely(ret < 0)) + goto error; +@@ -2252,10 +2288,10 @@ static int ffs_func_bind(struct usb_configuration *c, + } + + if (likely(high)) { +- func->function.hs_descriptors = data->hs_descs; ++ func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs); + ret = ffs_do_descs(ffs->hs_descs_count, +- data->raw_descs + ret, +- (sizeof data->raw_descs) - ret, ++ vla_ptr(vlabuf, d, raw_descs) + ret, ++ d_raw_descs__sz - ret, + __ffs_func_bind_do_descs, func); + if (unlikely(ret < 0)) + goto error; +@@ -2268,7 +2304,7 @@ static int ffs_func_bind(struct usb_configuration *c, + */ + ret = ffs_do_descs(ffs->fs_descs_count + + (high ? ffs->hs_descs_count : 0), +- data->raw_descs, sizeof data->raw_descs, ++ vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz, + __ffs_func_bind_do_nums, func); + if (unlikely(ret < 0)) + goto error; +-- +1.8.3.2 + |