summaryrefslogtreecommitdiffstats
path: root/drivers/uwb
diff options
context:
space:
mode:
authorThomas Pugliese <thomas.pugliese@gmail.com>2013-08-09 10:25:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-12 18:41:08 -0400
commitc654ecbbfefbeec8fbf202e117364bff48ecaea3 (patch)
tree262c335c73b088ef1851c926f7bfe5f95f8cf33c /drivers/uwb
parent6dd433e6cf2475ce8abec1b467720858c24450eb (diff)
HWA RC: fix a kernel panic when unplugging the HWA dongle
This patch fixes a kernel panic that can occur when unplugging the HWA dongle while a downstream device is in the process of disconnecting. This involved 2 changes. First, call usb_lock_device_for_reset before usb_reset_device to synchronize the HWA's post_rest and disconnect routines. Second, set the hwarc->neep_urb and hwarc->rd_buffer to NULL when they are freed in the error path in the post_reset routine. This prevents a double free when the disconnect routine is called and attempts to free those resources again. Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/uwb')
-rw-r--r--drivers/uwb/hwa-rc.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 0621abef9b4a..0257f35cfb9d 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -611,7 +611,16 @@ static
611int hwarc_reset(struct uwb_rc *uwb_rc) 611int hwarc_reset(struct uwb_rc *uwb_rc)
612{ 612{
613 struct hwarc *hwarc = uwb_rc->priv; 613 struct hwarc *hwarc = uwb_rc->priv;
614 return usb_reset_device(hwarc->usb_dev); 614 int result;
615
616 /* device lock must be held when calling usb_reset_device. */
617 result = usb_lock_device_for_reset(hwarc->usb_dev, NULL);
618 if (result >= 0) {
619 result = usb_reset_device(hwarc->usb_dev);
620 usb_unlock_device(hwarc->usb_dev);
621 }
622
623 return result;
615} 624}
616 625
617/** 626/**
@@ -709,8 +718,10 @@ static int hwarc_neep_init(struct uwb_rc *rc)
709 718
710error_neep_submit: 719error_neep_submit:
711 usb_free_urb(hwarc->neep_urb); 720 usb_free_urb(hwarc->neep_urb);
721 hwarc->neep_urb = NULL;
712error_urb_alloc: 722error_urb_alloc:
713 free_page((unsigned long)hwarc->rd_buffer); 723 free_page((unsigned long)hwarc->rd_buffer);
724 hwarc->rd_buffer = NULL;
714error_rd_buffer: 725error_rd_buffer:
715 return -ENOMEM; 726 return -ENOMEM;
716} 727}
@@ -723,7 +734,10 @@ static void hwarc_neep_release(struct uwb_rc *rc)
723 734
724 usb_kill_urb(hwarc->neep_urb); 735 usb_kill_urb(hwarc->neep_urb);
725 usb_free_urb(hwarc->neep_urb); 736 usb_free_urb(hwarc->neep_urb);
737 hwarc->neep_urb = NULL;
738
726 free_page((unsigned long)hwarc->rd_buffer); 739 free_page((unsigned long)hwarc->rd_buffer);
740 hwarc->rd_buffer = NULL;
727} 741}
728 742
729/** 743/**