aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-11-17 16:42:24 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-18 13:51:01 -0500
commit86dc243cb2ddecb6984401463ebb0963ceff3cdc (patch)
treeb4d9e980c1c2333138b9d3a7b2285d19cf7c833d
parent0720a06a7518c9d0c0125bd5d1f3b6264c55c3dd (diff)
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>
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/usbstring.c73
2 files changed, 5 insertions, 69 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index b21cd376c11a..a11dbc85d08b 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -15,6 +15,7 @@
15 15
16menuconfig USB_GADGET 16menuconfig USB_GADGET
17 tristate "USB Gadget Support" 17 tristate "USB Gadget Support"
18 select NLS
18 help 19 help
19 USB is a master/slave protocol, organized with one master 20 USB is a master/slave protocol, organized with one master
20 host (such as a PC) controlling up to 127 peripheral devices. 21 host (such as a PC) controlling up to 127 peripheral devices.
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 58c4d37d312a..4d25b9009edf 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -13,82 +13,17 @@
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/nls.h>
16 17
17#include <linux/usb/ch9.h> 18#include <linux/usb/ch9.h>
18#include <linux/usb/gadget.h> 19#include <linux/usb/gadget.h>
19 20
20#include <asm/unaligned.h>
21
22
23static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
24{
25 int count = 0;
26 u8 c;
27 u16 uchar;
28
29 /* this insists on correct encodings, though not minimal ones.
30 * BUT it currently rejects legit 4-byte UTF-8 code points,
31 * which need surrogate pairs. (Unicode 3.1 can use them.)
32 */
33 while (len != 0 && (c = (u8) *s++) != 0) {
34 if (unlikely(c & 0x80)) {
35 // 2-byte sequence:
36 // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
37 if ((c & 0xe0) == 0xc0) {
38 uchar = (c & 0x1f) << 6;
39
40 c = (u8) *s++;
41 if ((c & 0xc0) != 0x80)
42 goto fail;
43 c &= 0x3f;
44 uchar |= c;
45
46 // 3-byte sequence (most CJKV characters):
47 // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
48 } else if ((c & 0xf0) == 0xe0) {
49 uchar = (c & 0x0f) << 12;
50
51 c = (u8) *s++;
52 if ((c & 0xc0) != 0x80)
53 goto fail;
54 c &= 0x3f;
55 uchar |= c << 6;
56
57 c = (u8) *s++;
58 if ((c & 0xc0) != 0x80)
59 goto fail;
60 c &= 0x3f;
61 uchar |= c;
62
63 /* no bogus surrogates */
64 if (0xd800 <= uchar && uchar <= 0xdfff)
65 goto fail;
66
67 // 4-byte sequence (surrogate pairs, currently rare):
68 // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
69 // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
70 // (uuuuu = wwww + 1)
71 // FIXME accept the surrogate code points (only)
72
73 } else
74 goto fail;
75 } else
76 uchar = c;
77 put_unaligned_le16(uchar, cp++);
78 count++;
79 len--;
80 }
81 return count;
82fail:
83 return -1;
84}
85
86 21
87/** 22/**
88 * usb_gadget_get_string - fill out a string descriptor 23 * usb_gadget_get_string - fill out a string descriptor
89 * @table: of c strings encoded using UTF-8 24 * @table: of c strings encoded using UTF-8
90 * @id: string id, from low byte of wValue in get string descriptor 25 * @id: string id, from low byte of wValue in get string descriptor
91 * @buf: at least 256 bytes 26 * @buf: at least 256 bytes, must be 16-bit aligned
92 * 27 *
93 * Finds the UTF-8 string matching the ID, and converts it into a 28 * Finds the UTF-8 string matching the ID, and converts it into a
94 * string descriptor in utf16-le. 29 * string descriptor in utf16-le.
@@ -125,8 +60,8 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)
125 60
126 /* string descriptors have length, tag, then UTF16-LE text */ 61 /* string descriptors have length, tag, then UTF16-LE text */
127 len = min ((size_t) 126, strlen (s->s)); 62 len = min ((size_t) 126, strlen (s->s));
128 memset (buf + 2, 0, 2 * len); /* zero all the bytes */ 63 len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN,
129 len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len); 64 (wchar_t *) &buf[2], 126);
130 if (len < 0) 65 if (len < 0)
131 return -EINVAL; 66 return -EINVAL;
132 buf [0] = (len + 1) * 2; 67 buf [0] = (len + 1) * 2;