diff options
author | David Brownell <david-b@pacbell.net> | 2007-08-02 03:02:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:03 -0400 |
commit | 51a0e85cd9b47e2e6332b40ea486cc1659d8a3ec (patch) | |
tree | ad3722ecf3f93578c42d18eda49ef72d2d8f99cf | |
parent | 8c07021635a10c9a4969cbff0f2325a94c860f77 (diff) |
USB: gadget: serial gadget cleanups
Clean up the serial gadget, using newer APIs and conventions:
- gadget_is_dualspeed() and gadget_is_otg() ... #ifdef removal
- Remove many now-needless #includes
- Use the DEBUG and VERBOSE_DEBUG conventions; turned up a bug in
the original debug messaging
- Various whitespace fixes.
This gave only a minor object code shrinkage, but the source looks
much cleaner in various places.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Al Borchers <alborchers@steinerpoint.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/serial.c | 166 |
1 files changed, 73 insertions, 93 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ce4d2e09633d..afdf71f76f7e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -17,30 +17,11 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/ioport.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/utsname.h> | 21 | #include <linux/utsname.h> |
31 | #include <linux/wait.h> | ||
32 | #include <linux/proc_fs.h> | ||
33 | #include <linux/device.h> | 22 | #include <linux/device.h> |
34 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 24 | #include <linux/tty_flip.h> |
36 | #include <linux/mutex.h> | ||
37 | |||
38 | #include <asm/byteorder.h> | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/irq.h> | ||
41 | #include <asm/system.h> | ||
42 | #include <asm/unaligned.h> | ||
43 | #include <asm/uaccess.h> | ||
44 | 25 | ||
45 | #include <linux/usb/ch9.h> | 26 | #include <linux/usb/ch9.h> |
46 | #include <linux/usb/cdc.h> | 27 | #include <linux/usb/cdc.h> |
@@ -89,30 +70,29 @@ | |||
89 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY | 70 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY |
90 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS | 71 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS |
91 | 72 | ||
92 | /* select highspeed/fullspeed, hiding highspeed if not configured */ | 73 | /* maxpacket and other transfer characteristics vary by speed. */ |
93 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 74 | static inline struct usb_endpoint_descriptor * |
94 | #define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs)) | 75 | choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, |
95 | #else | 76 | struct usb_endpoint_descriptor *fs) |
96 | #define GS_SPEED_SELECT(is_hs,hs,fs) (fs) | 77 | { |
97 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 78 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
79 | return hs; | ||
80 | return fs; | ||
81 | } | ||
82 | |||
98 | 83 | ||
99 | /* debug settings */ | 84 | /* debug settings */ |
100 | #ifdef GS_DEBUG | 85 | #ifdef DEBUG |
101 | static int debug = 1; | 86 | static int debug = 1; |
87 | #else | ||
88 | #define debug 0 | ||
89 | #endif | ||
102 | 90 | ||
103 | #define gs_debug(format, arg...) \ | 91 | #define gs_debug(format, arg...) \ |
104 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) | 92 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) |
105 | #define gs_debug_level(level, format, arg...) \ | 93 | #define gs_debug_level(level, format, arg...) \ |
106 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) | 94 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) |
107 | 95 | ||
108 | #else | ||
109 | |||
110 | #define gs_debug(format, arg...) \ | ||
111 | do { } while(0) | ||
112 | #define gs_debug_level(level, format, arg...) \ | ||
113 | do { } while(0) | ||
114 | |||
115 | #endif /* GS_DEBUG */ | ||
116 | 96 | ||
117 | /* Thanks to NetChip Technologies for donating this product ID. | 97 | /* Thanks to NetChip Technologies for donating this product ID. |
118 | * | 98 | * |
@@ -147,10 +127,10 @@ struct gs_req_entry { | |||
147 | 127 | ||
148 | /* the port structure holds info for each port, one for each minor number */ | 128 | /* the port structure holds info for each port, one for each minor number */ |
149 | struct gs_port { | 129 | struct gs_port { |
150 | struct gs_dev *port_dev; /* pointer to device struct */ | 130 | struct gs_dev *port_dev; /* pointer to device struct */ |
151 | struct tty_struct *port_tty; /* pointer to tty struct */ | 131 | struct tty_struct *port_tty; /* pointer to tty struct */ |
152 | spinlock_t port_lock; | 132 | spinlock_t port_lock; |
153 | int port_num; | 133 | int port_num; |
154 | int port_open_count; | 134 | int port_open_count; |
155 | int port_in_use; /* open/close in progress */ | 135 | int port_in_use; /* open/close in progress */ |
156 | wait_queue_head_t port_write_wait;/* waiting to write */ | 136 | wait_queue_head_t port_write_wait;/* waiting to write */ |
@@ -188,7 +168,7 @@ static void __exit gs_module_exit(void); | |||
188 | /* tty driver */ | 168 | /* tty driver */ |
189 | static int gs_open(struct tty_struct *tty, struct file *file); | 169 | static int gs_open(struct tty_struct *tty, struct file *file); |
190 | static void gs_close(struct tty_struct *tty, struct file *file); | 170 | static void gs_close(struct tty_struct *tty, struct file *file); |
191 | static int gs_write(struct tty_struct *tty, | 171 | static int gs_write(struct tty_struct *tty, |
192 | const unsigned char *buf, int count); | 172 | const unsigned char *buf, int count); |
193 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); | 173 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); |
194 | static void gs_flush_chars(struct tty_struct *tty); | 174 | static void gs_flush_chars(struct tty_struct *tty); |
@@ -222,7 +202,7 @@ static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); | |||
222 | static void gs_disconnect(struct usb_gadget *gadget); | 202 | static void gs_disconnect(struct usb_gadget *gadget); |
223 | static int gs_set_config(struct gs_dev *dev, unsigned config); | 203 | static int gs_set_config(struct gs_dev *dev, unsigned config); |
224 | static void gs_reset_config(struct gs_dev *dev); | 204 | static void gs_reset_config(struct gs_dev *dev); |
225 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 205 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
226 | u8 type, unsigned int index, int is_otg); | 206 | u8 type, unsigned int index, int is_otg); |
227 | 207 | ||
228 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | 208 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, |
@@ -415,18 +395,18 @@ static const struct usb_cdc_header_desc gs_header_desc = { | |||
415 | }; | 395 | }; |
416 | 396 | ||
417 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { | 397 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { |
418 | .bLength = sizeof(gs_call_mgmt_descriptor), | 398 | .bLength = sizeof(gs_call_mgmt_descriptor), |
419 | .bDescriptorType = USB_DT_CS_INTERFACE, | 399 | .bDescriptorType = USB_DT_CS_INTERFACE, |
420 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, | 400 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, |
421 | .bmCapabilities = 0, | 401 | .bmCapabilities = 0, |
422 | .bDataInterface = 1, /* index of data interface */ | 402 | .bDataInterface = 1, /* index of data interface */ |
423 | }; | 403 | }; |
424 | 404 | ||
425 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | 405 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { |
426 | .bLength = sizeof(gs_acm_descriptor), | 406 | .bLength = sizeof(gs_acm_descriptor), |
427 | .bDescriptorType = USB_DT_CS_INTERFACE, | 407 | .bDescriptorType = USB_DT_CS_INTERFACE, |
428 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | 408 | .bDescriptorSubType = USB_CDC_ACM_TYPE, |
429 | .bmCapabilities = 0, | 409 | .bmCapabilities = 0, |
430 | }; | 410 | }; |
431 | 411 | ||
432 | static const struct usb_cdc_union_desc gs_union_desc = { | 412 | static const struct usb_cdc_union_desc gs_union_desc = { |
@@ -436,7 +416,7 @@ static const struct usb_cdc_union_desc gs_union_desc = { | |||
436 | .bMasterInterface0 = 0, /* index of control interface */ | 416 | .bMasterInterface0 = 0, /* index of control interface */ |
437 | .bSlaveInterface0 = 1, /* index of data interface */ | 417 | .bSlaveInterface0 = 1, /* index of data interface */ |
438 | }; | 418 | }; |
439 | 419 | ||
440 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { | 420 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { |
441 | .bLength = USB_DT_ENDPOINT_SIZE, | 421 | .bLength = USB_DT_ENDPOINT_SIZE, |
442 | .bDescriptorType = USB_DT_ENDPOINT, | 422 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -482,7 +462,6 @@ static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = { | |||
482 | NULL, | 462 | NULL, |
483 | }; | 463 | }; |
484 | 464 | ||
485 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
486 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { | 465 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { |
487 | .bLength = USB_DT_ENDPOINT_SIZE, | 466 | .bLength = USB_DT_ENDPOINT_SIZE, |
488 | .bDescriptorType = USB_DT_ENDPOINT, | 467 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -536,15 +515,13 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | |||
536 | NULL, | 515 | NULL, |
537 | }; | 516 | }; |
538 | 517 | ||
539 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
540 | |||
541 | 518 | ||
542 | /* Module */ | 519 | /* Module */ |
543 | MODULE_DESCRIPTION(GS_LONG_NAME); | 520 | MODULE_DESCRIPTION(GS_LONG_NAME); |
544 | MODULE_AUTHOR("Al Borchers"); | 521 | MODULE_AUTHOR("Al Borchers"); |
545 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
546 | 523 | ||
547 | #ifdef GS_DEBUG | 524 | #ifdef DEBUG |
548 | module_param(debug, int, S_IRUGO|S_IWUSR); | 525 | module_param(debug, int, S_IRUGO|S_IWUSR); |
549 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); | 526 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); |
550 | #endif | 527 | #endif |
@@ -915,7 +892,8 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) | |||
915 | return; | 892 | return; |
916 | } | 893 | } |
917 | 894 | ||
918 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); | 895 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n", |
896 | port->port_num, tty, ch, __builtin_return_address(0)); | ||
919 | 897 | ||
920 | spin_lock_irqsave(&port->port_lock, flags); | 898 | spin_lock_irqsave(&port->port_lock, flags); |
921 | 899 | ||
@@ -1116,7 +1094,11 @@ static int gs_send(struct gs_dev *dev) | |||
1116 | len = gs_send_packet(dev, req->buf, ep->maxpacket); | 1094 | len = gs_send_packet(dev, req->buf, ep->maxpacket); |
1117 | 1095 | ||
1118 | if (len > 0) { | 1096 | if (len > 0) { |
1119 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); | 1097 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x " |
1098 | "0x%2.2x 0x%2.2x ...\n", len, | ||
1099 | *((unsigned char *)req->buf), | ||
1100 | *((unsigned char *)req->buf+1), | ||
1101 | *((unsigned char *)req->buf+2)); | ||
1120 | list_del(&req_entry->re_entry); | 1102 | list_del(&req_entry->re_entry); |
1121 | req->length = len; | 1103 | req->length = len; |
1122 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 1104 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
@@ -1269,7 +1251,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | |||
1269 | 1251 | ||
1270 | switch(req->status) { | 1252 | switch(req->status) { |
1271 | case 0: | 1253 | case 0: |
1272 | /* normal completion */ | 1254 | /* normal completion */ |
1273 | gs_recv_packet(dev, req->buf, req->actual); | 1255 | gs_recv_packet(dev, req->buf, req->actual); |
1274 | requeue: | 1256 | requeue: |
1275 | req->length = ep->maxpacket; | 1257 | req->length = ep->maxpacket; |
@@ -1406,23 +1388,24 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1406 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1388 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1407 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1389 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1408 | 1390 | ||
1409 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1391 | if (gadget_is_dualspeed(gadget)) { |
1410 | gs_qualifier_desc.bDeviceClass = use_acm | 1392 | gs_qualifier_desc.bDeviceClass = use_acm |
1411 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1393 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1412 | /* assume ep0 uses the same packet size for both speeds */ | 1394 | /* assume ep0 uses the same packet size for both speeds */ |
1413 | gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0; | 1395 | gs_qualifier_desc.bMaxPacketSize0 = |
1414 | /* assume endpoints are dual-speed */ | 1396 | gs_device_desc.bMaxPacketSize0; |
1415 | gs_highspeed_notify_desc.bEndpointAddress = | 1397 | /* assume endpoints are dual-speed */ |
1416 | gs_fullspeed_notify_desc.bEndpointAddress; | 1398 | gs_highspeed_notify_desc.bEndpointAddress = |
1417 | gs_highspeed_in_desc.bEndpointAddress = | 1399 | gs_fullspeed_notify_desc.bEndpointAddress; |
1418 | gs_fullspeed_in_desc.bEndpointAddress; | 1400 | gs_highspeed_in_desc.bEndpointAddress = |
1419 | gs_highspeed_out_desc.bEndpointAddress = | 1401 | gs_fullspeed_in_desc.bEndpointAddress; |
1420 | gs_fullspeed_out_desc.bEndpointAddress; | 1402 | gs_highspeed_out_desc.bEndpointAddress = |
1421 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1403 | gs_fullspeed_out_desc.bEndpointAddress; |
1404 | } | ||
1422 | 1405 | ||
1423 | usb_gadget_set_selfpowered(gadget); | 1406 | usb_gadget_set_selfpowered(gadget); |
1424 | 1407 | ||
1425 | if (gadget->is_otg) { | 1408 | if (gadget_is_otg(gadget)) { |
1426 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, | 1409 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, |
1427 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1410 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1428 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1411 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
@@ -1570,9 +1553,8 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1570 | memcpy(req->buf, &gs_device_desc, ret); | 1553 | memcpy(req->buf, &gs_device_desc, ret); |
1571 | break; | 1554 | break; |
1572 | 1555 | ||
1573 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1574 | case USB_DT_DEVICE_QUALIFIER: | 1556 | case USB_DT_DEVICE_QUALIFIER: |
1575 | if (!gadget->is_dualspeed) | 1557 | if (!gadget_is_dualspeed(gadget)) |
1576 | break; | 1558 | break; |
1577 | ret = min(wLength, | 1559 | ret = min(wLength, |
1578 | (u16)sizeof(struct usb_qualifier_descriptor)); | 1560 | (u16)sizeof(struct usb_qualifier_descriptor)); |
@@ -1580,14 +1562,13 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1580 | break; | 1562 | break; |
1581 | 1563 | ||
1582 | case USB_DT_OTHER_SPEED_CONFIG: | 1564 | case USB_DT_OTHER_SPEED_CONFIG: |
1583 | if (!gadget->is_dualspeed) | 1565 | if (!gadget_is_dualspeed(gadget)) |
1584 | break; | 1566 | break; |
1585 | /* fall through */ | 1567 | /* fall through */ |
1586 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1587 | case USB_DT_CONFIG: | 1568 | case USB_DT_CONFIG: |
1588 | ret = gs_build_config_buf(req->buf, gadget->speed, | 1569 | ret = gs_build_config_buf(req->buf, gadget, |
1589 | wValue >> 8, wValue & 0xff, | 1570 | wValue >> 8, wValue & 0xff, |
1590 | gadget->is_otg); | 1571 | gadget_is_otg(gadget)); |
1591 | if (ret >= 0) | 1572 | if (ret >= 0) |
1592 | ret = min(wLength, (u16)ret); | 1573 | ret = min(wLength, (u16)ret); |
1593 | break; | 1574 | break; |
@@ -1827,8 +1808,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1827 | 1808 | ||
1828 | if (EP_NOTIFY_NAME | 1809 | if (EP_NOTIFY_NAME |
1829 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { | 1810 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { |
1830 | ep_desc = GS_SPEED_SELECT( | 1811 | ep_desc = choose_ep_desc(gadget, |
1831 | gadget->speed == USB_SPEED_HIGH, | ||
1832 | &gs_highspeed_notify_desc, | 1812 | &gs_highspeed_notify_desc, |
1833 | &gs_fullspeed_notify_desc); | 1813 | &gs_fullspeed_notify_desc); |
1834 | ret = usb_ep_enable(ep,ep_desc); | 1814 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1844,9 +1824,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1844 | } | 1824 | } |
1845 | 1825 | ||
1846 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { | 1826 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { |
1847 | ep_desc = GS_SPEED_SELECT( | 1827 | ep_desc = choose_ep_desc(gadget, |
1848 | gadget->speed == USB_SPEED_HIGH, | 1828 | &gs_highspeed_in_desc, |
1849 | &gs_highspeed_in_desc, | ||
1850 | &gs_fullspeed_in_desc); | 1829 | &gs_fullspeed_in_desc); |
1851 | ret = usb_ep_enable(ep,ep_desc); | 1830 | ret = usb_ep_enable(ep,ep_desc); |
1852 | if (ret == 0) { | 1831 | if (ret == 0) { |
@@ -1861,8 +1840,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1861 | } | 1840 | } |
1862 | 1841 | ||
1863 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { | 1842 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { |
1864 | ep_desc = GS_SPEED_SELECT( | 1843 | ep_desc = choose_ep_desc(gadget, |
1865 | gadget->speed == USB_SPEED_HIGH, | ||
1866 | &gs_highspeed_out_desc, | 1844 | &gs_highspeed_out_desc, |
1867 | &gs_fullspeed_out_desc); | 1845 | &gs_fullspeed_out_desc); |
1868 | ret = usb_ep_enable(ep,ep_desc); | 1846 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1981,11 +1959,11 @@ static void gs_reset_config(struct gs_dev *dev) | |||
1981 | * Builds the config descriptors in the given buffer and returns the | 1959 | * Builds the config descriptors in the given buffer and returns the |
1982 | * length, or a negative error number. | 1960 | * length, or a negative error number. |
1983 | */ | 1961 | */ |
1984 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 1962 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
1985 | u8 type, unsigned int index, int is_otg) | 1963 | u8 type, unsigned int index, int is_otg) |
1986 | { | 1964 | { |
1987 | int len; | 1965 | int len; |
1988 | int high_speed; | 1966 | int high_speed = 0; |
1989 | const struct usb_config_descriptor *config_desc; | 1967 | const struct usb_config_descriptor *config_desc; |
1990 | const struct usb_descriptor_header **function; | 1968 | const struct usb_descriptor_header **function; |
1991 | 1969 | ||
@@ -1993,20 +1971,22 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | |||
1993 | return -EINVAL; | 1971 | return -EINVAL; |
1994 | 1972 | ||
1995 | /* other speed switches high and full speed */ | 1973 | /* other speed switches high and full speed */ |
1996 | high_speed = (speed == USB_SPEED_HIGH); | 1974 | if (gadget_is_dualspeed(g)) { |
1997 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1975 | high_speed = (g->speed == USB_SPEED_HIGH); |
1998 | high_speed = !high_speed; | 1976 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1977 | high_speed = !high_speed; | ||
1978 | } | ||
1999 | 1979 | ||
2000 | if (use_acm) { | 1980 | if (use_acm) { |
2001 | config_desc = &gs_acm_config_desc; | 1981 | config_desc = &gs_acm_config_desc; |
2002 | function = GS_SPEED_SELECT(high_speed, | 1982 | function = high_speed |
2003 | gs_acm_highspeed_function, | 1983 | ? gs_acm_highspeed_function |
2004 | gs_acm_fullspeed_function); | 1984 | : gs_acm_fullspeed_function; |
2005 | } else { | 1985 | } else { |
2006 | config_desc = &gs_bulk_config_desc; | 1986 | config_desc = &gs_bulk_config_desc; |
2007 | function = GS_SPEED_SELECT(high_speed, | 1987 | function = high_speed |
2008 | gs_bulk_highspeed_function, | 1988 | ? gs_bulk_highspeed_function |
2009 | gs_bulk_fullspeed_function); | 1989 | : gs_bulk_fullspeed_function; |
2010 | } | 1990 | } |
2011 | 1991 | ||
2012 | /* for now, don't advertise srp-only devices */ | 1992 | /* for now, don't advertise srp-only devices */ |