summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/bus/usb.c37
-rw-r--r--src/include/ipxe/usb.h6
2 files changed, 42 insertions, 1 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index bd2a446b..d8db3849 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -844,11 +844,39 @@ int usb_control ( struct usb_device *usb, unsigned int request,
}
/**
+ * Get default language ID
+ *
+ * @v usb USB device
+ * @ret language Language ID
+ */
+static unsigned int usb_get_default_language ( struct usb_device *usb ) {
+ struct {
+ struct usb_descriptor_header header;
+ uint16_t language[1];
+ } __attribute__ (( packed )) desc;
+ unsigned int language;
+ int rc;
+
+ /* Get descriptor */
+ if ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
+ &desc.header, sizeof ( desc ) ) ) !=0){
+ DBGC ( usb, "USB %s has no default language: %s\n",
+ usb->name, strerror ( rc ) );
+ return USB_LANG_ENGLISH;
+ }
+
+ /* Use first language ID */
+ language = le16_to_cpu ( desc.language[0] );
+ DBGC2 ( usb, "USB %s default language %#04x\n", usb->name, language );
+ return language;
+}
+
+/**
* Get USB string descriptor
*
* @v usb USB device
* @v index String index
- * @v language Language ID
+ * @v language Language ID, or 0 to use default
* @v buf Data buffer
* @v len Length of buffer
* @ret len String length (excluding NUL), or negative error
@@ -864,6 +892,13 @@ int usb_get_string_descriptor ( struct usb_device *usb, unsigned int index,
unsigned int i;
int rc;
+ /* Use default language ID, if applicable */
+ if ( ( language == 0 ) && ( index != 0 ) ) {
+ if ( ! usb->language )
+ usb->language = usb_get_default_language ( usb );
+ language = usb->language;
+ }
+
/* Allocate buffer for string */
desc = malloc ( sizeof ( *desc ) );
if ( ! desc ) {
diff --git a/src/include/ipxe/usb.h b/src/include/ipxe/usb.h
index e7909d30..68289d26 100644
--- a/src/include/ipxe/usb.h
+++ b/src/include/ipxe/usb.h
@@ -223,6 +223,9 @@ struct usb_string_descriptor {
/** A USB string descriptor */
#define USB_STRING_DESCRIPTOR 3
+/** Language ID for English */
+#define USB_LANG_ENGLISH 0x0409
+
/** A USB interface descriptor */
struct usb_interface_descriptor {
/** Descriptor header */
@@ -728,6 +731,9 @@ struct usb_device {
struct usb_endpoint control;
/** Completed control transfers */
struct list_head complete;
+
+ /** Default language ID (if known) */
+ unsigned int language;
};
/** USB device host controller operations */