diff options
author | Axel Lin <axel.lin@gmail.com> | 2010-11-12 00:47:42 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-12 01:02:23 -0500 |
commit | 161feb2417dd0c4324c2e8da24aaebd30a436d45 (patch) | |
tree | 5f641e5d73b5235ff19021eeca505a19402c590f /drivers/input/joystick | |
parent | 6ff92a6db2083ecd1a8e2742d9397159fd880987 (diff) |
Input: xpad - fix resource reclaim in xpad_probe error path
Properly free the resources in error path by the reverse order of resource
allocation.
Signed-off-by: Axel Lin <axel.lin@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/joystick')
-rw-r--r-- | drivers/input/joystick/xpad.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index e8b2ece3e01e..5fce72433932 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -760,8 +760,9 @@ static void xpad_close(struct input_dev *dev) | |||
760 | { | 760 | { |
761 | struct usb_xpad *xpad = input_get_drvdata(dev); | 761 | struct usb_xpad *xpad = input_get_drvdata(dev); |
762 | 762 | ||
763 | if(xpad->xtype != XTYPE_XBOX360W) | 763 | if (xpad->xtype != XTYPE_XBOX360W) |
764 | usb_kill_urb(xpad->irq_in); | 764 | usb_kill_urb(xpad->irq_in); |
765 | |||
765 | xpad_stop_output(xpad); | 766 | xpad_stop_output(xpad); |
766 | } | 767 | } |
767 | 768 | ||
@@ -896,15 +897,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
896 | 897 | ||
897 | error = xpad_init_output(intf, xpad); | 898 | error = xpad_init_output(intf, xpad); |
898 | if (error) | 899 | if (error) |
899 | goto fail2; | 900 | goto fail3; |
900 | 901 | ||
901 | error = xpad_init_ff(xpad); | 902 | error = xpad_init_ff(xpad); |
902 | if (error) | 903 | if (error) |
903 | goto fail3; | 904 | goto fail4; |
904 | 905 | ||
905 | error = xpad_led_probe(xpad); | 906 | error = xpad_led_probe(xpad); |
906 | if (error) | 907 | if (error) |
907 | goto fail3; | 908 | goto fail5; |
908 | 909 | ||
909 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 910 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
910 | usb_fill_int_urb(xpad->irq_in, udev, | 911 | usb_fill_int_urb(xpad->irq_in, udev, |
@@ -916,7 +917,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
916 | 917 | ||
917 | error = input_register_device(xpad->dev); | 918 | error = input_register_device(xpad->dev); |
918 | if (error) | 919 | if (error) |
919 | goto fail4; | 920 | goto fail6; |
920 | 921 | ||
921 | usb_set_intfdata(intf, xpad); | 922 | usb_set_intfdata(intf, xpad); |
922 | 923 | ||
@@ -931,7 +932,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
931 | xpad->irq_in->dev = xpad->udev; | 932 | xpad->irq_in->dev = xpad->udev; |
932 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | 933 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); |
933 | if (error) | 934 | if (error) |
934 | goto fail4; | 935 | goto fail7; |
935 | 936 | ||
936 | /* | 937 | /* |
937 | * Setup the message to set the LEDs on the | 938 | * Setup the message to set the LEDs on the |
@@ -940,13 +941,13 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
940 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); | 941 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); |
941 | if (!xpad->bulk_out) { | 942 | if (!xpad->bulk_out) { |
942 | error = -ENOMEM; | 943 | error = -ENOMEM; |
943 | goto fail5; | 944 | goto fail8; |
944 | } | 945 | } |
945 | 946 | ||
946 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); | 947 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); |
947 | if (!xpad->bdata) { | 948 | if (!xpad->bdata) { |
948 | error = -ENOMEM; | 949 | error = -ENOMEM; |
949 | goto fail6; | 950 | goto fail9; |
950 | } | 951 | } |
951 | 952 | ||
952 | xpad->bdata[2] = 0x08; | 953 | xpad->bdata[2] = 0x08; |
@@ -972,10 +973,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
972 | 973 | ||
973 | return 0; | 974 | return 0; |
974 | 975 | ||
975 | fail6: usb_free_urb(xpad->bulk_out); | 976 | fail9: usb_free_urb(xpad->bulk_out); |
976 | fail5: usb_kill_urb(xpad->irq_in); | 977 | fail8: usb_kill_urb(xpad->irq_in); |
977 | fail4: usb_free_urb(xpad->irq_in); | 978 | fail7: input_unregister_device(input_dev); |
978 | 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); | ||
979 | 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); |
980 | fail1: input_free_device(input_dev); | 986 | fail1: input_free_device(input_dev); |
981 | kfree(xpad); | 987 | kfree(xpad); |