Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 2003 David Brownell | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU Lesser General Public License as published | |
6 | * by the Free Software Foundation; either version 2.1 of the License, or | |
7 | * (at your option) any later version. | |
8 | */ | |
9 | ||
10 | #include <linux/errno.h> | |
11 | #include <linux/kernel.h> | |
a84d9e53 | 12 | #include <linux/module.h> |
1da177e4 LT |
13 | #include <linux/list.h> |
14 | #include <linux/string.h> | |
15 | #include <linux/device.h> | |
86dc243c | 16 | #include <linux/nls.h> |
1da177e4 | 17 | |
5f848137 | 18 | #include <linux/usb/ch9.h> |
9454a57a | 19 | #include <linux/usb/gadget.h> |
1da177e4 | 20 | |
1da177e4 LT |
21 | |
22 | /** | |
23 | * usb_gadget_get_string - fill out a string descriptor | |
24 | * @table: of c strings encoded using UTF-8 | |
25 | * @id: string id, from low byte of wValue in get string descriptor | |
86dc243c | 26 | * @buf: at least 256 bytes, must be 16-bit aligned |
1da177e4 LT |
27 | * |
28 | * Finds the UTF-8 string matching the ID, and converts it into a | |
29 | * string descriptor in utf16-le. | |
30 | * Returns length of descriptor (always even) or negative errno | |
31 | * | |
32 | * If your driver needs stings in multiple languages, you'll probably | |
33 | * "switch (wIndex) { ... }" in your ep0 string descriptor logic, | |
34 | * using this routine after choosing which set of UTF-8 strings to use. | |
35 | * Note that US-ASCII is a strict subset of UTF-8; any string bytes with | |
36 | * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 | |
37 | * characters (which are also widely used in C strings). | |
38 | */ | |
39 | int | |
40 | usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) | |
41 | { | |
42 | struct usb_string *s; | |
43 | int len; | |
44 | ||
45 | /* descriptor 0 has the language id */ | |
46 | if (id == 0) { | |
47 | buf [0] = 4; | |
48 | buf [1] = USB_DT_STRING; | |
49 | buf [2] = (u8) table->language; | |
50 | buf [3] = (u8) (table->language >> 8); | |
51 | return 4; | |
52 | } | |
53 | for (s = table->strings; s && s->s; s++) | |
54 | if (s->id == id) | |
55 | break; | |
56 | ||
57 | /* unrecognized: stall. */ | |
58 | if (!s || !s->s) | |
59 | return -EINVAL; | |
60 | ||
61 | /* string descriptors have length, tag, then UTF16-LE text */ | |
62 | len = min ((size_t) 126, strlen (s->s)); | |
86dc243c AS |
63 | len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, |
64 | (wchar_t *) &buf[2], 126); | |
1da177e4 LT |
65 | if (len < 0) |
66 | return -EINVAL; | |
67 | buf [0] = (len + 1) * 2; | |
68 | buf [1] = USB_DT_STRING; | |
69 | return buf [0]; | |
70 | } | |
a84d9e53 | 71 | EXPORT_SYMBOL_GPL(usb_gadget_get_string); |