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.c79
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
173static struct usb_endpoint_descriptor acm_fs_in_desc = { 173static 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
203static struct usb_endpoint_descriptor acm_hs_notify_desc = { 202static 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
212static struct usb_endpoint_descriptor acm_hs_in_desc = { 211static 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 */