diff options
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r-- | drivers/usb/gadget/f_acm.c | 50 |
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 | ||
42 | struct acm_ep_descs { | ||
43 | struct usb_endpoint_descriptor *in; | ||
44 | struct usb_endpoint_descriptor *out; | ||
45 | struct usb_endpoint_descriptor *notify; | ||
46 | }; | ||
47 | |||
48 | struct f_acm { | 42 | struct 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", |