diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/f_acm.c | 28 | ||||
-rw-r--r-- | drivers/usb/gadget/f_rndis.c | 35 |
2 files changed, 59 insertions, 4 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 4e3657808b0f..d10353d46b86 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) | 4 | * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) |
5 | * Copyright (C) 2008 by David Brownell | 5 | * Copyright (C) 2008 by David Brownell |
6 | * Copyright (C) 2008 by Nokia Corporation | 6 | * Copyright (C) 2008 by Nokia Corporation |
7 | * Copyright (C) 2009 by Samsung Electronics | ||
8 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | ||
7 | * | 9 | * |
8 | * This software is distributed under the terms of the GNU General | 10 | * This software is distributed under the terms of the GNU General |
9 | * Public License ("GPL") as published by the Free Software Foundation, | 11 | * Public License ("GPL") as published by the Free Software Foundation, |
@@ -99,6 +101,20 @@ static inline struct f_acm *port_to_acm(struct gserial *p) | |||
99 | 101 | ||
100 | /* interface and class descriptors: */ | 102 | /* interface and class descriptors: */ |
101 | 103 | ||
104 | static struct usb_interface_assoc_descriptor | ||
105 | acm_iad_descriptor = { | ||
106 | .bLength = sizeof acm_iad_descriptor, | ||
107 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | ||
108 | |||
109 | /* .bFirstInterface = DYNAMIC, */ | ||
110 | .bInterfaceCount = 2, // control + data | ||
111 | .bFunctionClass = USB_CLASS_COMM, | ||
112 | .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, | ||
113 | .bFunctionProtocol = USB_CDC_PROTO_NONE, | ||
114 | /* .iFunction = DYNAMIC */ | ||
115 | }; | ||
116 | |||
117 | |||
102 | static struct usb_interface_descriptor acm_control_interface_desc __initdata = { | 118 | static struct usb_interface_descriptor acm_control_interface_desc __initdata = { |
103 | .bLength = USB_DT_INTERFACE_SIZE, | 119 | .bLength = USB_DT_INTERFACE_SIZE, |
104 | .bDescriptorType = USB_DT_INTERFACE, | 120 | .bDescriptorType = USB_DT_INTERFACE, |
@@ -178,6 +194,7 @@ static struct usb_endpoint_descriptor acm_fs_out_desc __initdata = { | |||
178 | }; | 194 | }; |
179 | 195 | ||
180 | static struct usb_descriptor_header *acm_fs_function[] __initdata = { | 196 | static struct usb_descriptor_header *acm_fs_function[] __initdata = { |
197 | (struct usb_descriptor_header *) &acm_iad_descriptor, | ||
181 | (struct usb_descriptor_header *) &acm_control_interface_desc, | 198 | (struct usb_descriptor_header *) &acm_control_interface_desc, |
182 | (struct usb_descriptor_header *) &acm_header_desc, | 199 | (struct usb_descriptor_header *) &acm_header_desc, |
183 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, | 200 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, |
@@ -216,6 +233,7 @@ static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { | |||
216 | }; | 233 | }; |
217 | 234 | ||
218 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { | 235 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { |
236 | (struct usb_descriptor_header *) &acm_iad_descriptor, | ||
219 | (struct usb_descriptor_header *) &acm_control_interface_desc, | 237 | (struct usb_descriptor_header *) &acm_control_interface_desc, |
220 | (struct usb_descriptor_header *) &acm_header_desc, | 238 | (struct usb_descriptor_header *) &acm_header_desc, |
221 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, | 239 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, |
@@ -232,11 +250,13 @@ static struct usb_descriptor_header *acm_hs_function[] __initdata = { | |||
232 | 250 | ||
233 | #define ACM_CTRL_IDX 0 | 251 | #define ACM_CTRL_IDX 0 |
234 | #define ACM_DATA_IDX 1 | 252 | #define ACM_DATA_IDX 1 |
253 | #define ACM_IAD_IDX 2 | ||
235 | 254 | ||
236 | /* static strings, in UTF-8 */ | 255 | /* static strings, in UTF-8 */ |
237 | static struct usb_string acm_string_defs[] = { | 256 | static struct usb_string acm_string_defs[] = { |
238 | [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)", | 257 | [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)", |
239 | [ACM_DATA_IDX].s = "CDC ACM Data", | 258 | [ACM_DATA_IDX].s = "CDC ACM Data", |
259 | [ACM_IAD_IDX ].s = "CDC Serial", | ||
240 | { /* ZEROES END LIST */ }, | 260 | { /* ZEROES END LIST */ }, |
241 | }; | 261 | }; |
242 | 262 | ||
@@ -563,6 +583,7 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) | |||
563 | if (status < 0) | 583 | if (status < 0) |
564 | goto fail; | 584 | goto fail; |
565 | acm->ctrl_id = status; | 585 | acm->ctrl_id = status; |
586 | acm_iad_descriptor.bFirstInterface = status; | ||
566 | 587 | ||
567 | acm_control_interface_desc.bInterfaceNumber = status; | 588 | acm_control_interface_desc.bInterfaceNumber = status; |
568 | acm_union_desc .bMasterInterface0 = status; | 589 | acm_union_desc .bMasterInterface0 = status; |
@@ -732,6 +753,13 @@ int __init acm_bind_config(struct usb_configuration *c, u8 port_num) | |||
732 | acm_string_defs[ACM_DATA_IDX].id = status; | 753 | acm_string_defs[ACM_DATA_IDX].id = status; |
733 | 754 | ||
734 | acm_data_interface_desc.iInterface = status; | 755 | acm_data_interface_desc.iInterface = status; |
756 | |||
757 | status = usb_string_id(c->cdev); | ||
758 | if (status < 0) | ||
759 | return status; | ||
760 | acm_string_defs[ACM_IAD_IDX].id = status; | ||
761 | |||
762 | acm_iad_descriptor.iFunction = status; | ||
735 | } | 763 | } |
736 | 764 | ||
737 | /* allocate and initialize one new instance */ | 765 | /* allocate and initialize one new instance */ |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index c9966cc07d3a..95dae4c1ea40 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2003-2005,2008 David Brownell | 4 | * Copyright (C) 2003-2005,2008 David Brownell |
5 | * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger | 5 | * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger |
6 | * Copyright (C) 2008 Nokia Corporation | 6 | * Copyright (C) 2008 Nokia Corporation |
7 | * Copyright (C) 2009 Samsung Electronics | ||
8 | * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) | ||
7 | * | 9 | * |
8 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -149,8 +151,8 @@ static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = { | |||
149 | .bDataInterface = 0x01, | 151 | .bDataInterface = 0x01, |
150 | }; | 152 | }; |
151 | 153 | ||
152 | static struct usb_cdc_acm_descriptor acm_descriptor __initdata = { | 154 | static struct usb_cdc_acm_descriptor rndis_acm_descriptor __initdata = { |
153 | .bLength = sizeof acm_descriptor, | 155 | .bLength = sizeof rndis_acm_descriptor, |
154 | .bDescriptorType = USB_DT_CS_INTERFACE, | 156 | .bDescriptorType = USB_DT_CS_INTERFACE, |
155 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | 157 | .bDescriptorSubType = USB_CDC_ACM_TYPE, |
156 | 158 | ||
@@ -179,6 +181,20 @@ static struct usb_interface_descriptor rndis_data_intf __initdata = { | |||
179 | /* .iInterface = DYNAMIC */ | 181 | /* .iInterface = DYNAMIC */ |
180 | }; | 182 | }; |
181 | 183 | ||
184 | |||
185 | static struct usb_interface_assoc_descriptor | ||
186 | rndis_iad_descriptor = { | ||
187 | .bLength = sizeof rndis_iad_descriptor, | ||
188 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | ||
189 | |||
190 | .bFirstInterface = 0, /* XXX, hardcoded */ | ||
191 | .bInterfaceCount = 2, // control + data | ||
192 | .bFunctionClass = USB_CLASS_COMM, | ||
193 | .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, | ||
194 | .bFunctionProtocol = USB_CDC_PROTO_NONE, | ||
195 | /* .iFunction = DYNAMIC */ | ||
196 | }; | ||
197 | |||
182 | /* full speed support: */ | 198 | /* full speed support: */ |
183 | 199 | ||
184 | static struct usb_endpoint_descriptor fs_notify_desc __initdata = { | 200 | static struct usb_endpoint_descriptor fs_notify_desc __initdata = { |
@@ -208,11 +224,12 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = { | |||
208 | }; | 224 | }; |
209 | 225 | ||
210 | static struct usb_descriptor_header *eth_fs_function[] __initdata = { | 226 | static struct usb_descriptor_header *eth_fs_function[] __initdata = { |
227 | (struct usb_descriptor_header *) &rndis_iad_descriptor, | ||
211 | /* control interface matches ACM, not Ethernet */ | 228 | /* control interface matches ACM, not Ethernet */ |
212 | (struct usb_descriptor_header *) &rndis_control_intf, | 229 | (struct usb_descriptor_header *) &rndis_control_intf, |
213 | (struct usb_descriptor_header *) &header_desc, | 230 | (struct usb_descriptor_header *) &header_desc, |
214 | (struct usb_descriptor_header *) &call_mgmt_descriptor, | 231 | (struct usb_descriptor_header *) &call_mgmt_descriptor, |
215 | (struct usb_descriptor_header *) &acm_descriptor, | 232 | (struct usb_descriptor_header *) &rndis_acm_descriptor, |
216 | (struct usb_descriptor_header *) &rndis_union_desc, | 233 | (struct usb_descriptor_header *) &rndis_union_desc, |
217 | (struct usb_descriptor_header *) &fs_notify_desc, | 234 | (struct usb_descriptor_header *) &fs_notify_desc, |
218 | /* data interface has no altsetting */ | 235 | /* data interface has no altsetting */ |
@@ -252,11 +269,12 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = { | |||
252 | }; | 269 | }; |
253 | 270 | ||
254 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { | 271 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { |
272 | (struct usb_descriptor_header *) &rndis_iad_descriptor, | ||
255 | /* control interface matches ACM, not Ethernet */ | 273 | /* control interface matches ACM, not Ethernet */ |
256 | (struct usb_descriptor_header *) &rndis_control_intf, | 274 | (struct usb_descriptor_header *) &rndis_control_intf, |
257 | (struct usb_descriptor_header *) &header_desc, | 275 | (struct usb_descriptor_header *) &header_desc, |
258 | (struct usb_descriptor_header *) &call_mgmt_descriptor, | 276 | (struct usb_descriptor_header *) &call_mgmt_descriptor, |
259 | (struct usb_descriptor_header *) &acm_descriptor, | 277 | (struct usb_descriptor_header *) &rndis_acm_descriptor, |
260 | (struct usb_descriptor_header *) &rndis_union_desc, | 278 | (struct usb_descriptor_header *) &rndis_union_desc, |
261 | (struct usb_descriptor_header *) &hs_notify_desc, | 279 | (struct usb_descriptor_header *) &hs_notify_desc, |
262 | /* data interface has no altsetting */ | 280 | /* data interface has no altsetting */ |
@@ -271,6 +289,7 @@ static struct usb_descriptor_header *eth_hs_function[] __initdata = { | |||
271 | static struct usb_string rndis_string_defs[] = { | 289 | static struct usb_string rndis_string_defs[] = { |
272 | [0].s = "RNDIS Communications Control", | 290 | [0].s = "RNDIS Communications Control", |
273 | [1].s = "RNDIS Ethernet Data", | 291 | [1].s = "RNDIS Ethernet Data", |
292 | [2].s = "RNDIS", | ||
274 | { } /* end of list */ | 293 | { } /* end of list */ |
275 | }; | 294 | }; |
276 | 295 | ||
@@ -587,6 +606,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
587 | if (status < 0) | 606 | if (status < 0) |
588 | goto fail; | 607 | goto fail; |
589 | rndis->ctrl_id = status; | 608 | rndis->ctrl_id = status; |
609 | rndis_iad_descriptor.bFirstInterface = status; | ||
590 | 610 | ||
591 | rndis_control_intf.bInterfaceNumber = status; | 611 | rndis_control_intf.bInterfaceNumber = status; |
592 | rndis_union_desc.bMasterInterface0 = status; | 612 | rndis_union_desc.bMasterInterface0 = status; |
@@ -798,6 +818,13 @@ int __init rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | |||
798 | return status; | 818 | return status; |
799 | rndis_string_defs[1].id = status; | 819 | rndis_string_defs[1].id = status; |
800 | rndis_data_intf.iInterface = status; | 820 | rndis_data_intf.iInterface = status; |
821 | |||
822 | /* IAD iFunction label */ | ||
823 | status = usb_string_id(c->cdev); | ||
824 | if (status < 0) | ||
825 | return status; | ||
826 | rndis_string_defs[2].id = status; | ||
827 | rndis_iad_descriptor.iFunction = status; | ||
801 | } | 828 | } |
802 | 829 | ||
803 | /* allocate and initialize one new instance */ | 830 | /* allocate and initialize one new instance */ |