ChangeSet 1.1078.2.5, 2003/05/08 11:34:30-07:00, david-b@pacbell.net [PATCH] USB Gadget string utility (5/6) This adds utility code that gadget drivers can use to manage string descriptors (drivers/usb/gadget/usbstring.c) in the common case that the ISO-8859/1 character set is in use. Both "Gadget Zero" and the Ethernet gadget code use this. diff -Nru a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/usb/gadget/usbstring.c Thu May 8 14:31:46 2003 @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2003 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include + + +/** + * usb_gadget_get_string - fill out a string descriptor + * @table: of c strings using iso latin/1 characters + * @id: string id, from low byte of wValue in get string descriptor + * @buf: at least 256 bytes + * + * Finds the iso latin/1 string matching the ID, and converts it into a + * string descriptor in utf16-le. + * Returns length of descriptor (always even) or negative errno + * + * If your driver needs stings in multiple languages, you'll need to + * to use some alternate solution for languages where the ISO 8859/1 + * (latin/1) character set can't be used. For example, they can't be + * used with Chinese (Big5, GB2312, etc), Japanese, Korean, or many other + * languages. You'd likely "switch (wIndex) { ... }" in your ep0 + * string descriptor logic, using this routine in cases where "western + * european" characters suffice for the strings being returned. + */ +int +usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) +{ + struct usb_string *s; + int len; + + /* descriptor 0 has the language id */ + if (id == 0) { + buf [0] = 4; + buf [1] = USB_DT_STRING; + buf [2] = (u8) table->language; + buf [3] = (u8) (table->language >> 8); + return 4; + } + for (s = table->strings; s && s->s; s++) + if (s->id == id) + break; + + /* unrecognized: stall. */ + if (!s || !s->s) + return -EINVAL; + + /* string descriptors have length, tag, then UTF16-LE text */ + len = min ((size_t) 126, strlen (s->s)); + buf [0] = (len + 1) * 2; + buf [1] = USB_DT_STRING; + memset (buf + 2, 0, 2 * len); /* zero all the high bytes */ + while (len) { + buf [2 * len] = s->s [len - 1]; + len--; + } + return buf [0]; +} +