Commit c654ecbb authored by Thomas Pugliese's avatar Thomas Pugliese Committed by Greg Kroah-Hartman

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: default avatarThomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6dd433e6
...@@ -611,7 +611,16 @@ static ...@@ -611,7 +611,16 @@ static
int hwarc_reset(struct uwb_rc *uwb_rc) int hwarc_reset(struct uwb_rc *uwb_rc)
{ {
struct hwarc *hwarc = uwb_rc->priv; struct hwarc *hwarc = uwb_rc->priv;
return usb_reset_device(hwarc->usb_dev); int result;
/* device lock must be held when calling usb_reset_device. */
result = usb_lock_device_for_reset(hwarc->usb_dev, NULL);
if (result >= 0) {
result = usb_reset_device(hwarc->usb_dev);
usb_unlock_device(hwarc->usb_dev);
}
return result;
} }
/** /**
...@@ -709,8 +718,10 @@ static int hwarc_neep_init(struct uwb_rc *rc) ...@@ -709,8 +718,10 @@ static int hwarc_neep_init(struct uwb_rc *rc)
error_neep_submit: error_neep_submit:
usb_free_urb(hwarc->neep_urb); usb_free_urb(hwarc->neep_urb);
hwarc->neep_urb = NULL;
error_urb_alloc: error_urb_alloc:
free_page((unsigned long)hwarc->rd_buffer); free_page((unsigned long)hwarc->rd_buffer);
hwarc->rd_buffer = NULL;
error_rd_buffer: error_rd_buffer:
return -ENOMEM; return -ENOMEM;
} }
...@@ -723,7 +734,10 @@ static void hwarc_neep_release(struct uwb_rc *rc) ...@@ -723,7 +734,10 @@ static void hwarc_neep_release(struct uwb_rc *rc)
usb_kill_urb(hwarc->neep_urb); usb_kill_urb(hwarc->neep_urb);
usb_free_urb(hwarc->neep_urb); usb_free_urb(hwarc->neep_urb);
hwarc->neep_urb = NULL;
free_page((unsigned long)hwarc->rd_buffer); free_page((unsigned long)hwarc->rd_buffer);
hwarc->rd_buffer = NULL;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment