diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-10-22 16:14:59 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-10-31 09:03:27 -0400 |
commit | 391aa852a372308c216d8638e57fe8fe560558f2 (patch) | |
tree | 5925c154b3484711c7deb77e0c5770a8cb84e7dc /drivers/usb | |
parent | 64dce9144507d4a6c624fe1b8e0aa88daeae0b9b (diff) |
usb: gadget: uac2: add some error recovery in afunc_bind()
In case something goes wrong here, don't leak memory / endpoints.
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/f_uac2.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index d3c6cffccb72..f02b8ece5287 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c | |||
@@ -978,15 +978,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
978 | INTF_SET(agdev->as_in_alt, ret); | 978 | INTF_SET(agdev->as_in_alt, ret); |
979 | 979 | ||
980 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); | 980 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); |
981 | if (!agdev->out_ep) | 981 | if (!agdev->out_ep) { |
982 | dev_err(&uac2->pdev.dev, | 982 | dev_err(&uac2->pdev.dev, |
983 | "%s:%d Error!\n", __func__, __LINE__); | 983 | "%s:%d Error!\n", __func__, __LINE__); |
984 | goto err; | ||
985 | } | ||
984 | agdev->out_ep->driver_data = agdev; | 986 | agdev->out_ep->driver_data = agdev; |
985 | 987 | ||
986 | agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); | 988 | agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); |
987 | if (!agdev->in_ep) | 989 | if (!agdev->in_ep) { |
988 | dev_err(&uac2->pdev.dev, | 990 | dev_err(&uac2->pdev.dev, |
989 | "%s:%d Error!\n", __func__, __LINE__); | 991 | "%s:%d Error!\n", __func__, __LINE__); |
992 | goto err; | ||
993 | } | ||
990 | agdev->in_ep->driver_data = agdev; | 994 | agdev->in_ep->driver_data = agdev; |
991 | 995 | ||
992 | hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; | 996 | hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; |
@@ -1005,6 +1009,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
1005 | prm->max_psize = 0; | 1009 | prm->max_psize = 0; |
1006 | dev_err(&uac2->pdev.dev, | 1010 | dev_err(&uac2->pdev.dev, |
1007 | "%s:%d Error!\n", __func__, __LINE__); | 1011 | "%s:%d Error!\n", __func__, __LINE__); |
1012 | goto err; | ||
1008 | } | 1013 | } |
1009 | 1014 | ||
1010 | prm = &agdev->uac2.p_prm; | 1015 | prm = &agdev->uac2.p_prm; |
@@ -1014,9 +1019,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
1014 | prm->max_psize = 0; | 1019 | prm->max_psize = 0; |
1015 | dev_err(&uac2->pdev.dev, | 1020 | dev_err(&uac2->pdev.dev, |
1016 | "%s:%d Error!\n", __func__, __LINE__); | 1021 | "%s:%d Error!\n", __func__, __LINE__); |
1022 | goto err; | ||
1017 | } | 1023 | } |
1018 | 1024 | ||
1019 | return alsa_uac2_init(agdev); | 1025 | ret = alsa_uac2_init(agdev); |
1026 | if (ret) | ||
1027 | goto err; | ||
1028 | return 0; | ||
1029 | err: | ||
1030 | kfree(agdev->uac2.p_prm.rbuf); | ||
1031 | kfree(agdev->uac2.c_prm.rbuf); | ||
1032 | usb_free_descriptors(fn->hs_descriptors); | ||
1033 | usb_free_descriptors(fn->descriptors); | ||
1034 | if (agdev->in_ep) | ||
1035 | agdev->in_ep->driver_data = NULL; | ||
1036 | if (agdev->out_ep) | ||
1037 | agdev->out_ep->driver_data = NULL; | ||
1038 | return -EINVAL; | ||
1020 | } | 1039 | } |
1021 | 1040 | ||
1022 | static void | 1041 | static void |