diff options
Diffstat (limited to 'drivers/input/joystick/xpad.c')
-rw-r--r-- | drivers/input/joystick/xpad.c | 123 |
1 files changed, 71 insertions, 52 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f9fb7fa10af3..56abf3d0e911 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -543,21 +543,25 @@ exit: | |||
543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
544 | { | 544 | { |
545 | struct usb_endpoint_descriptor *ep_irq_out; | 545 | struct usb_endpoint_descriptor *ep_irq_out; |
546 | int error = -ENOMEM; | 546 | int error; |
547 | 547 | ||
548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) | 548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
549 | return 0; | 549 | return 0; |
550 | 550 | ||
551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, | 551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, |
552 | GFP_KERNEL, &xpad->odata_dma); | 552 | GFP_KERNEL, &xpad->odata_dma); |
553 | if (!xpad->odata) | 553 | if (!xpad->odata) { |
554 | error = -ENOMEM; | ||
554 | goto fail1; | 555 | goto fail1; |
556 | } | ||
555 | 557 | ||
556 | mutex_init(&xpad->odata_mutex); | 558 | mutex_init(&xpad->odata_mutex); |
557 | 559 | ||
558 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); | 560 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); |
559 | if (!xpad->irq_out) | 561 | if (!xpad->irq_out) { |
562 | error = -ENOMEM; | ||
560 | goto fail2; | 563 | goto fail2; |
564 | } | ||
561 | 565 | ||
562 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; | 566 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; |
563 | usb_fill_int_urb(xpad->irq_out, xpad->udev, | 567 | usb_fill_int_urb(xpad->irq_out, xpad->udev, |
@@ -728,7 +732,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) | |||
728 | 732 | ||
729 | if (xpad_led) { | 733 | if (xpad_led) { |
730 | led_classdev_unregister(&xpad_led->led_cdev); | 734 | led_classdev_unregister(&xpad_led->led_cdev); |
731 | kfree(xpad_led->name); | 735 | kfree(xpad_led); |
732 | } | 736 | } |
733 | } | 737 | } |
734 | #else | 738 | #else |
@@ -756,8 +760,9 @@ static void xpad_close(struct input_dev *dev) | |||
756 | { | 760 | { |
757 | struct usb_xpad *xpad = input_get_drvdata(dev); | 761 | struct usb_xpad *xpad = input_get_drvdata(dev); |
758 | 762 | ||
759 | if(xpad->xtype != XTYPE_XBOX360W) | 763 | if (xpad->xtype != XTYPE_XBOX360W) |
760 | usb_kill_urb(xpad->irq_in); | 764 | usb_kill_urb(xpad->irq_in); |
765 | |||
761 | xpad_stop_output(xpad); | 766 | xpad_stop_output(xpad); |
762 | } | 767 | } |
763 | 768 | ||
@@ -789,8 +794,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
789 | struct usb_xpad *xpad; | 794 | struct usb_xpad *xpad; |
790 | struct input_dev *input_dev; | 795 | struct input_dev *input_dev; |
791 | struct usb_endpoint_descriptor *ep_irq_in; | 796 | struct usb_endpoint_descriptor *ep_irq_in; |
792 | int i; | 797 | int i, error; |
793 | int error = -ENOMEM; | ||
794 | 798 | ||
795 | for (i = 0; xpad_device[i].idVendor; i++) { | 799 | for (i = 0; xpad_device[i].idVendor; i++) { |
796 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && | 800 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && |
@@ -800,17 +804,23 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
800 | 804 | ||
801 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); | 805 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
802 | input_dev = input_allocate_device(); | 806 | input_dev = input_allocate_device(); |
803 | if (!xpad || !input_dev) | 807 | if (!xpad || !input_dev) { |
808 | error = -ENOMEM; | ||
804 | goto fail1; | 809 | goto fail1; |
810 | } | ||
805 | 811 | ||
806 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, | 812 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, |
807 | GFP_KERNEL, &xpad->idata_dma); | 813 | GFP_KERNEL, &xpad->idata_dma); |
808 | if (!xpad->idata) | 814 | if (!xpad->idata) { |
815 | error = -ENOMEM; | ||
809 | goto fail1; | 816 | goto fail1; |
817 | } | ||
810 | 818 | ||
811 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); | 819 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); |
812 | if (!xpad->irq_in) | 820 | if (!xpad->irq_in) { |
821 | error = -ENOMEM; | ||
813 | goto fail2; | 822 | goto fail2; |
823 | } | ||
814 | 824 | ||
815 | xpad->udev = udev; | 825 | xpad->udev = udev; |
816 | xpad->mapping = xpad_device[i].mapping; | 826 | xpad->mapping = xpad_device[i].mapping; |
@@ -887,15 +897,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
887 | 897 | ||
888 | error = xpad_init_output(intf, xpad); | 898 | error = xpad_init_output(intf, xpad); |
889 | if (error) | 899 | if (error) |
890 | goto fail2; | 900 | goto fail3; |
891 | 901 | ||
892 | error = xpad_init_ff(xpad); | 902 | error = xpad_init_ff(xpad); |
893 | if (error) | 903 | if (error) |
894 | goto fail3; | 904 | goto fail4; |
895 | 905 | ||
896 | error = xpad_led_probe(xpad); | 906 | error = xpad_led_probe(xpad); |
897 | if (error) | 907 | if (error) |
898 | goto fail3; | 908 | goto fail5; |
899 | 909 | ||
900 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 910 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
901 | usb_fill_int_urb(xpad->irq_in, udev, | 911 | usb_fill_int_urb(xpad->irq_in, udev, |
@@ -907,34 +917,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
907 | 917 | ||
908 | error = input_register_device(xpad->dev); | 918 | error = input_register_device(xpad->dev); |
909 | if (error) | 919 | if (error) |
910 | goto fail4; | 920 | goto fail6; |
911 | 921 | ||
912 | usb_set_intfdata(intf, xpad); | 922 | usb_set_intfdata(intf, xpad); |
913 | 923 | ||
914 | /* | ||
915 | * Submit the int URB immediatly rather than waiting for open | ||
916 | * because we get status messages from the device whether | ||
917 | * or not any controllers are attached. In fact, it's | ||
918 | * exactly the message that a controller has arrived that | ||
919 | * we're waiting for. | ||
920 | */ | ||
921 | if (xpad->xtype == XTYPE_XBOX360W) { | 924 | if (xpad->xtype == XTYPE_XBOX360W) { |
922 | xpad->irq_in->dev = xpad->udev; | ||
923 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
924 | if (error) | ||
925 | goto fail4; | ||
926 | |||
927 | /* | 925 | /* |
928 | * Setup the message to set the LEDs on the | 926 | * Setup the message to set the LEDs on the |
929 | * controller when it shows up | 927 | * controller when it shows up |
930 | */ | 928 | */ |
931 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); | 929 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); |
932 | if(!xpad->bulk_out) | 930 | if (!xpad->bulk_out) { |
933 | goto fail5; | 931 | error = -ENOMEM; |
932 | goto fail7; | ||
933 | } | ||
934 | 934 | ||
935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); | 935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); |
936 | if(!xpad->bdata) | 936 | if (!xpad->bdata) { |
937 | goto fail6; | 937 | error = -ENOMEM; |
938 | goto fail8; | ||
939 | } | ||
938 | 940 | ||
939 | xpad->bdata[2] = 0x08; | 941 | xpad->bdata[2] = 0x08; |
940 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { | 942 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { |
@@ -955,14 +957,31 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
955 | usb_fill_bulk_urb(xpad->bulk_out, udev, | 957 | usb_fill_bulk_urb(xpad->bulk_out, udev, |
956 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), | 958 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), |
957 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); | 959 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); |
960 | |||
961 | /* | ||
962 | * Submit the int URB immediately rather than waiting for open | ||
963 | * because we get status messages from the device whether | ||
964 | * or not any controllers are attached. In fact, it's | ||
965 | * exactly the message that a controller has arrived that | ||
966 | * we're waiting for. | ||
967 | */ | ||
968 | xpad->irq_in->dev = xpad->udev; | ||
969 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
970 | if (error) | ||
971 | goto fail9; | ||
958 | } | 972 | } |
959 | 973 | ||
960 | return 0; | 974 | return 0; |
961 | 975 | ||
962 | fail6: usb_free_urb(xpad->bulk_out); | 976 | fail9: kfree(xpad->bdata); |
963 | fail5: usb_kill_urb(xpad->irq_in); | 977 | fail8: usb_free_urb(xpad->bulk_out); |
964 | fail4: usb_free_urb(xpad->irq_in); | 978 | fail7: input_unregister_device(input_dev); |
965 | fail3: xpad_deinit_output(xpad); | 979 | input_dev = NULL; |
980 | fail6: xpad_led_disconnect(xpad); | ||
981 | fail5: if (input_dev) | ||
982 | input_ff_destroy(input_dev); | ||
983 | fail4: xpad_deinit_output(xpad); | ||
984 | fail3: usb_free_urb(xpad->irq_in); | ||
966 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 985 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
967 | fail1: input_free_device(input_dev); | 986 | fail1: input_free_device(input_dev); |
968 | kfree(xpad); | 987 | kfree(xpad); |
@@ -974,21 +993,24 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
974 | { | 993 | { |
975 | struct usb_xpad *xpad = usb_get_intfdata (intf); | 994 | struct usb_xpad *xpad = usb_get_intfdata (intf); |
976 | 995 | ||
977 | usb_set_intfdata(intf, NULL); | 996 | xpad_led_disconnect(xpad); |
978 | if (xpad) { | 997 | input_unregister_device(xpad->dev); |
979 | xpad_led_disconnect(xpad); | 998 | xpad_deinit_output(xpad); |
980 | input_unregister_device(xpad->dev); | 999 | |
981 | xpad_deinit_output(xpad); | 1000 | if (xpad->xtype == XTYPE_XBOX360W) { |
982 | if (xpad->xtype == XTYPE_XBOX360W) { | 1001 | usb_kill_urb(xpad->bulk_out); |
983 | usb_kill_urb(xpad->bulk_out); | 1002 | usb_free_urb(xpad->bulk_out); |
984 | usb_free_urb(xpad->bulk_out); | 1003 | usb_kill_urb(xpad->irq_in); |
985 | usb_kill_urb(xpad->irq_in); | ||
986 | } | ||
987 | usb_free_urb(xpad->irq_in); | ||
988 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
989 | xpad->idata, xpad->idata_dma); | ||
990 | kfree(xpad); | ||
991 | } | 1004 | } |
1005 | |||
1006 | usb_free_urb(xpad->irq_in); | ||
1007 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
1008 | xpad->idata, xpad->idata_dma); | ||
1009 | |||
1010 | kfree(xpad->bdata); | ||
1011 | kfree(xpad); | ||
1012 | |||
1013 | usb_set_intfdata(intf, NULL); | ||
992 | } | 1014 | } |
993 | 1015 | ||
994 | static struct usb_driver xpad_driver = { | 1016 | static struct usb_driver xpad_driver = { |
@@ -1000,10 +1022,7 @@ static struct usb_driver xpad_driver = { | |||
1000 | 1022 | ||
1001 | static int __init usb_xpad_init(void) | 1023 | static int __init usb_xpad_init(void) |
1002 | { | 1024 | { |
1003 | int result = usb_register(&xpad_driver); | 1025 | return usb_register(&xpad_driver); |
1004 | if (result == 0) | ||
1005 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); | ||
1006 | return result; | ||
1007 | } | 1026 | } |
1008 | 1027 | ||
1009 | static void __exit usb_xpad_exit(void) | 1028 | static void __exit usb_xpad_exit(void) |