diff options
Diffstat (limited to 'drivers/usb/gadget/usbstring.c')
| -rw-r--r-- | drivers/usb/gadget/usbstring.c | 77 | 
1 files changed, 6 insertions, 71 deletions
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 58c4d37d312..73a4dfba0ed 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -9,86 +9,21 @@  #include <linux/errno.h>  #include <linux/kernel.h> +#include <linux/module.h>  #include <linux/list.h>  #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,12 +60,12 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)  	/* 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;  	buf [1] = USB_DT_STRING;  	return buf [0];  } - +EXPORT_SYMBOL_GPL(usb_gadget_get_string);  | 
