aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_acm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r--drivers/usb/gadget/f_acm.c50
1 files changed, 15 insertions, 35 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index bd6226cbae86..3f8849339ade 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -39,12 +39,6 @@
39 * descriptors (roughly equivalent to CDC Unions) may sometimes help. 39 * descriptors (roughly equivalent to CDC Unions) may sometimes help.
40 */ 40 */
41 41
42struct acm_ep_descs {
43 struct usb_endpoint_descriptor *in;
44 struct usb_endpoint_descriptor *out;
45 struct usb_endpoint_descriptor *notify;
46};
47
48struct f_acm { 42struct f_acm {
49 struct gserial port; 43 struct gserial port;
50 u8 ctrl_id, data_id; 44 u8 ctrl_id, data_id;
@@ -58,11 +52,7 @@ struct f_acm {
58 */ 52 */
59 spinlock_t lock; 53 spinlock_t lock;
60 54
61 struct acm_ep_descs fs;
62 struct acm_ep_descs hs;
63
64 struct usb_ep *notify; 55 struct usb_ep *notify;
65 struct usb_endpoint_descriptor *notify_desc;
66 struct usb_request *notify_req; 56 struct usb_request *notify_req;
67 57
68 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ 58 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
@@ -405,23 +395,27 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
405 usb_ep_disable(acm->notify); 395 usb_ep_disable(acm->notify);
406 } else { 396 } else {
407 VDBG(cdev, "init acm ctrl interface %d\n", intf); 397 VDBG(cdev, "init acm ctrl interface %d\n", intf);
408 acm->notify_desc = ep_choose(cdev->gadget, 398 if (config_ep_by_speed(cdev->gadget, f, acm->notify))
409 acm->hs.notify, 399 return -EINVAL;
410 acm->fs.notify);
411 } 400 }
412 usb_ep_enable(acm->notify, acm->notify_desc); 401 usb_ep_enable(acm->notify);
413 acm->notify->driver_data = acm; 402 acm->notify->driver_data = acm;
414 403
415 } else if (intf == acm->data_id) { 404 } else if (intf == acm->data_id) {
416 if (acm->port.in->driver_data) { 405 if (acm->port.in->driver_data) {
417 DBG(cdev, "reset acm ttyGS%d\n", acm->port_num); 406 DBG(cdev, "reset acm ttyGS%d\n", acm->port_num);
418 gserial_disconnect(&acm->port); 407 gserial_disconnect(&acm->port);
419 } else { 408 }
409 if (!acm->port.in->desc || !acm->port.out->desc) {
420 DBG(cdev, "activate acm ttyGS%d\n", acm->port_num); 410 DBG(cdev, "activate acm ttyGS%d\n", acm->port_num);
421 acm->port.in_desc = ep_choose(cdev->gadget, 411 if (config_ep_by_speed(cdev->gadget, f,
422 acm->hs.in, acm->fs.in); 412 acm->port.in) ||
423 acm->port.out_desc = ep_choose(cdev->gadget, 413 config_ep_by_speed(cdev->gadget, f,
424 acm->hs.out, acm->fs.out); 414 acm->port.out)) {
415 acm->port.in->desc = NULL;
416 acm->port.out->desc = NULL;
417 return -EINVAL;
418 }
425 } 419 }
426 gserial_connect(&acm->port, acm->port_num); 420 gserial_connect(&acm->port, acm->port_num);
427 421
@@ -629,18 +623,11 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
629 acm->notify_req->complete = acm_cdc_notify_complete; 623 acm->notify_req->complete = acm_cdc_notify_complete;
630 acm->notify_req->context = acm; 624 acm->notify_req->context = acm;
631 625
632 /* copy descriptors, and track endpoint copies */ 626 /* copy descriptors */
633 f->descriptors = usb_copy_descriptors(acm_fs_function); 627 f->descriptors = usb_copy_descriptors(acm_fs_function);
634 if (!f->descriptors) 628 if (!f->descriptors)
635 goto fail; 629 goto fail;
636 630
637 acm->fs.in = usb_find_endpoint(acm_fs_function,
638 f->descriptors, &acm_fs_in_desc);
639 acm->fs.out = usb_find_endpoint(acm_fs_function,
640 f->descriptors, &acm_fs_out_desc);
641 acm->fs.notify = usb_find_endpoint(acm_fs_function,
642 f->descriptors, &acm_fs_notify_desc);
643
644 /* support all relevant hardware speeds... we expect that when 631 /* support all relevant hardware speeds... we expect that when
645 * hardware is dual speed, all bulk-capable endpoints work at 632 * hardware is dual speed, all bulk-capable endpoints work at
646 * both speeds 633 * both speeds
@@ -653,15 +640,8 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
653 acm_hs_notify_desc.bEndpointAddress = 640 acm_hs_notify_desc.bEndpointAddress =
654 acm_fs_notify_desc.bEndpointAddress; 641 acm_fs_notify_desc.bEndpointAddress;
655 642
656 /* copy descriptors, and track endpoint copies */ 643 /* copy descriptors */
657 f->hs_descriptors = usb_copy_descriptors(acm_hs_function); 644 f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
658
659 acm->hs.in = usb_find_endpoint(acm_hs_function,
660 f->hs_descriptors, &acm_hs_in_desc);
661 acm->hs.out = usb_find_endpoint(acm_hs_function,
662 f->hs_descriptors, &acm_hs_out_desc);
663 acm->hs.notify = usb_find_endpoint(acm_hs_function,
664 f->hs_descriptors, &acm_hs_notify_desc);
665 } 645 }
666 646
667 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", 647 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",