USB: remove homegrown UTF conversion routine for gadgets

This patch (as1502) removes the UTF8-to-UTF16 conversion routine in
the USB gadget library and replaces it with a call to the equivalent
function in the NLS library.

The only downside worth noting is that the NLS library routine
requires the output buffer to be 16-bit aligned.  This is always true
in the gadget code, because the output buffer is always a
usb_request buffer being used to send a string descriptor.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 58c4d37..4d25b90 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -13,82 +13,17 @@
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/nls.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
-#include <asm/unaligned.h>
-
-
-static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
-{
-	int	count = 0;
-	u8	c;
-	u16	uchar;
-
-	/* this insists on correct encodings, though not minimal ones.
-	 * BUT it currently rejects legit 4-byte UTF-8 code points,
-	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
-	 */
-	while (len != 0 && (c = (u8) *s++) != 0) {
-		if (unlikely(c & 0x80)) {
-			// 2-byte sequence:
-			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-			if ((c & 0xe0) == 0xc0) {
-				uchar = (c & 0x1f) << 6;
-
-				c = (u8) *s++;
-				if ((c & 0xc0) != 0x80)
-					goto fail;
-				c &= 0x3f;
-				uchar |= c;
-
-			// 3-byte sequence (most CJKV characters):
-			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-			} else if ((c & 0xf0) == 0xe0) {
-				uchar = (c & 0x0f) << 12;
-
-				c = (u8) *s++;
-				if ((c & 0xc0) != 0x80)
-					goto fail;
-				c &= 0x3f;
-				uchar |= c << 6;
-
-				c = (u8) *s++;
-				if ((c & 0xc0) != 0x80)
-					goto fail;
-				c &= 0x3f;
-				uchar |= c;
-
-				/* no bogus surrogates */
-				if (0xd800 <= uchar && uchar <= 0xdfff)
-					goto fail;
-
-			// 4-byte sequence (surrogate pairs, currently rare):
-			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-			// (uuuuu = wwww + 1)
-			// FIXME accept the surrogate code points (only)
-
-			} else
-				goto fail;
-		} else
-			uchar = c;
-		put_unaligned_le16(uchar, cp++);
-		count++;
-		len--;
-	}
-	return count;
-fail:
-	return -1;
-}
-
 
 /**
  * usb_gadget_get_string - fill out a string descriptor 
  * @table: of c strings encoded using UTF-8
  * @id: string id, from low byte of wValue in get string descriptor
- * @buf: at least 256 bytes
+ * @buf: at least 256 bytes, must be 16-bit aligned
  *
  * Finds the UTF-8 string matching the ID, and converts it into a
  * string descriptor in utf16-le.
@@ -125,8 +60,8 @@
 
 	/* string descriptors have length, tag, then UTF16-LE text */
 	len = min ((size_t) 126, strlen (s->s));
-	memset (buf + 2, 0, 2 * len);	/* zero all the bytes */
-	len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len);
+	len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN,
+			(wchar_t *) &buf[2], 126);
 	if (len < 0)
 		return -EINVAL;
 	buf [0] = (len + 1) * 2;