diff options
author | Johan Hovold <johan@kernel.org> | 2017-06-20 06:52:02 -0400 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2017-06-21 03:38:58 -0400 |
commit | 45e5d4d418f37cb9b2746c1fc63ab89b7b521d78 (patch) | |
tree | 12ad91df46a64960eeca5c2e4c14635bb9550b78 | |
parent | 08f741a93333dc81b6d17d25f712ca167f250b1a (diff) |
USB: serial: refactor port endpoint setup
Make the probe callback more readable by refactoring the port
endpoint-resource setup by adding four helper functions.
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 222 |
1 files changed, 130 insertions, 92 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c7ca95f64edc..f68275dd1e9f 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -742,6 +742,124 @@ static void find_endpoints(struct usb_serial *serial, | |||
742 | } | 742 | } |
743 | } | 743 | } |
744 | 744 | ||
745 | static int setup_port_bulk_in(struct usb_serial_port *port, | ||
746 | struct usb_endpoint_descriptor *epd) | ||
747 | { | ||
748 | struct usb_serial_driver *type = port->serial->type; | ||
749 | struct usb_device *udev = port->serial->dev; | ||
750 | int buffer_size; | ||
751 | int i; | ||
752 | |||
753 | buffer_size = max_t(int, type->bulk_in_size, usb_endpoint_maxp(epd)); | ||
754 | port->bulk_in_size = buffer_size; | ||
755 | port->bulk_in_endpointAddress = epd->bEndpointAddress; | ||
756 | |||
757 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { | ||
758 | set_bit(i, &port->read_urbs_free); | ||
759 | port->read_urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
760 | if (!port->read_urbs[i]) | ||
761 | return -ENOMEM; | ||
762 | port->bulk_in_buffers[i] = kmalloc(buffer_size, GFP_KERNEL); | ||
763 | if (!port->bulk_in_buffers[i]) | ||
764 | return -ENOMEM; | ||
765 | usb_fill_bulk_urb(port->read_urbs[i], udev, | ||
766 | usb_rcvbulkpipe(udev, epd->bEndpointAddress), | ||
767 | port->bulk_in_buffers[i], buffer_size, | ||
768 | type->read_bulk_callback, port); | ||
769 | } | ||
770 | |||
771 | port->read_urb = port->read_urbs[0]; | ||
772 | port->bulk_in_buffer = port->bulk_in_buffers[0]; | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static int setup_port_bulk_out(struct usb_serial_port *port, | ||
778 | struct usb_endpoint_descriptor *epd) | ||
779 | { | ||
780 | struct usb_serial_driver *type = port->serial->type; | ||
781 | struct usb_device *udev = port->serial->dev; | ||
782 | int buffer_size; | ||
783 | int i; | ||
784 | |||
785 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) | ||
786 | return -ENOMEM; | ||
787 | if (type->bulk_out_size) | ||
788 | buffer_size = type->bulk_out_size; | ||
789 | else | ||
790 | buffer_size = usb_endpoint_maxp(epd); | ||
791 | port->bulk_out_size = buffer_size; | ||
792 | port->bulk_out_endpointAddress = epd->bEndpointAddress; | ||
793 | |||
794 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { | ||
795 | set_bit(i, &port->write_urbs_free); | ||
796 | port->write_urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
797 | if (!port->write_urbs[i]) | ||
798 | return -ENOMEM; | ||
799 | port->bulk_out_buffers[i] = kmalloc(buffer_size, GFP_KERNEL); | ||
800 | if (!port->bulk_out_buffers[i]) | ||
801 | return -ENOMEM; | ||
802 | usb_fill_bulk_urb(port->write_urbs[i], udev, | ||
803 | usb_sndbulkpipe(udev, epd->bEndpointAddress), | ||
804 | port->bulk_out_buffers[i], buffer_size, | ||
805 | type->write_bulk_callback, port); | ||
806 | } | ||
807 | |||
808 | port->write_urb = port->write_urbs[0]; | ||
809 | port->bulk_out_buffer = port->bulk_out_buffers[0]; | ||
810 | |||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static int setup_port_interrupt_in(struct usb_serial_port *port, | ||
815 | struct usb_endpoint_descriptor *epd) | ||
816 | { | ||
817 | struct usb_serial_driver *type = port->serial->type; | ||
818 | struct usb_device *udev = port->serial->dev; | ||
819 | int buffer_size; | ||
820 | |||
821 | port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
822 | if (!port->interrupt_in_urb) | ||
823 | return -ENOMEM; | ||
824 | buffer_size = usb_endpoint_maxp(epd); | ||
825 | port->interrupt_in_endpointAddress = epd->bEndpointAddress; | ||
826 | port->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
827 | if (!port->interrupt_in_buffer) | ||
828 | return -ENOMEM; | ||
829 | usb_fill_int_urb(port->interrupt_in_urb, udev, | ||
830 | usb_rcvintpipe(udev, epd->bEndpointAddress), | ||
831 | port->interrupt_in_buffer, buffer_size, | ||
832 | type->read_int_callback, port, | ||
833 | epd->bInterval); | ||
834 | |||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static int setup_port_interrupt_out(struct usb_serial_port *port, | ||
839 | struct usb_endpoint_descriptor *epd) | ||
840 | { | ||
841 | struct usb_serial_driver *type = port->serial->type; | ||
842 | struct usb_device *udev = port->serial->dev; | ||
843 | int buffer_size; | ||
844 | |||
845 | port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
846 | if (!port->interrupt_out_urb) | ||
847 | return -ENOMEM; | ||
848 | buffer_size = usb_endpoint_maxp(epd); | ||
849 | port->interrupt_out_size = buffer_size; | ||
850 | port->interrupt_out_endpointAddress = epd->bEndpointAddress; | ||
851 | port->interrupt_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
852 | if (!port->interrupt_out_buffer) | ||
853 | return -ENOMEM; | ||
854 | usb_fill_int_urb(port->interrupt_out_urb, udev, | ||
855 | usb_sndintpipe(udev, epd->bEndpointAddress), | ||
856 | port->interrupt_out_buffer, buffer_size, | ||
857 | type->write_int_callback, port, | ||
858 | epd->bInterval); | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
745 | static int usb_serial_probe(struct usb_interface *interface, | 863 | static int usb_serial_probe(struct usb_interface *interface, |
746 | const struct usb_device_id *id) | 864 | const struct usb_device_id *id) |
747 | { | 865 | { |
@@ -749,13 +867,10 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
749 | struct usb_device *dev = interface_to_usbdev(interface); | 867 | struct usb_device *dev = interface_to_usbdev(interface); |
750 | struct usb_serial *serial = NULL; | 868 | struct usb_serial *serial = NULL; |
751 | struct usb_serial_port *port; | 869 | struct usb_serial_port *port; |
752 | struct usb_endpoint_descriptor *endpoint; | ||
753 | struct usb_serial_endpoints *epds; | 870 | struct usb_serial_endpoints *epds; |
754 | struct usb_serial_driver *type = NULL; | 871 | struct usb_serial_driver *type = NULL; |
755 | int retval; | 872 | int retval; |
756 | int buffer_size; | ||
757 | int i; | 873 | int i; |
758 | int j; | ||
759 | int num_ports = 0; | 874 | int num_ports = 0; |
760 | unsigned char max_endpoints; | 875 | unsigned char max_endpoints; |
761 | 876 | ||
@@ -867,86 +982,24 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
867 | 982 | ||
868 | /* set up the endpoint information */ | 983 | /* set up the endpoint information */ |
869 | for (i = 0; i < epds->num_bulk_in; ++i) { | 984 | for (i = 0; i < epds->num_bulk_in; ++i) { |
870 | endpoint = epds->bulk_in[i]; | 985 | retval = setup_port_bulk_in(serial->port[i], epds->bulk_in[i]); |
871 | port = serial->port[i]; | 986 | if (retval) |
872 | buffer_size = max_t(int, serial->type->bulk_in_size, | 987 | goto probe_error; |
873 | usb_endpoint_maxp(endpoint)); | ||
874 | port->bulk_in_size = buffer_size; | ||
875 | port->bulk_in_endpointAddress = endpoint->bEndpointAddress; | ||
876 | |||
877 | for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) { | ||
878 | set_bit(j, &port->read_urbs_free); | ||
879 | port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); | ||
880 | if (!port->read_urbs[j]) | ||
881 | goto probe_error; | ||
882 | port->bulk_in_buffers[j] = kmalloc(buffer_size, | ||
883 | GFP_KERNEL); | ||
884 | if (!port->bulk_in_buffers[j]) | ||
885 | goto probe_error; | ||
886 | usb_fill_bulk_urb(port->read_urbs[j], dev, | ||
887 | usb_rcvbulkpipe(dev, | ||
888 | endpoint->bEndpointAddress), | ||
889 | port->bulk_in_buffers[j], buffer_size, | ||
890 | serial->type->read_bulk_callback, | ||
891 | port); | ||
892 | } | ||
893 | |||
894 | port->read_urb = port->read_urbs[0]; | ||
895 | port->bulk_in_buffer = port->bulk_in_buffers[0]; | ||
896 | } | 988 | } |
897 | 989 | ||
898 | for (i = 0; i < epds->num_bulk_out; ++i) { | 990 | for (i = 0; i < epds->num_bulk_out; ++i) { |
899 | endpoint = epds->bulk_out[i]; | 991 | retval = setup_port_bulk_out(serial->port[i], |
900 | port = serial->port[i]; | 992 | epds->bulk_out[i]); |
901 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) | 993 | if (retval) |
902 | goto probe_error; | 994 | goto probe_error; |
903 | buffer_size = serial->type->bulk_out_size; | ||
904 | if (!buffer_size) | ||
905 | buffer_size = usb_endpoint_maxp(endpoint); | ||
906 | port->bulk_out_size = buffer_size; | ||
907 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; | ||
908 | |||
909 | for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) { | ||
910 | set_bit(j, &port->write_urbs_free); | ||
911 | port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); | ||
912 | if (!port->write_urbs[j]) | ||
913 | goto probe_error; | ||
914 | port->bulk_out_buffers[j] = kmalloc(buffer_size, | ||
915 | GFP_KERNEL); | ||
916 | if (!port->bulk_out_buffers[j]) | ||
917 | goto probe_error; | ||
918 | usb_fill_bulk_urb(port->write_urbs[j], dev, | ||
919 | usb_sndbulkpipe(dev, | ||
920 | endpoint->bEndpointAddress), | ||
921 | port->bulk_out_buffers[j], buffer_size, | ||
922 | serial->type->write_bulk_callback, | ||
923 | port); | ||
924 | } | ||
925 | |||
926 | port->write_urb = port->write_urbs[0]; | ||
927 | port->bulk_out_buffer = port->bulk_out_buffers[0]; | ||
928 | } | 995 | } |
929 | 996 | ||
930 | if (serial->type->read_int_callback) { | 997 | if (serial->type->read_int_callback) { |
931 | for (i = 0; i < epds->num_interrupt_in; ++i) { | 998 | for (i = 0; i < epds->num_interrupt_in; ++i) { |
932 | endpoint = epds->interrupt_in[i]; | 999 | retval = setup_port_interrupt_in(serial->port[i], |
933 | port = serial->port[i]; | 1000 | epds->interrupt_in[i]); |
934 | port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 1001 | if (retval) |
935 | if (!port->interrupt_in_urb) | ||
936 | goto probe_error; | ||
937 | buffer_size = usb_endpoint_maxp(endpoint); | ||
938 | port->interrupt_in_endpointAddress = | ||
939 | endpoint->bEndpointAddress; | ||
940 | port->interrupt_in_buffer = kmalloc(buffer_size, | ||
941 | GFP_KERNEL); | ||
942 | if (!port->interrupt_in_buffer) | ||
943 | goto probe_error; | 1002 | goto probe_error; |
944 | usb_fill_int_urb(port->interrupt_in_urb, dev, | ||
945 | usb_rcvintpipe(dev, | ||
946 | endpoint->bEndpointAddress), | ||
947 | port->interrupt_in_buffer, buffer_size, | ||
948 | serial->type->read_int_callback, port, | ||
949 | endpoint->bInterval); | ||
950 | } | 1003 | } |
951 | } else if (epds->num_interrupt_in) { | 1004 | } else if (epds->num_interrupt_in) { |
952 | dev_dbg(ddev, "The device claims to support interrupt in transfers, but read_int_callback is not defined\n"); | 1005 | dev_dbg(ddev, "The device claims to support interrupt in transfers, but read_int_callback is not defined\n"); |
@@ -954,25 +1007,10 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
954 | 1007 | ||
955 | if (serial->type->write_int_callback) { | 1008 | if (serial->type->write_int_callback) { |
956 | for (i = 0; i < epds->num_interrupt_out; ++i) { | 1009 | for (i = 0; i < epds->num_interrupt_out; ++i) { |
957 | endpoint = epds->interrupt_out[i]; | 1010 | retval = setup_port_interrupt_out(serial->port[i], |
958 | port = serial->port[i]; | 1011 | epds->interrupt_out[i]); |
959 | port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 1012 | if (retval) |
960 | if (!port->interrupt_out_urb) | ||
961 | goto probe_error; | ||
962 | buffer_size = usb_endpoint_maxp(endpoint); | ||
963 | port->interrupt_out_size = buffer_size; | ||
964 | port->interrupt_out_endpointAddress = | ||
965 | endpoint->bEndpointAddress; | ||
966 | port->interrupt_out_buffer = kmalloc(buffer_size, | ||
967 | GFP_KERNEL); | ||
968 | if (!port->interrupt_out_buffer) | ||
969 | goto probe_error; | 1013 | goto probe_error; |
970 | usb_fill_int_urb(port->interrupt_out_urb, dev, | ||
971 | usb_sndintpipe(dev, | ||
972 | endpoint->bEndpointAddress), | ||
973 | port->interrupt_out_buffer, buffer_size, | ||
974 | serial->type->write_int_callback, port, | ||
975 | endpoint->bInterval); | ||
976 | } | 1014 | } |
977 | } else if (epds->num_interrupt_out) { | 1015 | } else if (epds->num_interrupt_out) { |
978 | dev_dbg(ddev, "The device claims to support interrupt out transfers, but write_int_callback is not defined\n"); | 1016 | dev_dbg(ddev, "The device claims to support interrupt out transfers, but write_int_callback is not defined\n"); |