diff options
Diffstat (limited to 'drivers/usb/gadget/f_rndis.c')
-rw-r--r-- | drivers/usb/gadget/f_rndis.c | 94 |
1 files changed, 25 insertions, 69 deletions
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index b1681e45aca7..71beeb833558 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -101,7 +101,7 @@ static unsigned int bitrate(struct usb_gadget *g) | |||
101 | /* | 101 | /* |
102 | */ | 102 | */ |
103 | 103 | ||
104 | #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ | 104 | #define RNDIS_STATUS_INTERVAL_MS 32 |
105 | #define STATUS_BYTECOUNT 8 /* 8 bytes data */ | 105 | #define STATUS_BYTECOUNT 8 /* 8 bytes data */ |
106 | 106 | ||
107 | 107 | ||
@@ -190,7 +190,7 @@ static struct usb_endpoint_descriptor fs_notify_desc = { | |||
190 | .bEndpointAddress = USB_DIR_IN, | 190 | .bEndpointAddress = USB_DIR_IN, |
191 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 191 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
192 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), | 192 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
193 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | 193 | .bInterval = RNDIS_STATUS_INTERVAL_MS, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | static struct usb_endpoint_descriptor fs_in_desc = { | 196 | static struct usb_endpoint_descriptor fs_in_desc = { |
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_notify_desc = { | |||
236 | .bEndpointAddress = USB_DIR_IN, | 236 | .bEndpointAddress = USB_DIR_IN, |
237 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 237 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
238 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), | 238 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
239 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 239 | .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS) |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static struct usb_endpoint_descriptor hs_in_desc = { | 242 | static struct usb_endpoint_descriptor hs_in_desc = { |
@@ -284,7 +284,7 @@ static struct usb_endpoint_descriptor ss_notify_desc = { | |||
284 | .bEndpointAddress = USB_DIR_IN, | 284 | .bEndpointAddress = USB_DIR_IN, |
285 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 285 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
286 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), | 286 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
287 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 287 | .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS) |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = { | 290 | static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = { |
@@ -722,42 +722,22 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
722 | rndis->notify_req->context = rndis; | 722 | rndis->notify_req->context = rndis; |
723 | rndis->notify_req->complete = rndis_response_complete; | 723 | rndis->notify_req->complete = rndis_response_complete; |
724 | 724 | ||
725 | /* copy descriptors, and track endpoint copies */ | ||
726 | f->descriptors = usb_copy_descriptors(eth_fs_function); | ||
727 | if (!f->descriptors) | ||
728 | goto fail; | ||
729 | |||
730 | /* support all relevant hardware speeds... we expect that when | 725 | /* support all relevant hardware speeds... we expect that when |
731 | * hardware is dual speed, all bulk-capable endpoints work at | 726 | * hardware is dual speed, all bulk-capable endpoints work at |
732 | * both speeds | 727 | * both speeds |
733 | */ | 728 | */ |
734 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 729 | hs_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress; |
735 | hs_in_desc.bEndpointAddress = | 730 | hs_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress; |
736 | fs_in_desc.bEndpointAddress; | 731 | hs_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; |
737 | hs_out_desc.bEndpointAddress = | ||
738 | fs_out_desc.bEndpointAddress; | ||
739 | hs_notify_desc.bEndpointAddress = | ||
740 | fs_notify_desc.bEndpointAddress; | ||
741 | |||
742 | /* copy descriptors, and track endpoint copies */ | ||
743 | f->hs_descriptors = usb_copy_descriptors(eth_hs_function); | ||
744 | if (!f->hs_descriptors) | ||
745 | goto fail; | ||
746 | } | ||
747 | 732 | ||
748 | if (gadget_is_superspeed(c->cdev->gadget)) { | 733 | ss_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress; |
749 | ss_in_desc.bEndpointAddress = | 734 | ss_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress; |
750 | fs_in_desc.bEndpointAddress; | 735 | ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; |
751 | ss_out_desc.bEndpointAddress = | 736 | |
752 | fs_out_desc.bEndpointAddress; | 737 | status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function, |
753 | ss_notify_desc.bEndpointAddress = | 738 | eth_ss_function); |
754 | fs_notify_desc.bEndpointAddress; | 739 | if (status) |
755 | 740 | goto fail; | |
756 | /* copy descriptors, and track endpoint copies */ | ||
757 | f->ss_descriptors = usb_copy_descriptors(eth_ss_function); | ||
758 | if (!f->ss_descriptors) | ||
759 | goto fail; | ||
760 | } | ||
761 | 741 | ||
762 | rndis->port.open = rndis_open; | 742 | rndis->port.open = rndis_open; |
763 | rndis->port.close = rndis_close; | 743 | rndis->port.close = rndis_close; |
@@ -788,12 +768,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
788 | return 0; | 768 | return 0; |
789 | 769 | ||
790 | fail: | 770 | fail: |
791 | if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors) | 771 | usb_free_all_descriptors(f); |
792 | usb_free_descriptors(f->ss_descriptors); | ||
793 | if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors) | ||
794 | usb_free_descriptors(f->hs_descriptors); | ||
795 | if (f->descriptors) | ||
796 | usb_free_descriptors(f->descriptors); | ||
797 | 772 | ||
798 | if (rndis->notify_req) { | 773 | if (rndis->notify_req) { |
799 | kfree(rndis->notify_req->buf); | 774 | kfree(rndis->notify_req->buf); |
@@ -803,9 +778,9 @@ fail: | |||
803 | /* we might as well release our claims on endpoints */ | 778 | /* we might as well release our claims on endpoints */ |
804 | if (rndis->notify) | 779 | if (rndis->notify) |
805 | rndis->notify->driver_data = NULL; | 780 | rndis->notify->driver_data = NULL; |
806 | if (rndis->port.out_ep->desc) | 781 | if (rndis->port.out_ep) |
807 | rndis->port.out_ep->driver_data = NULL; | 782 | rndis->port.out_ep->driver_data = NULL; |
808 | if (rndis->port.in_ep->desc) | 783 | if (rndis->port.in_ep) |
809 | rndis->port.in_ep->driver_data = NULL; | 784 | rndis->port.in_ep->driver_data = NULL; |
810 | 785 | ||
811 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | 786 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); |
@@ -820,13 +795,9 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) | |||
820 | 795 | ||
821 | rndis_deregister(rndis->config); | 796 | rndis_deregister(rndis->config); |
822 | rndis_exit(); | 797 | rndis_exit(); |
823 | rndis_string_defs[0].id = 0; | ||
824 | 798 | ||
825 | if (gadget_is_superspeed(c->cdev->gadget)) | 799 | rndis_string_defs[0].id = 0; |
826 | usb_free_descriptors(f->ss_descriptors); | 800 | usb_free_all_descriptors(f); |
827 | if (gadget_is_dualspeed(c->cdev->gadget)) | ||
828 | usb_free_descriptors(f->hs_descriptors); | ||
829 | usb_free_descriptors(f->descriptors); | ||
830 | 801 | ||
831 | kfree(rndis->notify_req->buf); | 802 | kfree(rndis->notify_req->buf); |
832 | usb_ep_free_request(rndis->notify, rndis->notify_req); | 803 | usb_ep_free_request(rndis->notify, rndis->notify_req); |
@@ -851,34 +822,19 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], | |||
851 | if (!can_support_rndis(c) || !ethaddr) | 822 | if (!can_support_rndis(c) || !ethaddr) |
852 | return -EINVAL; | 823 | return -EINVAL; |
853 | 824 | ||
854 | /* maybe allocate device-global string IDs */ | ||
855 | if (rndis_string_defs[0].id == 0) { | 825 | if (rndis_string_defs[0].id == 0) { |
856 | |||
857 | /* ... and setup RNDIS itself */ | 826 | /* ... and setup RNDIS itself */ |
858 | status = rndis_init(); | 827 | status = rndis_init(); |
859 | if (status < 0) | 828 | if (status < 0) |
860 | return status; | 829 | return status; |
861 | 830 | ||
862 | /* control interface label */ | 831 | status = usb_string_ids_tab(c->cdev, rndis_string_defs); |
863 | status = usb_string_id(c->cdev); | 832 | if (status) |
864 | if (status < 0) | ||
865 | return status; | 833 | return status; |
866 | rndis_string_defs[0].id = status; | ||
867 | rndis_control_intf.iInterface = status; | ||
868 | 834 | ||
869 | /* data interface label */ | 835 | rndis_control_intf.iInterface = rndis_string_defs[0].id; |
870 | status = usb_string_id(c->cdev); | 836 | rndis_data_intf.iInterface = rndis_string_defs[1].id; |
871 | if (status < 0) | 837 | rndis_iad_descriptor.iFunction = rndis_string_defs[2].id; |
872 | return status; | ||
873 | rndis_string_defs[1].id = status; | ||
874 | rndis_data_intf.iInterface = status; | ||
875 | |||
876 | /* IAD iFunction label */ | ||
877 | status = usb_string_id(c->cdev); | ||
878 | if (status < 0) | ||
879 | return status; | ||
880 | rndis_string_defs[2].id = status; | ||
881 | rndis_iad_descriptor.iFunction = status; | ||
882 | } | 838 | } |
883 | 839 | ||
884 | /* allocate and initialize one new instance */ | 840 | /* allocate and initialize one new instance */ |