From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: Dmitry Torokhov , Sasha Levin Subject: [PATCH AUTOSEL 4.18 19/88] Input: pxrc - fix freeing URB on device teardown Date: Fri, 7 Sep 2018 00:36:06 +0000 Message-ID: <20180907003547.57567-19-alexander.levin@microsoft.com> References: <20180907003547.57567-1-alexander.levin@microsoft.com> In-Reply-To: <20180907003547.57567-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: From: Dmitry Torokhov [ Upstream commit 34dad2cf1104869ce2db2bddb34f8e6780c2ddaa ] URB is the only resource that is not managed, and thus is destroyed too ear= ly, before we unregister input device and stop URB in pxrc_close(). To fix it l= et's install custom devm handler to free the URB at the right time in devm unwin= d sequence. Reviewed-by: Marcus Folkesson Tested-by: Marcus Folkesson Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/joystick/pxrc.c | 66 ++++++++++++++++------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/drivers/input/joystick/pxrc.c b/drivers/input/joystick/pxrc.c index 07a0dbd3ced2..cfb410cf0789 100644 --- a/drivers/input/joystick/pxrc.c +++ b/drivers/input/joystick/pxrc.c @@ -120,48 +120,51 @@ static void pxrc_close(struct input_dev *input) mutex_unlock(&pxrc->pm_mutex); } =20 +static void pxrc_free_urb(void *_pxrc) +{ + struct pxrc *pxrc =3D _pxrc; + + usb_free_urb(pxrc->urb); +} + static int pxrc_usb_init(struct pxrc *pxrc) { struct usb_endpoint_descriptor *epirq; unsigned int pipe; - int retval; + int error; =20 /* Set up the endpoint information */ /* This device only has an interrupt endpoint */ - retval =3D usb_find_common_endpoints(pxrc->intf->cur_altsetting, - NULL, NULL, &epirq, NULL); - if (retval) { - dev_err(&pxrc->intf->dev, - "Could not find endpoint\n"); - goto error; + error =3D usb_find_common_endpoints(pxrc->intf->cur_altsetting, + NULL, NULL, &epirq, NULL); + if (error) { + dev_err(&pxrc->intf->dev, "Could not find endpoint\n"); + return error; } =20 pxrc->bsize =3D usb_endpoint_maxp(epirq); pxrc->epaddr =3D epirq->bEndpointAddress; pxrc->data =3D devm_kmalloc(&pxrc->intf->dev, pxrc->bsize, GFP_KERNEL); - if (!pxrc->data) { - retval =3D -ENOMEM; - goto error; - } + if (!pxrc->data) + return -ENOMEM; =20 usb_set_intfdata(pxrc->intf, pxrc); usb_make_path(pxrc->udev, pxrc->phys, sizeof(pxrc->phys)); strlcat(pxrc->phys, "/input0", sizeof(pxrc->phys)); =20 pxrc->urb =3D usb_alloc_urb(0, GFP_KERNEL); - if (!pxrc->urb) { - retval =3D -ENOMEM; - goto error; - } + if (!pxrc->urb) + return -ENOMEM; + + error =3D devm_add_action_or_reset(&pxrc->intf->dev, pxrc_free_urb, pxrc)= ; + if (error) + return error; =20 pipe =3D usb_rcvintpipe(pxrc->udev, pxrc->epaddr), usb_fill_int_urb(pxrc->urb, pxrc->udev, pipe, pxrc->data, pxrc->bsize, pxrc_usb_irq, pxrc, 1); =20 -error: - return retval; - - + return 0; } =20 static int pxrc_input_init(struct pxrc *pxrc) @@ -197,7 +200,7 @@ static int pxrc_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct pxrc *pxrc; - int retval; + int error; =20 pxrc =3D devm_kzalloc(&intf->dev, sizeof(*pxrc), GFP_KERNEL); if (!pxrc) @@ -207,29 +210,20 @@ static int pxrc_probe(struct usb_interface *intf, pxrc->udev =3D usb_get_dev(interface_to_usbdev(intf)); pxrc->intf =3D intf; =20 - retval =3D pxrc_usb_init(pxrc); - if (retval) - goto error; + error =3D pxrc_usb_init(pxrc); + if (error) + return error; =20 - retval =3D pxrc_input_init(pxrc); - if (retval) - goto err_free_urb; + error =3D pxrc_input_init(pxrc); + if (error) + return error; =20 return 0; - -err_free_urb: - usb_free_urb(pxrc->urb); - -error: - return retval; } =20 static void pxrc_disconnect(struct usb_interface *intf) { - struct pxrc *pxrc =3D usb_get_intfdata(intf); - - usb_free_urb(pxrc->urb); - usb_set_intfdata(intf, NULL); + /* All driver resources are devm-managed. */ } =20 static int pxrc_suspend(struct usb_interface *intf, pm_message_t message) --=20 2.17.1