|
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (dev->have_langid)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (dev->string_langid < 0)
|
|
|
+ return -EPIPE;
|
|
|
+
|
|
|
+ err = usb_string_sub(dev, 0, 0, tbuf);
|
|
|
+
|
|
|
+ /* If the string was reported but is malformed, default to english
|
|
|
+ * (0x0409) */
|
|
|
+ if (err == -ENODATA || (err > 0 && err < 4)) {
|
|
|
+ dev->string_langid = 0x0409;
|
|
|
+ dev->have_langid = 1;
|
|
|
+ dev_err(&dev->dev,
|
|
|
+ "string descriptor 0 malformed (err = %d), "
|
|
|
+ "defaulting to 0x%04x\n",
|
|
|
+ err, dev->string_langid);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* In case of all other errors, we assume the device is not able to
|
|
|
+ * deal with strings at all. Set string_langid to -1 in order to
|
|
|
+ * prevent any string to be retrieved from the device */
|
|
|
+ if (err < 0) {
|
|
|
+ dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
|
|
|
+ err);
|
|
|
+ dev->string_langid = -1;
|
|
|
+ return -EPIPE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* always use the first langid listed */
|
|
|
+ dev->string_langid = tbuf[2] | (tbuf[3] << 8);
|
|
|
+ dev->have_langid = 1;
|
|
|
+ dev_dbg(&dev->dev, "default language 0x%04x\n",
|
|
|
+ dev->string_langid);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* usb_string - returns UTF-8 version of a string descriptor
|
|
|
* @dev: the device whose string descriptor is being retrieved
|
|
@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
|
|
if (!tbuf)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- /* get langid for strings if it's not yet known */
|
|
|
- if (!dev->have_langid) {
|
|
|
- err = usb_string_sub(dev, 0, 0, tbuf);
|
|
|
- if (err < 0) {
|
|
|
- dev_err(&dev->dev,
|
|
|
- "string descriptor 0 read error: %d\n",
|
|
|
- err);
|
|
|
- } else if (err < 4) {
|
|
|
- dev_err(&dev->dev, "string descriptor 0 too short\n");
|
|
|
- } else {
|
|
|
- dev->string_langid = tbuf[2] | (tbuf[3] << 8);
|
|
|
- /* always use the first langid listed */
|
|
|
- dev_dbg(&dev->dev, "default language 0x%04x\n",
|
|
|
- dev->string_langid);
|
|
|
- }
|
|
|
-
|
|
|
- dev->have_langid = 1;
|
|
|
- }
|
|
|
+ err = usb_get_langid(dev, tbuf);
|
|
|
+ if (err < 0)
|
|
|
+ goto errout;
|
|
|
|
|
|
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
|
|
|
if (err < 0)
|