diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2009-08-08 06:25:28 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-08-08 06:26:15 -0400 |
commit | a131bc185528331451a93db6c50a7d2070376a61 (patch) | |
tree | 18cccd206d4835ee8df147ac3b0c0e30cc00680d /drivers/usb/core/message.c | |
parent | 19943b0e30b05d42e494ae6fef78156ebc8c637e (diff) | |
parent | ff1649ff780fb7c0bfbf42d05ffc9b56336b9aa3 (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Pull fixes in from 2.6.31 so that people testing the iommu-2.6.git tree
no longer trip over bugs which were already fixed (sorry, Horms).
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r-- | drivers/usb/core/message.c | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2bed83caacb..9720e699f47 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, | |||
806 | return rc; | 806 | return rc; |
807 | } | 807 | } |
808 | 808 | ||
809 | static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf) | ||
810 | { | ||
811 | int err; | ||
812 | |||
813 | if (dev->have_langid) | ||
814 | return 0; | ||
815 | |||
816 | if (dev->string_langid < 0) | ||
817 | return -EPIPE; | ||
818 | |||
819 | err = usb_string_sub(dev, 0, 0, tbuf); | ||
820 | |||
821 | /* If the string was reported but is malformed, default to english | ||
822 | * (0x0409) */ | ||
823 | if (err == -ENODATA || (err > 0 && err < 4)) { | ||
824 | dev->string_langid = 0x0409; | ||
825 | dev->have_langid = 1; | ||
826 | dev_err(&dev->dev, | ||
827 | "string descriptor 0 malformed (err = %d), " | ||
828 | "defaulting to 0x%04x\n", | ||
829 | err, dev->string_langid); | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* In case of all other errors, we assume the device is not able to | ||
834 | * deal with strings at all. Set string_langid to -1 in order to | ||
835 | * prevent any string to be retrieved from the device */ | ||
836 | if (err < 0) { | ||
837 | dev_err(&dev->dev, "string descriptor 0 read error: %d\n", | ||
838 | err); | ||
839 | dev->string_langid = -1; | ||
840 | return -EPIPE; | ||
841 | } | ||
842 | |||
843 | /* always use the first langid listed */ | ||
844 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
845 | dev->have_langid = 1; | ||
846 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
847 | dev->string_langid); | ||
848 | return 0; | ||
849 | } | ||
850 | |||
809 | /** | 851 | /** |
810 | * usb_string - returns UTF-8 version of a string descriptor | 852 | * usb_string - returns UTF-8 version of a string descriptor |
811 | * @dev: the device whose string descriptor is being retrieved | 853 | * @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) | |||
837 | if (!tbuf) | 879 | if (!tbuf) |
838 | return -ENOMEM; | 880 | return -ENOMEM; |
839 | 881 | ||
840 | /* get langid for strings if it's not yet known */ | 882 | err = usb_get_langid(dev, tbuf); |
841 | if (!dev->have_langid) { | 883 | if (err < 0) |
842 | err = usb_string_sub(dev, 0, 0, tbuf); | 884 | goto errout; |
843 | if (err < 0) { | ||
844 | dev_err(&dev->dev, | ||
845 | "string descriptor 0 read error: %d\n", | ||
846 | err); | ||
847 | } else if (err < 4) { | ||
848 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | ||
849 | } else { | ||
850 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
851 | /* always use the first langid listed */ | ||
852 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
853 | dev->string_langid); | ||
854 | } | ||
855 | |||
856 | dev->have_langid = 1; | ||
857 | } | ||
858 | 885 | ||
859 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 886 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
860 | if (err < 0) | 887 | if (err < 0) |