diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-04-30 10:08:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:43 -0400 |
commit | 74675a58507e769beee7d949dbed788af3c4139d (patch) | |
tree | d4ae3cc06dbfadecf1eaf6ed0aef249fc87b07e6 /drivers/usb | |
parent | a853a3d4eb2edb066248a39f0634f6f5858816a0 (diff) |
NLS: update handling of Unicode
This patch (as1239) updates the kernel's treatment of Unicode. The
character-set conversion routines are well behind the current state of
the Unicode specification: They don't recognize the existence of code
points beyond plane 0 or of surrogate pairs in the UTF-16 encoding.
The old wchar_t 16-bit type is retained because it's still used in
lots of places. This shouldn't cause any new problems; if a
conversion now results in an invalid 16-bit code then before it must
have yielded an undefined code.
Difficult-to-read names like "utf_mbstowcs" are replaced with more
transparent names like "utf8s_to_utf16s" and the ordering of the
parameters is rationalized (buffer lengths come immediate after the
pointers they refer to, and the inputs precede the outputs).
Fortunately the low-level conversion routines are used in only a few
places; the interfaces to the higher-level uni2char and char2uni
methods have been left unchanged.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/message.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index e98f928c08ea..9bd26dec7599 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -780,14 +780,13 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
780 | { | 780 | { |
781 | unsigned char *tbuf; | 781 | unsigned char *tbuf; |
782 | int err; | 782 | int err; |
783 | unsigned int u; | ||
784 | 783 | ||
785 | if (dev->state == USB_STATE_SUSPENDED) | 784 | if (dev->state == USB_STATE_SUSPENDED) |
786 | return -EHOSTUNREACH; | 785 | return -EHOSTUNREACH; |
787 | if (size <= 0 || !buf || !index) | 786 | if (size <= 0 || !buf || !index) |
788 | return -EINVAL; | 787 | return -EINVAL; |
789 | buf[0] = 0; | 788 | buf[0] = 0; |
790 | tbuf = kmalloc(256 + 2, GFP_NOIO); | 789 | tbuf = kmalloc(256, GFP_NOIO); |
791 | if (!tbuf) | 790 | if (!tbuf) |
792 | return -ENOMEM; | 791 | return -ENOMEM; |
793 | 792 | ||
@@ -814,12 +813,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
814 | if (err < 0) | 813 | if (err < 0) |
815 | goto errout; | 814 | goto errout; |
816 | 815 | ||
817 | for (u = 2; u < err; u += 2) | ||
818 | le16_to_cpus((u16 *)&tbuf[u]); | ||
819 | tbuf[u] = 0; | ||
820 | tbuf[u + 1] = 0; | ||
821 | size--; /* leave room for trailing NULL char in output buffer */ | 816 | size--; /* leave room for trailing NULL char in output buffer */ |
822 | err = utf8_wcstombs(buf, (u16 *)&tbuf[2], size); | 817 | err = utf16s_to_utf8s((wchar_t *) &tbuf[2], (err - 2) / 2, |
818 | UTF16_LITTLE_ENDIAN, buf, size); | ||
823 | buf[err] = 0; | 819 | buf[err] = 0; |
824 | 820 | ||
825 | if (tbuf[1] != USB_DT_STRING) | 821 | if (tbuf[1] != USB_DT_STRING) |