diff options
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 64 |
1 files changed, 27 insertions, 37 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 3d132cb..fa671a8 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1882,13 +1882,20 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, char *const _data, size_t len) { u32 str_count, needed_count, lang_count; - struct usb_gadget_strings **stringtabs, *t; - struct usb_string *strings, *s; + struct usb_gadget_strings **stringtabspp, *t; + struct usb_string *stringsp, *s; const char *data = _data; + unsigned i = 0; - ENTER(); + 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; + ENTER(); if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC || + get_unaligned_le32(data + 4) != len)) goto error; str_count = get_unaligned_le32(data + 8); @@ -1897,12 +1904,10 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, /* if one is zero the other must be zero */ if (unlikely(!str_count != !lang_count)) goto error; - /* Do we have at least as many strings as descriptors need? */ needed_count = ffs->strings_count; if (unlikely(str_count < needed_count)) goto error; - /* * If we don't need any strings just return and free all * memory. @@ -1912,34 +1917,22 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, return 0; } - /* 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; - - d = kmalloc(sizeof *d, GFP_KERNEL); - if (unlikely(!d)) { - kfree(_data); - return -ENOMEM; - } - - stringtabs = d->stringtabs; - t = d->stringtab; - i = lang_count; - do { - *stringtabs++ = t++; - } while (--i); - *stringtabs = NULL; - - stringtabs = d->stringtabs; - t = d->stringtab; - s = d->strings; - strings = s; + d = kmalloc(sizeof *d, GFP_KERNEL); + if (unlikely(!d)) { + kfree(_data); + return -ENOMEM; } + stringtabspp = d->stringtabs; + t = d->stringtab; + i = lang_count; + do { + *stringtabspp++ = t++; + } while (--i); + *stringtabspp = NULL; + stringtabspp = d->stringtabs; + t = d->stringtab; + s = d->strings; + stringsp = s; /* For each language */ data += 16; @@ -1987,7 +1980,6 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, s->id = 0; /* terminator */ s->s = NULL; ++s; - } while (--lang_count); /* Some garbage left? */ @@ -1995,19 +1987,17 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, goto error_free; /* Done! */ - ffs->stringtabs = stringtabs; + ffs->stringtabs = stringtabspp; ffs->raw_strings = _data; return 0; - error_free: - kfree(stringtabs); + kfree(stringtabspp); error: kfree(_data); return -EINVAL; } - /* Events handling and management *******************************************/ static void __ffs_event_add(struct ffs_data *ffs, |