aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_eem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 02:08:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 02:08:32 -0400
commitf549953c15deab4c54708b39af86d4edecc6cddc (patch)
treef0412f989b77cdceab34c18aa85a8a25d5942a1f /drivers/usb/gadget/f_eem.c
parentf0deb97ab13ad1f89cd0993f7339655d59788405 (diff)
parente04f5f7e423018bcec84c11af2058cdce87816f3 (diff)
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (115 commits) EHCI: fix direction handling for interrupt data toggles USB: serial: add IDs for WinChipHead USB->RS232 adapter USB: OHCI: fix another regression for NVIDIA controllers usb: gadget: m66592-udc: add pullup function usb: gadget: m66592-udc: add function for external controller usb: gadget: r8a66597-udc: add pullup function usb: renesas_usbhs: support multi driver usb: renesas_usbhs: inaccessible pipe is not an error usb: renesas_usbhs: care buff alignment when dma handler USB: PL2303: correctly handle baudrates above 115200 usb: r8a66597-hcd: fixup USB_PORT_STAT_C_SUSPEND shift usb: renesas_usbhs: compile/config are rescued usb: renesas_usbhs: fixup comment-out usb: update email address in ohci-sh and r8a66597-hcd usb: r8a66597-hcd: add function for external controller EHCI: only power off port if over-current is active USB: mon: Allow to use usbmon without debugfs USB: EHCI: go back to using the system clock for QH unlinks ehci: add pci quirk for Ordissimo and RM Slate 100 too ehci: refactor pci quirk to use standard dmi_check_system method ... Fix up trivial conflicts in Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/usb/gadget/f_eem.c')
-rw-r--r--drivers/usb/gadget/f_eem.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index b3c304290150..046c6d0e6960 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -35,17 +35,9 @@
35 * Ethernet link. 35 * Ethernet link.
36 */ 36 */
37 37
38struct eem_ep_descs {
39 struct usb_endpoint_descriptor *in;
40 struct usb_endpoint_descriptor *out;
41};
42
43struct f_eem { 38struct f_eem {
44 struct gether port; 39 struct gether port;
45 u8 ctrl_id; 40 u8 ctrl_id;
46
47 struct eem_ep_descs fs;
48 struct eem_ep_descs hs;
49}; 41};
50 42
51static inline struct f_eem *func_to_eem(struct usb_function *f) 43static inline struct f_eem *func_to_eem(struct usb_function *f)
@@ -123,6 +115,45 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {
123 NULL, 115 NULL,
124}; 116};
125 117
118/* super speed support: */
119
120static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
121 .bLength = USB_DT_ENDPOINT_SIZE,
122 .bDescriptorType = USB_DT_ENDPOINT,
123
124 .bEndpointAddress = USB_DIR_IN,
125 .bmAttributes = USB_ENDPOINT_XFER_BULK,
126 .wMaxPacketSize = cpu_to_le16(1024),
127};
128
129static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
130 .bLength = USB_DT_ENDPOINT_SIZE,
131 .bDescriptorType = USB_DT_ENDPOINT,
132
133 .bEndpointAddress = USB_DIR_OUT,
134 .bmAttributes = USB_ENDPOINT_XFER_BULK,
135 .wMaxPacketSize = cpu_to_le16(1024),
136};
137
138static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
139 .bLength = sizeof eem_ss_bulk_comp_desc,
140 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
141
142 /* the following 2 values can be tweaked if necessary */
143 /* .bMaxBurst = 0, */
144 /* .bmAttributes = 0, */
145};
146
147static struct usb_descriptor_header *eem_ss_function[] __initdata = {
148 /* CDC EEM control descriptors */
149 (struct usb_descriptor_header *) &eem_intf,
150 (struct usb_descriptor_header *) &eem_ss_in_desc,
151 (struct usb_descriptor_header *) &eem_ss_bulk_comp_desc,
152 (struct usb_descriptor_header *) &eem_ss_out_desc,
153 (struct usb_descriptor_header *) &eem_ss_bulk_comp_desc,
154 NULL,
155};
156
126/* string descriptors: */ 157/* string descriptors: */
127 158
128static struct usb_string eem_string_defs[] = { 159static struct usb_string eem_string_defs[] = {
@@ -176,12 +207,16 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
176 gether_disconnect(&eem->port); 207 gether_disconnect(&eem->port);
177 } 208 }
178 209
179 if (!eem->port.in) { 210 if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
180 DBG(cdev, "init eem\n"); 211 DBG(cdev, "init eem\n");
181 eem->port.in = ep_choose(cdev->gadget, 212 if (config_ep_by_speed(cdev->gadget, f,
182 eem->hs.in, eem->fs.in); 213 eem->port.in_ep) ||
183 eem->port.out = ep_choose(cdev->gadget, 214 config_ep_by_speed(cdev->gadget, f,
184 eem->hs.out, eem->fs.out); 215 eem->port.out_ep)) {
216 eem->port.in_ep->desc = NULL;
217 eem->port.out_ep->desc = NULL;
218 goto fail;
219 }
185 } 220 }
186 221
187 /* zlps should not occur because zero-length EEM packets 222 /* zlps should not occur because zero-length EEM packets
@@ -253,11 +288,6 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
253 if (!f->descriptors) 288 if (!f->descriptors)
254 goto fail; 289 goto fail;
255 290
256 eem->fs.in = usb_find_endpoint(eem_fs_function,
257 f->descriptors, &eem_fs_in_desc);
258 eem->fs.out = usb_find_endpoint(eem_fs_function,
259 f->descriptors, &eem_fs_out_desc);
260
261 /* support all relevant hardware speeds... we expect that when 291 /* support all relevant hardware speeds... we expect that when
262 * hardware is dual speed, all bulk-capable endpoints work at 292 * hardware is dual speed, all bulk-capable endpoints work at
263 * both speeds 293 * both speeds
@@ -272,14 +302,22 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
272 f->hs_descriptors = usb_copy_descriptors(eem_hs_function); 302 f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
273 if (!f->hs_descriptors) 303 if (!f->hs_descriptors)
274 goto fail; 304 goto fail;
305 }
306
307 if (gadget_is_superspeed(c->cdev->gadget)) {
308 eem_ss_in_desc.bEndpointAddress =
309 eem_fs_in_desc.bEndpointAddress;
310 eem_ss_out_desc.bEndpointAddress =
311 eem_fs_out_desc.bEndpointAddress;
275 312
276 eem->hs.in = usb_find_endpoint(eem_hs_function, 313 /* copy descriptors, and track endpoint copies */
277 f->hs_descriptors, &eem_hs_in_desc); 314 f->ss_descriptors = usb_copy_descriptors(eem_ss_function);
278 eem->hs.out = usb_find_endpoint(eem_hs_function, 315 if (!f->ss_descriptors)
279 f->hs_descriptors, &eem_hs_out_desc); 316 goto fail;
280 } 317 }
281 318
282 DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", 319 DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
320 gadget_is_superspeed(c->cdev->gadget) ? "super" :
283 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 321 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
284 eem->port.in_ep->name, eem->port.out_ep->name); 322 eem->port.in_ep->name, eem->port.out_ep->name);
285 return 0; 323 return 0;
@@ -287,11 +325,13 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
287fail: 325fail:
288 if (f->descriptors) 326 if (f->descriptors)
289 usb_free_descriptors(f->descriptors); 327 usb_free_descriptors(f->descriptors);
328 if (f->hs_descriptors)
329 usb_free_descriptors(f->hs_descriptors);
290 330
291 /* we might as well release our claims on endpoints */ 331 /* we might as well release our claims on endpoints */
292 if (eem->port.out) 332 if (eem->port.out_ep->desc)
293 eem->port.out_ep->driver_data = NULL; 333 eem->port.out_ep->driver_data = NULL;
294 if (eem->port.in) 334 if (eem->port.in_ep->desc)
295 eem->port.in_ep->driver_data = NULL; 335 eem->port.in_ep->driver_data = NULL;
296 336
297 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); 337 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
@@ -306,6 +346,8 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
306 346
307 DBG(c->cdev, "eem unbind\n"); 347 DBG(c->cdev, "eem unbind\n");
308 348
349 if (gadget_is_superspeed(c->cdev->gadget))
350 usb_free_descriptors(f->ss_descriptors);
309 if (gadget_is_dualspeed(c->cdev->gadget)) 351 if (gadget_is_dualspeed(c->cdev->gadget))
310 usb_free_descriptors(f->hs_descriptors); 352 usb_free_descriptors(f->hs_descriptors);
311 usb_free_descriptors(f->descriptors); 353 usb_free_descriptors(f->descriptors);