diff options
| -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 */ |
