linux/drivers/usb/usbip/stub_dev.c

502 lines
12 KiB
C
Raw Normal View History

/*
* Copyright (C) 2003-2008 Takahiro Hirofuchi
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <linux/device.h>
#include <linux/file.h>
#include <linux/kthread.h>
#include <linux/module.h>
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 08:04:11 +00:00
#include "usbip_common.h"
#include "stub.h"
/*
* usbip_status shows the status of usbip-host as long as this driver is bound
* to the target device.
*/
static ssize_t usbip_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct stub_device *sdev = dev_get_drvdata(dev);
int status;
if (!sdev) {
dev_err(dev, "sdev is null\n");
return -ENODEV;
}
spin_lock_irq(&sdev->ud.lock);
status = sdev->ud.status;
spin_unlock_irq(&sdev->ud.lock);
return snprintf(buf, PAGE_SIZE, "%d\n", status);
}
static DEVICE_ATTR_RO(usbip_status);
/*
* usbip_sockfd gets a socket descriptor of an established TCP connection that
* is used to transfer usbip requests by kernel threads. -1 is a magic number
* by which usbip connection is finished.
*/
static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct stub_device *sdev = dev_get_drvdata(dev);
int sockfd = 0;
struct socket *socket;
int rv;
if (!sdev) {
dev_err(dev, "sdev is null\n");
return -ENODEV;
}
rv = sscanf(buf, "%d", &sockfd);
if (rv != 1)
return -EINVAL;
if (sockfd != -1) {
int err;
dev_info(dev, "stub up\n");
spin_lock_irq(&sdev->ud.lock);
if (sdev->ud.status != SDEV_ST_AVAILABLE) {
dev_err(dev, "not ready\n");
goto err;
}
socket = sockfd_lookup(sockfd, &err);
if (!socket)
goto err;
sdev->ud.tcp_socket = socket;
spin_unlock_irq(&sdev->ud.lock);
sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud,
"stub_rx");
sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud,
"stub_tx");
spin_lock_irq(&sdev->ud.lock);
sdev->ud.status = SDEV_ST_USED;
spin_unlock_irq(&sdev->ud.lock);
} else {
dev_info(dev, "stub down\n");
spin_lock_irq(&sdev->ud.lock);
if (sdev->ud.status != SDEV_ST_USED)
goto err;
spin_unlock_irq(&sdev->ud.lock);
usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
}
return count;
err:
spin_unlock_irq(&sdev->ud.lock);
return -EINVAL;
}
static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
static int stub_add_files(struct device *dev)
{
int err = 0;
err = device_create_file(dev, &dev_attr_usbip_status);
if (err)
goto err_status;
err = device_create_file(dev, &dev_attr_usbip_sockfd);
if (err)
goto err_sockfd;
err = device_create_file(dev, &dev_attr_usbip_debug);
if (err)
goto err_debug;
return 0;
err_debug:
device_remove_file(dev, &dev_attr_usbip_sockfd);
err_sockfd:
device_remove_file(dev, &dev_attr_usbip_status);
err_status:
return err;
}
static void stub_remove_files(struct device *dev)
{
device_remove_file(dev, &dev_attr_usbip_status);
device_remove_file(dev, &dev_attr_usbip_sockfd);
device_remove_file(dev, &dev_attr_usbip_debug);
}
static void stub_shutdown_connection(struct usbip_device *ud)
{
struct stub_device *sdev = container_of(ud, struct stub_device, ud);
/*
* When removing an exported device, kernel panic sometimes occurred
* and then EIP was sk_wait_data of stub_rx thread. Is this because
* sk_wait_data returned though stub_rx thread was already finished by
* step 1?
*/
if (ud->tcp_socket) {
dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n",
ud->tcp_socket);
kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
}
/* 1. stop threads */
staging: usbip: stub_dev: Fixed oops during removal of usbip_host stub_shutdown_connection() should set kernel thread pointers to NULL after killing them. so that at the time of usbip_host removal stub_shutdown_connection() doesn't try to kill kernel threads which are already killed. [ 1504.312158] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1504.315833] IP: [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.317688] PGD 41f1c067 PUD 41d0f067 PMD 0 [ 1504.319611] Oops: 0000 [#2] SMP [ 1504.321480] Modules linked in: vhci_hcd(O) usbip_host(O-) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 1504.329666] CPU 1 [ 1504.329687] Pid: 2434, comm: usbip_eh Tainted: G D O 3.6.0-rc31+ #2 LENOVO 20042 /Base Board Product Name [ 1504.333502] RIP: 0010:[<ffffffff8108186f>] [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.335371] RSP: 0018:ffff880041c7fdd0 EFLAGS: 00010282 [ 1504.337226] RAX: 0000000000000000 RBX: ffff880041c2db40 RCX: ffff880041e4ae50 [ 1504.339101] RDX: 0000000000000044 RSI: 0000000000000286 RDI: 0000000000000000 [ 1504.341027] RBP: ffff880041c7fde0 R08: ffff880041c7e000 R09: 0000000000000000 [ 1504.342934] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 1504.344840] R13: 0000000000000000 R14: ffff88004d448000 R15: ffff880041c7fea0 [ 1504.346743] FS: 0000000000000000(0000) GS:ffff880077440000(0000) knlGS:0000000000000000 [ 1504.348671] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 1504.350612] CR2: 0000000000000000 CR3: 0000000041d0d000 CR4: 00000000000007e0 [ 1504.352723] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1504.354734] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 1504.356737] Process usbip_eh (pid: 2434, threadinfo ffff880041c7e000, task ffff88004d448000) [ 1504.358711] Stack: [ 1504.360635] ffff880041c7fde0 ffff880041c2db40 ffff880041c7fe00 ffffffff81052aaa [ 1504.362589] ffff880041c2db40 0000000000000000 ffff880041c7fe30 ffffffff8107a148 [ 1504.364539] ffff880041e4ae10 ffff880041e4ae00 ffff88004d448000 ffff88004d448000 [ 1504.366470] Call Trace: [ 1504.368368] [<ffffffff81052aaa>] __put_task_struct+0x4a/0x140 [ 1504.370307] [<ffffffff8107a148>] kthread_stop+0x108/0x110 [ 1504.370312] [<ffffffffa040da4e>] stub_shutdown_connection+0x3e/0x1b0 [usbip_host] [ 1504.370315] [<ffffffffa03fd920>] event_handler_loop+0x70/0x140 [usbip_core] [ 1504.370318] [<ffffffff8107ad30>] ? add_wait_queue+0x60/0x60 [ 1504.370320] [<ffffffffa03fd8b0>] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 1504.370322] [<ffffffff8107a453>] kthread+0x93/0xa0 [ 1504.370327] [<ffffffff81670e84>] kernel_thread_helper+0x4/0x10 [ 1504.370330] [<ffffffff8107a3c0>] ? flush_kthread_worker+0xb0/0xb0 [ 1504.370332] [<ffffffff81670e80>] ? gs_change+0x13/0x13 [ 1504.370351] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 1504.370353] RIP [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.370353] RSP <ffff880041c7fdd0> [ 1504.370354] CR2: 0000000000000000 [ 1504.401376] ---[ end trace 1971ce612a16727a ]--- Signed-off-by: navin patidar <navinp@cdac.in> Acked-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-19 11:37:27 +00:00
if (ud->tcp_rx) {
kthread_stop_put(ud->tcp_rx);
staging: usbip: stub_dev: Fixed oops during removal of usbip_host stub_shutdown_connection() should set kernel thread pointers to NULL after killing them. so that at the time of usbip_host removal stub_shutdown_connection() doesn't try to kill kernel threads which are already killed. [ 1504.312158] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1504.315833] IP: [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.317688] PGD 41f1c067 PUD 41d0f067 PMD 0 [ 1504.319611] Oops: 0000 [#2] SMP [ 1504.321480] Modules linked in: vhci_hcd(O) usbip_host(O-) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 1504.329666] CPU 1 [ 1504.329687] Pid: 2434, comm: usbip_eh Tainted: G D O 3.6.0-rc31+ #2 LENOVO 20042 /Base Board Product Name [ 1504.333502] RIP: 0010:[<ffffffff8108186f>] [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.335371] RSP: 0018:ffff880041c7fdd0 EFLAGS: 00010282 [ 1504.337226] RAX: 0000000000000000 RBX: ffff880041c2db40 RCX: ffff880041e4ae50 [ 1504.339101] RDX: 0000000000000044 RSI: 0000000000000286 RDI: 0000000000000000 [ 1504.341027] RBP: ffff880041c7fde0 R08: ffff880041c7e000 R09: 0000000000000000 [ 1504.342934] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 1504.344840] R13: 0000000000000000 R14: ffff88004d448000 R15: ffff880041c7fea0 [ 1504.346743] FS: 0000000000000000(0000) GS:ffff880077440000(0000) knlGS:0000000000000000 [ 1504.348671] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 1504.350612] CR2: 0000000000000000 CR3: 0000000041d0d000 CR4: 00000000000007e0 [ 1504.352723] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1504.354734] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 1504.356737] Process usbip_eh (pid: 2434, threadinfo ffff880041c7e000, task ffff88004d448000) [ 1504.358711] Stack: [ 1504.360635] ffff880041c7fde0 ffff880041c2db40 ffff880041c7fe00 ffffffff81052aaa [ 1504.362589] ffff880041c2db40 0000000000000000 ffff880041c7fe30 ffffffff8107a148 [ 1504.364539] ffff880041e4ae10 ffff880041e4ae00 ffff88004d448000 ffff88004d448000 [ 1504.366470] Call Trace: [ 1504.368368] [<ffffffff81052aaa>] __put_task_struct+0x4a/0x140 [ 1504.370307] [<ffffffff8107a148>] kthread_stop+0x108/0x110 [ 1504.370312] [<ffffffffa040da4e>] stub_shutdown_connection+0x3e/0x1b0 [usbip_host] [ 1504.370315] [<ffffffffa03fd920>] event_handler_loop+0x70/0x140 [usbip_core] [ 1504.370318] [<ffffffff8107ad30>] ? add_wait_queue+0x60/0x60 [ 1504.370320] [<ffffffffa03fd8b0>] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 1504.370322] [<ffffffff8107a453>] kthread+0x93/0xa0 [ 1504.370327] [<ffffffff81670e84>] kernel_thread_helper+0x4/0x10 [ 1504.370330] [<ffffffff8107a3c0>] ? flush_kthread_worker+0xb0/0xb0 [ 1504.370332] [<ffffffff81670e80>] ? gs_change+0x13/0x13 [ 1504.370351] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 1504.370353] RIP [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.370353] RSP <ffff880041c7fdd0> [ 1504.370354] CR2: 0000000000000000 [ 1504.401376] ---[ end trace 1971ce612a16727a ]--- Signed-off-by: navin patidar <navinp@cdac.in> Acked-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-19 11:37:27 +00:00
ud->tcp_rx = NULL;
}
if (ud->tcp_tx) {
kthread_stop_put(ud->tcp_tx);
staging: usbip: stub_dev: Fixed oops during removal of usbip_host stub_shutdown_connection() should set kernel thread pointers to NULL after killing them. so that at the time of usbip_host removal stub_shutdown_connection() doesn't try to kill kernel threads which are already killed. [ 1504.312158] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1504.315833] IP: [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.317688] PGD 41f1c067 PUD 41d0f067 PMD 0 [ 1504.319611] Oops: 0000 [#2] SMP [ 1504.321480] Modules linked in: vhci_hcd(O) usbip_host(O-) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 1504.329666] CPU 1 [ 1504.329687] Pid: 2434, comm: usbip_eh Tainted: G D O 3.6.0-rc31+ #2 LENOVO 20042 /Base Board Product Name [ 1504.333502] RIP: 0010:[<ffffffff8108186f>] [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.335371] RSP: 0018:ffff880041c7fdd0 EFLAGS: 00010282 [ 1504.337226] RAX: 0000000000000000 RBX: ffff880041c2db40 RCX: ffff880041e4ae50 [ 1504.339101] RDX: 0000000000000044 RSI: 0000000000000286 RDI: 0000000000000000 [ 1504.341027] RBP: ffff880041c7fde0 R08: ffff880041c7e000 R09: 0000000000000000 [ 1504.342934] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 1504.344840] R13: 0000000000000000 R14: ffff88004d448000 R15: ffff880041c7fea0 [ 1504.346743] FS: 0000000000000000(0000) GS:ffff880077440000(0000) knlGS:0000000000000000 [ 1504.348671] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 1504.350612] CR2: 0000000000000000 CR3: 0000000041d0d000 CR4: 00000000000007e0 [ 1504.352723] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1504.354734] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 1504.356737] Process usbip_eh (pid: 2434, threadinfo ffff880041c7e000, task ffff88004d448000) [ 1504.358711] Stack: [ 1504.360635] ffff880041c7fde0 ffff880041c2db40 ffff880041c7fe00 ffffffff81052aaa [ 1504.362589] ffff880041c2db40 0000000000000000 ffff880041c7fe30 ffffffff8107a148 [ 1504.364539] ffff880041e4ae10 ffff880041e4ae00 ffff88004d448000 ffff88004d448000 [ 1504.366470] Call Trace: [ 1504.368368] [<ffffffff81052aaa>] __put_task_struct+0x4a/0x140 [ 1504.370307] [<ffffffff8107a148>] kthread_stop+0x108/0x110 [ 1504.370312] [<ffffffffa040da4e>] stub_shutdown_connection+0x3e/0x1b0 [usbip_host] [ 1504.370315] [<ffffffffa03fd920>] event_handler_loop+0x70/0x140 [usbip_core] [ 1504.370318] [<ffffffff8107ad30>] ? add_wait_queue+0x60/0x60 [ 1504.370320] [<ffffffffa03fd8b0>] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 1504.370322] [<ffffffff8107a453>] kthread+0x93/0xa0 [ 1504.370327] [<ffffffff81670e84>] kernel_thread_helper+0x4/0x10 [ 1504.370330] [<ffffffff8107a3c0>] ? flush_kthread_worker+0xb0/0xb0 [ 1504.370332] [<ffffffff81670e80>] ? gs_change+0x13/0x13 [ 1504.370351] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 1504.370353] RIP [<ffffffff8108186f>] exit_creds+0x1f/0x70 [ 1504.370353] RSP <ffff880041c7fdd0> [ 1504.370354] CR2: 0000000000000000 [ 1504.401376] ---[ end trace 1971ce612a16727a ]--- Signed-off-by: navin patidar <navinp@cdac.in> Acked-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-19 11:37:27 +00:00
ud->tcp_tx = NULL;
}
/*
* 2. close the socket
*
* tcp_socket is freed after threads are killed so that usbip_xmit does
* not touch NULL socket.
*/
if (ud->tcp_socket) {
sockfd_put(ud->tcp_socket);
ud->tcp_socket = NULL;
}
/* 3. free used data */
stub_device_cleanup_urbs(sdev);
/* 4. free stub_unlink */
{
unsigned long flags;
struct stub_unlink *unlink, *tmp;
spin_lock_irqsave(&sdev->priv_lock, flags);
list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
list_del(&unlink->list);
kfree(unlink);
}
list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free,
list) {
list_del(&unlink->list);
kfree(unlink);
}
spin_unlock_irqrestore(&sdev->priv_lock, flags);
}
}
static void stub_device_reset(struct usbip_device *ud)
{
struct stub_device *sdev = container_of(ud, struct stub_device, ud);
staging: usbip: stub: update refcounts for devices and interfaces The stub driver expects to access the usb interface and usb device structures even if the device has been disconnected in the meantime. This change gets a reference to them in the stub probe function using usb_get_intf()/usb_get_dev() and drops them in the disconnect function. This fixes an oops observed with a Logic Controls Line display (0fa8:a030) which disconnects itself when it is reset: [ 1348.562274] BUG: unable to handle kernel paging request at 5f7433e5 [ 1348.562327] IP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 [ 1348.562374] *pde = 00000000 [ 1348.562397] Oops: 0000 [#1] [ 1348.562418] last sysfs file: /sys/devices/pci0000:00/0000:00:10.2/usb4/4-1/bConfigurationValue [ 1348.562454] Modules linked in: usbip vhci_hcd usbip_common_mod fbcon tileblit font bitblit softcursor serio_raw uvesafb pcspkr via_rng snd_via82xx gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_oss snd_seq_midi_event snd_seq snd_timer snd_seq_device snd usbhid hid via_rhine soundcore mii igel_flash aufs pata_via [ 1348.562649] [ 1348.562670] Pid: 2855, comm: usbip_eh Not tainted (2.6.32 #23.37-ud-r113) M300C [ 1348.562704] EIP: 0060:[<c0393b02>] EFLAGS: 00010216 CPU: 0 [ 1348.562734] EIP is at usb_lock_device_for_reset+0x22/0xd0 [ 1348.562762] EAX: 5f7433cd EBX: 5f7433cd ECX: de293a5c EDX: dd326a00 [ 1348.562793] ESI: 5f7433cd EDI: 000400f6 EBP: cf43ff48 ESP: cf43ff38 [ 1348.562824] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 1348.562854] Process usbip_eh (pid: 2855, ti=cf43e000 task=d2c7f230 task.ti=cf43e000) [ 1348.562884] Stack: [ 1348.562900] d6ec9960 de2939cc 5f7433cd 5f743431 cf43ff70 df8fd32f de2939cc d2c7f230 [ 1348.562940] <0> cf43ff70 00000282 00000282 de2939cc d2c7f230 d2c7f230 cf43ffa8 df84416d [ 1348.562987] <0> cf43ff88 d2c7f230 de293a24 d2c7f230 00000000 d2c7f230 c014e760 cf43ff94 [ 1348.563042] Call Trace: [ 1348.563073] [<df8fd32f>] ? stub_device_reset+0x3f/0x110 [usbip] [ 1348.563114] [<df84416d>] ? event_handler_loop+0xcd/0xe8 [usbip_common_mod] [ 1348.563156] [<c014e760>] ? autoremove_wake_function+0x0/0x50 [ 1348.563193] [<df843d80>] ? usbip_thread+0x0/0x60 [usbip_common_mod] [ 1348.563230] [<df843dd1>] ? usbip_thread+0x51/0x60 [usbip_common_mod] [ 1348.563265] [<c014e374>] ? kthread+0x74/0x80 [ 1348.563294] [<c014e300>] ? kthread+0x0/0x80 [ 1348.563326] [<c0103c47>] ? kernel_thread_helper+0x7/0x10 [ 1348.563351] Code: 00 e8 73 4d 00 00 5d c3 90 55 89 e5 83 ec 10 89 5d f4 89 75 f8 89 7d fc 0f 1f 44 00 00 8b 3d c0 2e 67 c0 81 c7 fa 00 00 00 89 c3 <8b> 40 18 89 d6 85 c0 75 15 b8 ed ff ff ff 8b 5d f4 8b 75 f8 8b [ 1348.563528] EIP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 SS:ESP 0068:cf43ff38 [ 1348.563570] CR2: 000000005f7433e5 [ 1348.563593] ---[ end trace 9c3f1e3a2e5299d9 ]--- Signed-off-by: Max Vozeler <max@vozeler.com> Tested-by: Mark Wehby <MWehby@luxotticaRetail.com> Tested-by: Steven Harms <sharms@luxotticaRetail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-01-12 13:01:59 +00:00
struct usb_device *udev = sdev->udev;
int ret;
dev_dbg(&udev->dev, "device reset");
staging: usbip: stub: update refcounts for devices and interfaces The stub driver expects to access the usb interface and usb device structures even if the device has been disconnected in the meantime. This change gets a reference to them in the stub probe function using usb_get_intf()/usb_get_dev() and drops them in the disconnect function. This fixes an oops observed with a Logic Controls Line display (0fa8:a030) which disconnects itself when it is reset: [ 1348.562274] BUG: unable to handle kernel paging request at 5f7433e5 [ 1348.562327] IP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 [ 1348.562374] *pde = 00000000 [ 1348.562397] Oops: 0000 [#1] [ 1348.562418] last sysfs file: /sys/devices/pci0000:00/0000:00:10.2/usb4/4-1/bConfigurationValue [ 1348.562454] Modules linked in: usbip vhci_hcd usbip_common_mod fbcon tileblit font bitblit softcursor serio_raw uvesafb pcspkr via_rng snd_via82xx gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_oss snd_seq_midi_event snd_seq snd_timer snd_seq_device snd usbhid hid via_rhine soundcore mii igel_flash aufs pata_via [ 1348.562649] [ 1348.562670] Pid: 2855, comm: usbip_eh Not tainted (2.6.32 #23.37-ud-r113) M300C [ 1348.562704] EIP: 0060:[<c0393b02>] EFLAGS: 00010216 CPU: 0 [ 1348.562734] EIP is at usb_lock_device_for_reset+0x22/0xd0 [ 1348.562762] EAX: 5f7433cd EBX: 5f7433cd ECX: de293a5c EDX: dd326a00 [ 1348.562793] ESI: 5f7433cd EDI: 000400f6 EBP: cf43ff48 ESP: cf43ff38 [ 1348.562824] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 1348.562854] Process usbip_eh (pid: 2855, ti=cf43e000 task=d2c7f230 task.ti=cf43e000) [ 1348.562884] Stack: [ 1348.562900] d6ec9960 de2939cc 5f7433cd 5f743431 cf43ff70 df8fd32f de2939cc d2c7f230 [ 1348.562940] <0> cf43ff70 00000282 00000282 de2939cc d2c7f230 d2c7f230 cf43ffa8 df84416d [ 1348.562987] <0> cf43ff88 d2c7f230 de293a24 d2c7f230 00000000 d2c7f230 c014e760 cf43ff94 [ 1348.563042] Call Trace: [ 1348.563073] [<df8fd32f>] ? stub_device_reset+0x3f/0x110 [usbip] [ 1348.563114] [<df84416d>] ? event_handler_loop+0xcd/0xe8 [usbip_common_mod] [ 1348.563156] [<c014e760>] ? autoremove_wake_function+0x0/0x50 [ 1348.563193] [<df843d80>] ? usbip_thread+0x0/0x60 [usbip_common_mod] [ 1348.563230] [<df843dd1>] ? usbip_thread+0x51/0x60 [usbip_common_mod] [ 1348.563265] [<c014e374>] ? kthread+0x74/0x80 [ 1348.563294] [<c014e300>] ? kthread+0x0/0x80 [ 1348.563326] [<c0103c47>] ? kernel_thread_helper+0x7/0x10 [ 1348.563351] Code: 00 e8 73 4d 00 00 5d c3 90 55 89 e5 83 ec 10 89 5d f4 89 75 f8 89 7d fc 0f 1f 44 00 00 8b 3d c0 2e 67 c0 81 c7 fa 00 00 00 89 c3 <8b> 40 18 89 d6 85 c0 75 15 b8 ed ff ff ff 8b 5d f4 8b 75 f8 8b [ 1348.563528] EIP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 SS:ESP 0068:cf43ff38 [ 1348.563570] CR2: 000000005f7433e5 [ 1348.563593] ---[ end trace 9c3f1e3a2e5299d9 ]--- Signed-off-by: Max Vozeler <max@vozeler.com> Tested-by: Mark Wehby <MWehby@luxotticaRetail.com> Tested-by: Steven Harms <sharms@luxotticaRetail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-01-12 13:01:59 +00:00
ret = usb_lock_device_for_reset(udev, NULL);
if (ret < 0) {
dev_err(&udev->dev, "lock for reset\n");
spin_lock_irq(&ud->lock);
ud->status = SDEV_ST_ERROR;
spin_unlock_irq(&ud->lock);
return;
}
/* try to reset the device */
ret = usb_reset_device(udev);
usb_unlock_device(udev);
spin_lock_irq(&ud->lock);
if (ret) {
dev_err(&udev->dev, "device reset\n");
ud->status = SDEV_ST_ERROR;
} else {
dev_info(&udev->dev, "device reset\n");
ud->status = SDEV_ST_AVAILABLE;
}
spin_unlock_irq(&ud->lock);
}
static void stub_device_unusable(struct usbip_device *ud)
{
spin_lock_irq(&ud->lock);
ud->status = SDEV_ST_ERROR;
spin_unlock_irq(&ud->lock);
}
/**
* stub_device_alloc - allocate a new stub_device struct
* @udev: usb_device of a new device
*
* Allocates and initializes a new stub_device struct.
*/
static struct stub_device *stub_device_alloc(struct usb_device *udev)
{
struct stub_device *sdev;
int busnum = udev->bus->busnum;
int devnum = udev->devnum;
dev_dbg(&udev->dev, "allocating stub device");
/* yes, it's a new device */
sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL);
if (!sdev)
return NULL;
staging: usbip: stub: update refcounts for devices and interfaces The stub driver expects to access the usb interface and usb device structures even if the device has been disconnected in the meantime. This change gets a reference to them in the stub probe function using usb_get_intf()/usb_get_dev() and drops them in the disconnect function. This fixes an oops observed with a Logic Controls Line display (0fa8:a030) which disconnects itself when it is reset: [ 1348.562274] BUG: unable to handle kernel paging request at 5f7433e5 [ 1348.562327] IP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 [ 1348.562374] *pde = 00000000 [ 1348.562397] Oops: 0000 [#1] [ 1348.562418] last sysfs file: /sys/devices/pci0000:00/0000:00:10.2/usb4/4-1/bConfigurationValue [ 1348.562454] Modules linked in: usbip vhci_hcd usbip_common_mod fbcon tileblit font bitblit softcursor serio_raw uvesafb pcspkr via_rng snd_via82xx gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_oss snd_seq_midi_event snd_seq snd_timer snd_seq_device snd usbhid hid via_rhine soundcore mii igel_flash aufs pata_via [ 1348.562649] [ 1348.562670] Pid: 2855, comm: usbip_eh Not tainted (2.6.32 #23.37-ud-r113) M300C [ 1348.562704] EIP: 0060:[<c0393b02>] EFLAGS: 00010216 CPU: 0 [ 1348.562734] EIP is at usb_lock_device_for_reset+0x22/0xd0 [ 1348.562762] EAX: 5f7433cd EBX: 5f7433cd ECX: de293a5c EDX: dd326a00 [ 1348.562793] ESI: 5f7433cd EDI: 000400f6 EBP: cf43ff48 ESP: cf43ff38 [ 1348.562824] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 1348.562854] Process usbip_eh (pid: 2855, ti=cf43e000 task=d2c7f230 task.ti=cf43e000) [ 1348.562884] Stack: [ 1348.562900] d6ec9960 de2939cc 5f7433cd 5f743431 cf43ff70 df8fd32f de2939cc d2c7f230 [ 1348.562940] <0> cf43ff70 00000282 00000282 de2939cc d2c7f230 d2c7f230 cf43ffa8 df84416d [ 1348.562987] <0> cf43ff88 d2c7f230 de293a24 d2c7f230 00000000 d2c7f230 c014e760 cf43ff94 [ 1348.563042] Call Trace: [ 1348.563073] [<df8fd32f>] ? stub_device_reset+0x3f/0x110 [usbip] [ 1348.563114] [<df84416d>] ? event_handler_loop+0xcd/0xe8 [usbip_common_mod] [ 1348.563156] [<c014e760>] ? autoremove_wake_function+0x0/0x50 [ 1348.563193] [<df843d80>] ? usbip_thread+0x0/0x60 [usbip_common_mod] [ 1348.563230] [<df843dd1>] ? usbip_thread+0x51/0x60 [usbip_common_mod] [ 1348.563265] [<c014e374>] ? kthread+0x74/0x80 [ 1348.563294] [<c014e300>] ? kthread+0x0/0x80 [ 1348.563326] [<c0103c47>] ? kernel_thread_helper+0x7/0x10 [ 1348.563351] Code: 00 e8 73 4d 00 00 5d c3 90 55 89 e5 83 ec 10 89 5d f4 89 75 f8 89 7d fc 0f 1f 44 00 00 8b 3d c0 2e 67 c0 81 c7 fa 00 00 00 89 c3 <8b> 40 18 89 d6 85 c0 75 15 b8 ed ff ff ff 8b 5d f4 8b 75 f8 8b [ 1348.563528] EIP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 SS:ESP 0068:cf43ff38 [ 1348.563570] CR2: 000000005f7433e5 [ 1348.563593] ---[ end trace 9c3f1e3a2e5299d9 ]--- Signed-off-by: Max Vozeler <max@vozeler.com> Tested-by: Mark Wehby <MWehby@luxotticaRetail.com> Tested-by: Steven Harms <sharms@luxotticaRetail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-01-12 13:01:59 +00:00
sdev->udev = usb_get_dev(udev);
/*
* devid is defined with devnum when this driver is first allocated.
* devnum may change later if a device is reset. However, devid never
* changes during a usbip connection.
*/
sdev->devid = (busnum << 16) | devnum;
sdev->ud.side = USBIP_STUB;
sdev->ud.status = SDEV_ST_AVAILABLE;
spin_lock_init(&sdev->ud.lock);
sdev->ud.tcp_socket = NULL;
INIT_LIST_HEAD(&sdev->priv_init);
INIT_LIST_HEAD(&sdev->priv_tx);
INIT_LIST_HEAD(&sdev->priv_free);
INIT_LIST_HEAD(&sdev->unlink_free);
INIT_LIST_HEAD(&sdev->unlink_tx);
spin_lock_init(&sdev->priv_lock);
init_waitqueue_head(&sdev->tx_waitq);
sdev->ud.eh_ops.shutdown = stub_shutdown_connection;
sdev->ud.eh_ops.reset = stub_device_reset;
sdev->ud.eh_ops.unusable = stub_device_unusable;
usbip_start_eh(&sdev->ud);
dev_dbg(&udev->dev, "register new device\n");
return sdev;
}
static void stub_device_free(struct stub_device *sdev)
{
kfree(sdev);
}
static int stub_probe(struct usb_device *udev)
{
struct stub_device *sdev = NULL;
const char *udev_busid = dev_name(&udev->dev);
struct bus_id_priv *busid_priv;
int rc;
dev_dbg(&udev->dev, "Enter\n");
/* check we should claim or not by busid_table */
busid_priv = get_busid_priv(udev_busid);
if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
(busid_priv->status == STUB_BUSID_OTHER)) {
dev_info(&udev->dev,
"%s is not in match_busid table... skip!\n",
udev_busid);
/*
* Return value should be ENODEV or ENOXIO to continue trying
* other matched drivers by the driver core.
* See driver_probe_device() in driver/base/dd.c
*/
return -ENODEV;
}
if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
udev_busid);
return -ENODEV;
}
if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
dev_dbg(&udev->dev,
"%s is attached on vhci_hcd... skip!\n",
udev_busid);
return -ENODEV;
}
/* ok, this is my device */
sdev = stub_device_alloc(udev);
if (!sdev)
return -ENOMEM;
dev_info(&udev->dev,
"usbip-host: register new device (bus %u dev %u)\n",
udev->bus->busnum, udev->devnum);
busid_priv->shutdown_busid = 0;
/* set private data to usb_device */
dev_set_drvdata(&udev->dev, sdev);
busid_priv->sdev = sdev;
busid_priv->udev = udev;
/*
* Claim this hub port.
* It doesn't matter what value we pass as owner
* (struct dev_state) as long as it is unique.
*/
rc = usb_hub_claim_port(udev->parent, udev->portnum,
(struct usb_dev_state *) udev);
if (rc) {
dev_dbg(&udev->dev, "unable to claim port\n");
goto err_port;
}
rc = stub_add_files(&udev->dev);
if (rc) {
dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
goto err_files;
}
busid_priv->status = STUB_BUSID_ALLOC;
return 0;
err_files:
usb_hub_release_port(udev->parent, udev->portnum,
(struct usb_dev_state *) udev);
err_port:
dev_set_drvdata(&udev->dev, NULL);
usb_put_dev(udev);
busid_priv->sdev = NULL;
stub_device_free(sdev);
return rc;
}
static void shutdown_busid(struct bus_id_priv *busid_priv)
{
if (busid_priv->sdev && !busid_priv->shutdown_busid) {
busid_priv->shutdown_busid = 1;
usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
/* wait for the stop of the event handler */
usbip_stop_eh(&busid_priv->sdev->ud);
}
}
/*
* called in usb_disconnect() or usb_deregister()
* but only if actconfig(active configuration) exists
*/
static void stub_disconnect(struct usb_device *udev)
{
struct stub_device *sdev;
const char *udev_busid = dev_name(&udev->dev);
struct bus_id_priv *busid_priv;
int rc;
dev_dbg(&udev->dev, "Enter\n");
busid_priv = get_busid_priv(udev_busid);
if (!busid_priv) {
BUG();
return;
}
sdev = dev_get_drvdata(&udev->dev);
/* get stub_device */
if (!sdev) {
dev_err(&udev->dev, "could not get device");
return;
}
dev_set_drvdata(&udev->dev, NULL);
/*
* NOTE: rx/tx threads are invoked for each usb_device.
*/
stub_remove_files(&udev->dev);
/* release port */
rc = usb_hub_release_port(udev->parent, udev->portnum,
(struct usb_dev_state *) udev);
if (rc) {
dev_dbg(&udev->dev, "unable to release port\n");
return;
}
/* If usb reset is called from event handler */
usbip: event handler as one thread Dear all, 1. Overview In current USB/IP implementation, event kernel threads are created for each port. The functions of the threads are closing connection and error handling so they don't have not so many events to handle. There's no need to have thread for each port. BEFORE) vhci side - VHCI_NPORTS(8) threads are created. $ ps aux | grep usbip root 10059 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10060 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10061 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10062 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10063 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10064 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10065 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] root 10066 0.0 0.0 0 0 ? S 17:06 0:00 [usbip_eh] BEFORE) stub side - threads will be created every bind operation. $ ps aux | grep usbip root 8368 0.0 0.0 0 0 ? S 17:56 0:00 [usbip_eh] root 8399 0.0 0.0 0 0 ? S 17:56 0:00 [usbip_eh] This patch put event threads of stub and vhci driver as one workqueue. AFTER) only one event threads in each vhci and stub side. $ ps aux | grep usbip root 10457 0.0 0.0 0 0 ? S< 17:47 0:00 [usbip_event] 2. Modification to usbip_event.c BEFORE) kernel threads are created in usbip_start_eh(). AFTER) one workqueue is created in new usbip_init_eh(). Event handler which was main loop of kernel thread is modified to workqueue handler. Events themselves are stored in struct usbip_device - same as before. usbip_devices which have event are listed in event_list. The handler picks an element from the list and wakeup usbip_device. The wakeup method is same as before. usbip_in_eh() substitutes statement which checks whether functions are called from eh_ops or not. In this function, the worker context is used for the checking. The context will be set in a variable in the beginning of first event handling. usbip_in_eh() is used in event handler so it works well. 3. Modifications to programs using usbip_event.c Initialization and termination of workqueue are added to init and exit routine of usbip_core respectively. A. version info v2) # Merged 1/2 event handler itself and 2/2 user programs because of auto build fail at 1/2 casued unmodified user programs in 1/2. Signed-off-by: Nobuo Iwata <nobuo.iwata@fujixerox.co.jp> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-03-24 01:50:59 +00:00
if (usbip_in_eh(current))
return;
/* shutdown the current connection */
shutdown_busid(busid_priv);
staging: usbip: stub: update refcounts for devices and interfaces The stub driver expects to access the usb interface and usb device structures even if the device has been disconnected in the meantime. This change gets a reference to them in the stub probe function using usb_get_intf()/usb_get_dev() and drops them in the disconnect function. This fixes an oops observed with a Logic Controls Line display (0fa8:a030) which disconnects itself when it is reset: [ 1348.562274] BUG: unable to handle kernel paging request at 5f7433e5 [ 1348.562327] IP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 [ 1348.562374] *pde = 00000000 [ 1348.562397] Oops: 0000 [#1] [ 1348.562418] last sysfs file: /sys/devices/pci0000:00/0000:00:10.2/usb4/4-1/bConfigurationValue [ 1348.562454] Modules linked in: usbip vhci_hcd usbip_common_mod fbcon tileblit font bitblit softcursor serio_raw uvesafb pcspkr via_rng snd_via82xx gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_oss snd_seq_midi_event snd_seq snd_timer snd_seq_device snd usbhid hid via_rhine soundcore mii igel_flash aufs pata_via [ 1348.562649] [ 1348.562670] Pid: 2855, comm: usbip_eh Not tainted (2.6.32 #23.37-ud-r113) M300C [ 1348.562704] EIP: 0060:[<c0393b02>] EFLAGS: 00010216 CPU: 0 [ 1348.562734] EIP is at usb_lock_device_for_reset+0x22/0xd0 [ 1348.562762] EAX: 5f7433cd EBX: 5f7433cd ECX: de293a5c EDX: dd326a00 [ 1348.562793] ESI: 5f7433cd EDI: 000400f6 EBP: cf43ff48 ESP: cf43ff38 [ 1348.562824] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 1348.562854] Process usbip_eh (pid: 2855, ti=cf43e000 task=d2c7f230 task.ti=cf43e000) [ 1348.562884] Stack: [ 1348.562900] d6ec9960 de2939cc 5f7433cd 5f743431 cf43ff70 df8fd32f de2939cc d2c7f230 [ 1348.562940] <0> cf43ff70 00000282 00000282 de2939cc d2c7f230 d2c7f230 cf43ffa8 df84416d [ 1348.562987] <0> cf43ff88 d2c7f230 de293a24 d2c7f230 00000000 d2c7f230 c014e760 cf43ff94 [ 1348.563042] Call Trace: [ 1348.563073] [<df8fd32f>] ? stub_device_reset+0x3f/0x110 [usbip] [ 1348.563114] [<df84416d>] ? event_handler_loop+0xcd/0xe8 [usbip_common_mod] [ 1348.563156] [<c014e760>] ? autoremove_wake_function+0x0/0x50 [ 1348.563193] [<df843d80>] ? usbip_thread+0x0/0x60 [usbip_common_mod] [ 1348.563230] [<df843dd1>] ? usbip_thread+0x51/0x60 [usbip_common_mod] [ 1348.563265] [<c014e374>] ? kthread+0x74/0x80 [ 1348.563294] [<c014e300>] ? kthread+0x0/0x80 [ 1348.563326] [<c0103c47>] ? kernel_thread_helper+0x7/0x10 [ 1348.563351] Code: 00 e8 73 4d 00 00 5d c3 90 55 89 e5 83 ec 10 89 5d f4 89 75 f8 89 7d fc 0f 1f 44 00 00 8b 3d c0 2e 67 c0 81 c7 fa 00 00 00 89 c3 <8b> 40 18 89 d6 85 c0 75 15 b8 ed ff ff ff 8b 5d f4 8b 75 f8 8b [ 1348.563528] EIP: [<c0393b02>] usb_lock_device_for_reset+0x22/0xd0 SS:ESP 0068:cf43ff38 [ 1348.563570] CR2: 000000005f7433e5 [ 1348.563593] ---[ end trace 9c3f1e3a2e5299d9 ]--- Signed-off-by: Max Vozeler <max@vozeler.com> Tested-by: Mark Wehby <MWehby@luxotticaRetail.com> Tested-by: Steven Harms <sharms@luxotticaRetail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-01-12 13:01:59 +00:00
usb_put_dev(sdev->udev);
/* free sdev */
busid_priv->sdev = NULL;
stub_device_free(sdev);
if (busid_priv->status == STUB_BUSID_ALLOC) {
busid_priv->status = STUB_BUSID_ADDED;
} else {
busid_priv->status = STUB_BUSID_OTHER;
del_match_busid((char *)udev_busid);
}
}
#ifdef CONFIG_PM
/* These functions need usb_port_suspend and usb_port_resume,
* which reside in drivers/usb/core/usb.h. Skip for now. */
static int stub_suspend(struct usb_device *udev, pm_message_t message)
{
dev_dbg(&udev->dev, "stub_suspend\n");
return 0;
}
static int stub_resume(struct usb_device *udev, pm_message_t message)
{
dev_dbg(&udev->dev, "stub_resume\n");
return 0;
}
#endif /* CONFIG_PM */
struct usb_device_driver stub_driver = {
.name = "usbip-host",
.probe = stub_probe,
.disconnect = stub_disconnect,
#ifdef CONFIG_PM
.suspend = stub_suspend,
.resume = stub_resume,
#endif
.supports_autosuspend = 0,
};