diff options
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r-- | drivers/usb/gadget/f_acm.c | 79 |
1 files changed, 24 insertions, 55 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d672250a61fa..549174466c21 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -87,7 +87,7 @@ static inline struct f_acm *port_to_acm(struct gserial *p) | |||
87 | 87 | ||
88 | /* notification endpoint uses smallish and infrequent fixed-size messages */ | 88 | /* notification endpoint uses smallish and infrequent fixed-size messages */ |
89 | 89 | ||
90 | #define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ | 90 | #define GS_NOTIFY_INTERVAL_MS 32 |
91 | #define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */ | 91 | #define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */ |
92 | 92 | ||
93 | /* interface and class descriptors: */ | 93 | /* interface and class descriptors: */ |
@@ -167,7 +167,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc = { | |||
167 | .bEndpointAddress = USB_DIR_IN, | 167 | .bEndpointAddress = USB_DIR_IN, |
168 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 168 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
169 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), | 169 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
170 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, | 170 | .bInterval = GS_NOTIFY_INTERVAL_MS, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static struct usb_endpoint_descriptor acm_fs_in_desc = { | 173 | static struct usb_endpoint_descriptor acm_fs_in_desc = { |
@@ -199,14 +199,13 @@ static struct usb_descriptor_header *acm_fs_function[] = { | |||
199 | }; | 199 | }; |
200 | 200 | ||
201 | /* high speed support: */ | 201 | /* high speed support: */ |
202 | |||
203 | static struct usb_endpoint_descriptor acm_hs_notify_desc = { | 202 | static struct usb_endpoint_descriptor acm_hs_notify_desc = { |
204 | .bLength = USB_DT_ENDPOINT_SIZE, | 203 | .bLength = USB_DT_ENDPOINT_SIZE, |
205 | .bDescriptorType = USB_DT_ENDPOINT, | 204 | .bDescriptorType = USB_DT_ENDPOINT, |
206 | .bEndpointAddress = USB_DIR_IN, | 205 | .bEndpointAddress = USB_DIR_IN, |
207 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 206 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
208 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), | 207 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
209 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, | 208 | .bInterval = USB_MS_TO_HS_INTERVAL(GS_NOTIFY_INTERVAL_MS), |
210 | }; | 209 | }; |
211 | 210 | ||
212 | static struct usb_endpoint_descriptor acm_hs_in_desc = { | 211 | static struct usb_endpoint_descriptor acm_hs_in_desc = { |
@@ -659,37 +658,22 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) | |||
659 | acm->notify_req->complete = acm_cdc_notify_complete; | 658 | acm->notify_req->complete = acm_cdc_notify_complete; |
660 | acm->notify_req->context = acm; | 659 | acm->notify_req->context = acm; |
661 | 660 | ||
662 | /* copy descriptors */ | ||
663 | f->descriptors = usb_copy_descriptors(acm_fs_function); | ||
664 | if (!f->descriptors) | ||
665 | goto fail; | ||
666 | |||
667 | /* support all relevant hardware speeds... we expect that when | 661 | /* support all relevant hardware speeds... we expect that when |
668 | * hardware is dual speed, all bulk-capable endpoints work at | 662 | * hardware is dual speed, all bulk-capable endpoints work at |
669 | * both speeds | 663 | * both speeds |
670 | */ | 664 | */ |
671 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 665 | acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress; |
672 | acm_hs_in_desc.bEndpointAddress = | 666 | acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress; |
673 | acm_fs_in_desc.bEndpointAddress; | 667 | acm_hs_notify_desc.bEndpointAddress = |
674 | acm_hs_out_desc.bEndpointAddress = | 668 | acm_fs_notify_desc.bEndpointAddress; |
675 | acm_fs_out_desc.bEndpointAddress; | 669 | |
676 | acm_hs_notify_desc.bEndpointAddress = | 670 | acm_ss_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress; |
677 | acm_fs_notify_desc.bEndpointAddress; | 671 | acm_ss_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress; |
678 | 672 | ||
679 | /* copy descriptors */ | 673 | status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function, |
680 | f->hs_descriptors = usb_copy_descriptors(acm_hs_function); | 674 | acm_ss_function); |
681 | } | 675 | if (status) |
682 | if (gadget_is_superspeed(c->cdev->gadget)) { | 676 | goto fail; |
683 | acm_ss_in_desc.bEndpointAddress = | ||
684 | acm_fs_in_desc.bEndpointAddress; | ||
685 | acm_ss_out_desc.bEndpointAddress = | ||
686 | acm_fs_out_desc.bEndpointAddress; | ||
687 | |||
688 | /* copy descriptors, and track endpoint copies */ | ||
689 | f->ss_descriptors = usb_copy_descriptors(acm_ss_function); | ||
690 | if (!f->ss_descriptors) | ||
691 | goto fail; | ||
692 | } | ||
693 | 677 | ||
694 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 678 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
695 | acm->port_num, | 679 | acm->port_num, |
@@ -721,11 +705,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
721 | { | 705 | { |
722 | struct f_acm *acm = func_to_acm(f); | 706 | struct f_acm *acm = func_to_acm(f); |
723 | 707 | ||
724 | if (gadget_is_dualspeed(c->cdev->gadget)) | 708 | acm_string_defs[0].id = 0; |
725 | usb_free_descriptors(f->hs_descriptors); | 709 | usb_free_all_descriptors(f); |
726 | if (gadget_is_superspeed(c->cdev->gadget)) | ||
727 | usb_free_descriptors(f->ss_descriptors); | ||
728 | usb_free_descriptors(f->descriptors); | ||
729 | gs_free_req(acm->notify, acm->notify_req); | 710 | gs_free_req(acm->notify, acm->notify_req); |
730 | kfree(acm); | 711 | kfree(acm); |
731 | } | 712 | } |
@@ -762,27 +743,15 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) | |||
762 | */ | 743 | */ |
763 | 744 | ||
764 | /* maybe allocate device-global string IDs, and patch descriptors */ | 745 | /* maybe allocate device-global string IDs, and patch descriptors */ |
765 | if (acm_string_defs[ACM_CTRL_IDX].id == 0) { | 746 | if (acm_string_defs[0].id == 0) { |
766 | status = usb_string_id(c->cdev); | 747 | status = usb_string_ids_tab(c->cdev, acm_string_defs); |
767 | if (status < 0) | 748 | if (status < 0) |
768 | return status; | 749 | return status; |
769 | acm_string_defs[ACM_CTRL_IDX].id = status; | 750 | acm_control_interface_desc.iInterface = |
770 | 751 | acm_string_defs[ACM_CTRL_IDX].id; | |
771 | acm_control_interface_desc.iInterface = status; | 752 | acm_data_interface_desc.iInterface = |
772 | 753 | acm_string_defs[ACM_DATA_IDX].id; | |
773 | status = usb_string_id(c->cdev); | 754 | acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id; |
774 | if (status < 0) | ||
775 | return status; | ||
776 | acm_string_defs[ACM_DATA_IDX].id = status; | ||
777 | |||
778 | acm_data_interface_desc.iInterface = status; | ||
779 | |||
780 | status = usb_string_id(c->cdev); | ||
781 | if (status < 0) | ||
782 | return status; | ||
783 | acm_string_defs[ACM_IAD_IDX].id = status; | ||
784 | |||
785 | acm_iad_descriptor.iFunction = status; | ||
786 | } | 755 | } |
787 | 756 | ||
788 | /* allocate and initialize one new instance */ | 757 | /* allocate and initialize one new instance */ |