aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/usbip
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-03-01 18:13:05 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-02 16:03:59 -0500
commit9720b4bc76a83807c68e00c62bfba575251bb73e (patch)
tree41794e9b5f715bf5ee52d428cadcf70ac773347b /drivers/staging/usbip
parent8c81161615feb8c666c675ec7a660dc9b011683f (diff)
staging/usbip: convert to kthread
usbip has its own infrastructure for managing kernel threads, similar to kthread. By changing it to use the standard functions, we can simplify the code and get rid of one of the last BKL users at the same time. Includes changes suggested by Max Vozeler. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Greg Kroah-Hartman <gregkh@suse.de> Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net> Cc: Max Vozeler <max@vozeler.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/usbip')
-rw-r--r--drivers/staging/usbip/Kconfig2
-rw-r--r--drivers/staging/usbip/stub.h4
-rw-r--r--drivers/staging/usbip/stub_dev.c12
-rw-r--r--drivers/staging/usbip/stub_rx.c13
-rw-r--r--drivers/staging/usbip/stub_tx.c17
-rw-r--r--drivers/staging/usbip/usbip_common.c105
-rw-r--r--drivers/staging/usbip/usbip_common.h20
-rw-r--r--drivers/staging/usbip/usbip_event.c38
-rw-r--r--drivers/staging/usbip/vhci.h4
-rw-r--r--drivers/staging/usbip/vhci_hcd.c10
-rw-r--r--drivers/staging/usbip/vhci_rx.c16
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c9
-rw-r--r--drivers/staging/usbip/vhci_tx.c17
13 files changed, 64 insertions, 203 deletions
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
index b11ec379b5c..2c1d10acb8b 100644
--- a/drivers/staging/usbip/Kconfig
+++ b/drivers/staging/usbip/Kconfig
@@ -1,6 +1,6 @@
1config USB_IP_COMMON 1config USB_IP_COMMON
2 tristate "USB IP support (EXPERIMENTAL)" 2 tristate "USB IP support (EXPERIMENTAL)"
3 depends on USB && NET && EXPERIMENTAL && BKL 3 depends on USB && NET && EXPERIMENTAL
4 default N 4 default N
5 ---help--- 5 ---help---
6 This enables pushing USB packets over IP to allow remote 6 This enables pushing USB packets over IP to allow remote
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h
index d73267961ef..6004fcdbc1a 100644
--- a/drivers/staging/usbip/stub.h
+++ b/drivers/staging/usbip/stub.h
@@ -95,13 +95,13 @@ extern struct kmem_cache *stub_priv_cache;
95 95
96/* stub_tx.c */ 96/* stub_tx.c */
97void stub_complete(struct urb *); 97void stub_complete(struct urb *);
98void stub_tx_loop(struct usbip_task *); 98int stub_tx_loop(void *data);
99 99
100/* stub_dev.c */ 100/* stub_dev.c */
101extern struct usb_driver stub_driver; 101extern struct usb_driver stub_driver;
102 102
103/* stub_rx.c */ 103/* stub_rx.c */
104void stub_rx_loop(struct usbip_task *); 104int stub_rx_loop(void *data);
105void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); 105void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
106 106
107/* stub_main.c */ 107/* stub_main.c */
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index a7ce51cc890..8214c353d9f 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "stub.h" 24#include "stub.h"
@@ -138,7 +139,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
138 139
139 spin_unlock(&sdev->ud.lock); 140 spin_unlock(&sdev->ud.lock);
140 141
141 usbip_start_threads(&sdev->ud); 142 sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx");
143 sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx");
142 144
143 spin_lock(&sdev->ud.lock); 145 spin_lock(&sdev->ud.lock);
144 sdev->ud.status = SDEV_ST_USED; 146 sdev->ud.status = SDEV_ST_USED;
@@ -218,7 +220,8 @@ static void stub_shutdown_connection(struct usbip_device *ud)
218 } 220 }
219 221
220 /* 1. stop threads */ 222 /* 1. stop threads */
221 usbip_stop_threads(ud); 223 kthread_stop(ud->tcp_rx);
224 kthread_stop(ud->tcp_tx);
222 225
223 /* 2. close the socket */ 226 /* 2. close the socket */
224 /* 227 /*
@@ -336,9 +339,6 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev,
336 */ 339 */
337 sdev->devid = (busnum << 16) | devnum; 340 sdev->devid = (busnum << 16) | devnum;
338 341
339 usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop);
340 usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop);
341
342 sdev->ud.side = USBIP_STUB; 342 sdev->ud.side = USBIP_STUB;
343 sdev->ud.status = SDEV_ST_AVAILABLE; 343 sdev->ud.status = SDEV_ST_AVAILABLE;
344 /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */ 344 /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */
@@ -543,7 +543,7 @@ static void stub_disconnect(struct usb_interface *interface)
543 stub_remove_files(&interface->dev); 543 stub_remove_files(&interface->dev);
544 544
545 /*If usb reset called from event handler*/ 545 /*If usb reset called from event handler*/
546 if (busid_priv->sdev->ud.eh.thread == current) { 546 if (busid_priv->sdev->ud.eh == current) {
547 busid_priv->interf_count--; 547 busid_priv->interf_count--;
548 return; 548 return;
549 } 549 }
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index ae6ac82754a..6445f12cb4f 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "stub.h" 24#include "stub.h"
@@ -616,19 +617,15 @@ static void stub_rx_pdu(struct usbip_device *ud)
616 617
617} 618}
618 619
619void stub_rx_loop(struct usbip_task *ut) 620int stub_rx_loop(void *data)
620{ 621{
621 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); 622 struct usbip_device *ud = data;
622
623 while (1) {
624 if (signal_pending(current)) {
625 usbip_dbg_stub_rx("signal caught!\n");
626 break;
627 }
628 623
624 while (!kthread_should_stop()) {
629 if (usbip_event_happened(ud)) 625 if (usbip_event_happened(ud))
630 break; 626 break;
631 627
632 stub_rx_pdu(ud); 628 stub_rx_pdu(ud);
633 } 629 }
630 return 0;
634} 631}
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
index d7136e2c86f..5523f25998e 100644
--- a/drivers/staging/usbip/stub_tx.c
+++ b/drivers/staging/usbip/stub_tx.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "stub.h" 24#include "stub.h"
@@ -333,17 +334,12 @@ static int stub_send_ret_unlink(struct stub_device *sdev)
333 334
334/*-------------------------------------------------------------------------*/ 335/*-------------------------------------------------------------------------*/
335 336
336void stub_tx_loop(struct usbip_task *ut) 337int stub_tx_loop(void *data)
337{ 338{
338 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); 339 struct usbip_device *ud = data;
339 struct stub_device *sdev = container_of(ud, struct stub_device, ud); 340 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
340 341
341 while (1) { 342 while (!kthread_should_stop()) {
342 if (signal_pending(current)) {
343 usbip_dbg_stub_tx("signal catched\n");
344 break;
345 }
346
347 if (usbip_event_happened(ud)) 343 if (usbip_event_happened(ud))
348 break; 344 break;
349 345
@@ -369,6 +365,9 @@ void stub_tx_loop(struct usbip_task *ut)
369 365
370 wait_event_interruptible(sdev->tx_waitq, 366 wait_event_interruptible(sdev->tx_waitq,
371 (!list_empty(&sdev->priv_tx) || 367 (!list_empty(&sdev->priv_tx) ||
372 !list_empty(&sdev->unlink_tx))); 368 !list_empty(&sdev->unlink_tx) ||
369 kthread_should_stop()));
373 } 370 }
371
372 return 0;
374} 373}
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 210ef16bab8..337abc48f71 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/smp_lock.h>
22#include <linux/file.h> 21#include <linux/file.h>
23#include <linux/tcp.h> 22#include <linux/tcp.h>
24#include <linux/in.h> 23#include <linux/in.h>
@@ -349,110 +348,6 @@ void usbip_dump_header(struct usbip_header *pdu)
349} 348}
350EXPORT_SYMBOL_GPL(usbip_dump_header); 349EXPORT_SYMBOL_GPL(usbip_dump_header);
351 350
352
353/*-------------------------------------------------------------------------*/
354/* thread routines */
355
356int usbip_thread(void *param)
357{
358 struct usbip_task *ut = param;
359
360 if (!ut)
361 return -EINVAL;
362
363 lock_kernel();
364 daemonize(ut->name);
365 allow_signal(SIGKILL);
366 ut->thread = current;
367 unlock_kernel();
368
369 /* srv.rb must wait for rx_thread starting */
370 complete(&ut->thread_done);
371
372 /* start of while loop */
373 ut->loop_ops(ut);
374
375 /* end of loop */
376 ut->thread = NULL;
377
378 complete_and_exit(&ut->thread_done, 0);
379}
380
381static void stop_rx_thread(struct usbip_device *ud)
382{
383 if (ud->tcp_rx.thread != NULL) {
384 send_sig(SIGKILL, ud->tcp_rx.thread, 1);
385 wait_for_completion(&ud->tcp_rx.thread_done);
386 usbip_udbg("rx_thread for ud %p has finished\n", ud);
387 }
388}
389
390static void stop_tx_thread(struct usbip_device *ud)
391{
392 if (ud->tcp_tx.thread != NULL) {
393 send_sig(SIGKILL, ud->tcp_tx.thread, 1);
394 wait_for_completion(&ud->tcp_tx.thread_done);
395 usbip_udbg("tx_thread for ud %p has finished\n", ud);
396 }
397}
398
399int usbip_start_threads(struct usbip_device *ud)
400{
401 /*
402 * threads are invoked per one device (per one connection).
403 */
404 struct task_struct *th;
405 int err = 0;
406
407 th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
408 if (IS_ERR(th)) {
409 printk(KERN_WARNING
410 "Unable to start control thread\n");
411 err = PTR_ERR(th);
412 goto ust_exit;
413 }
414
415 th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
416 if (IS_ERR(th)) {
417 printk(KERN_WARNING
418 "Unable to start control thread\n");
419 err = PTR_ERR(th);
420 goto tx_thread_err;
421 }
422
423 /* confirm threads are starting */
424 wait_for_completion(&ud->tcp_rx.thread_done);
425 wait_for_completion(&ud->tcp_tx.thread_done);
426
427 return 0;
428
429tx_thread_err:
430 stop_rx_thread(ud);
431
432ust_exit:
433 return err;
434}
435EXPORT_SYMBOL_GPL(usbip_start_threads);
436
437void usbip_stop_threads(struct usbip_device *ud)
438{
439 /* kill threads related to this sdev, if v.c. exists */
440 stop_rx_thread(ud);
441 stop_tx_thread(ud);
442}
443EXPORT_SYMBOL_GPL(usbip_stop_threads);
444
445void usbip_task_init(struct usbip_task *ut, char *name,
446 void (*loop_ops)(struct usbip_task *))
447{
448 ut->thread = NULL;
449 init_completion(&ut->thread_done);
450 ut->name = name;
451 ut->loop_ops = loop_ops;
452}
453EXPORT_SYMBOL_GPL(usbip_task_init);
454
455
456/*-------------------------------------------------------------------------*/ 351/*-------------------------------------------------------------------------*/
457/* socket routines */ 352/* socket routines */
458 353
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index d280e234e06..9f809c315d9 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -307,13 +307,6 @@ void usbip_dump_header(struct usbip_header *pdu);
307 307
308struct usbip_device; 308struct usbip_device;
309 309
310struct usbip_task {
311 struct task_struct *thread;
312 struct completion thread_done;
313 char *name;
314 void (*loop_ops)(struct usbip_task *);
315};
316
317enum usbip_side { 310enum usbip_side {
318 USBIP_VHCI, 311 USBIP_VHCI,
319 USBIP_STUB, 312 USBIP_STUB,
@@ -346,8 +339,8 @@ struct usbip_device {
346 339
347 struct socket *tcp_socket; 340 struct socket *tcp_socket;
348 341
349 struct usbip_task tcp_rx; 342 struct task_struct *tcp_rx;
350 struct usbip_task tcp_tx; 343 struct task_struct *tcp_tx;
351 344
352 /* event handler */ 345 /* event handler */
353#define USBIP_EH_SHUTDOWN (1 << 0) 346#define USBIP_EH_SHUTDOWN (1 << 0)
@@ -367,7 +360,7 @@ struct usbip_device {
367#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) 360#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
368 361
369 unsigned long event; 362 unsigned long event;
370 struct usbip_task eh; 363 struct task_struct *eh;
371 wait_queue_head_t eh_waitq; 364 wait_queue_head_t eh_waitq;
372 365
373 struct eh_ops { 366 struct eh_ops {
@@ -378,13 +371,6 @@ struct usbip_device {
378}; 371};
379 372
380 373
381void usbip_task_init(struct usbip_task *ut, char *,
382 void (*loop_ops)(struct usbip_task *));
383
384int usbip_start_threads(struct usbip_device *ud);
385void usbip_stop_threads(struct usbip_device *ud);
386int usbip_thread(void *param);
387
388void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, 374void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
389 int pack); 375 int pack);
390 376
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c
index af3832b03e4..f4b287ef71d 100644
--- a/drivers/staging/usbip/usbip_event.c
+++ b/drivers/staging/usbip/usbip_event.c
@@ -62,55 +62,43 @@ static int event_handler(struct usbip_device *ud)
62 return 0; 62 return 0;
63} 63}
64 64
65static void event_handler_loop(struct usbip_task *ut) 65static int event_handler_loop(void *data)
66{ 66{
67 struct usbip_device *ud = container_of(ut, struct usbip_device, eh); 67 struct usbip_device *ud = data;
68 68
69 while (1) { 69 while (!kthread_should_stop()) {
70 if (signal_pending(current)) { 70 wait_event_interruptible(ud->eh_waitq,
71 usbip_dbg_eh("signal catched!\n"); 71 usbip_event_happened(ud) ||
72 break; 72 kthread_should_stop());
73 } 73 usbip_dbg_eh("wakeup\n");
74 74
75 if (event_handler(ud) < 0) 75 if (event_handler(ud) < 0)
76 break; 76 break;
77
78 wait_event_interruptible(ud->eh_waitq,
79 usbip_event_happened(ud));
80 usbip_dbg_eh("wakeup\n");
81 } 77 }
78 return 0;
82} 79}
83 80
84int usbip_start_eh(struct usbip_device *ud) 81int usbip_start_eh(struct usbip_device *ud)
85{ 82{
86 struct usbip_task *eh = &ud->eh;
87 struct task_struct *th;
88
89 init_waitqueue_head(&ud->eh_waitq); 83 init_waitqueue_head(&ud->eh_waitq);
90 ud->event = 0; 84 ud->event = 0;
91 85
92 usbip_task_init(eh, "usbip_eh", event_handler_loop); 86 ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh");
93 87 if (IS_ERR(ud->eh)) {
94 th = kthread_run(usbip_thread, (void *)eh, "usbip");
95 if (IS_ERR(th)) {
96 printk(KERN_WARNING 88 printk(KERN_WARNING
97 "Unable to start control thread\n"); 89 "Unable to start control thread\n");
98 return PTR_ERR(th); 90 return PTR_ERR(ud->eh);
99 } 91 }
100
101 wait_for_completion(&eh->thread_done);
102 return 0; 92 return 0;
103} 93}
104EXPORT_SYMBOL_GPL(usbip_start_eh); 94EXPORT_SYMBOL_GPL(usbip_start_eh);
105 95
106void usbip_stop_eh(struct usbip_device *ud) 96void usbip_stop_eh(struct usbip_device *ud)
107{ 97{
108 struct usbip_task *eh = &ud->eh; 98 if (ud->eh == current)
109
110 if (eh->thread == current)
111 return; /* do not wait for myself */ 99 return; /* do not wait for myself */
112 100
113 wait_for_completion(&eh->thread_done); 101 kthread_stop(ud->eh);
114 usbip_dbg_eh("usbip_eh has finished\n"); 102 usbip_dbg_eh("usbip_eh has finished\n");
115} 103}
116EXPORT_SYMBOL_GPL(usbip_stop_eh); 104EXPORT_SYMBOL_GPL(usbip_stop_eh);
diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h
index afc3b1a7188..d3f1e5f8a96 100644
--- a/drivers/staging/usbip/vhci.h
+++ b/drivers/staging/usbip/vhci.h
@@ -113,8 +113,8 @@ extern struct attribute_group dev_attr_group;
113/* vhci_hcd.c */ 113/* vhci_hcd.c */
114void rh_port_connect(int rhport, enum usb_device_speed speed); 114void rh_port_connect(int rhport, enum usb_device_speed speed);
115void rh_port_disconnect(int rhport); 115void rh_port_disconnect(int rhport);
116void vhci_rx_loop(struct usbip_task *ut); 116int vhci_rx_loop(void *data);
117void vhci_tx_loop(struct usbip_task *ut); 117int vhci_tx_loop(void *data);
118 118
119struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, 119struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
120 __u32 seqnum); 120 __u32 seqnum);
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index a35fe61268d..36ae9fbd20a 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "vhci.h" 24#include "vhci.h"
@@ -874,7 +875,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
874 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); 875 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
875 } 876 }
876 877
877 usbip_stop_threads(&vdev->ud); 878 /* kill threads related to this sdev, if v.c. exists */
879 kthread_stop(vdev->ud.tcp_rx);
880 kthread_stop(vdev->ud.tcp_tx);
881
878 usbip_uinfo("stop threads\n"); 882 usbip_uinfo("stop threads\n");
879 883
880 /* active connection is closed */ 884 /* active connection is closed */
@@ -945,8 +949,8 @@ static void vhci_device_init(struct vhci_device *vdev)
945{ 949{
946 memset(vdev, 0, sizeof(*vdev)); 950 memset(vdev, 0, sizeof(*vdev));
947 951
948 usbip_task_init(&vdev->ud.tcp_rx, "vhci_rx", vhci_rx_loop); 952 vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
949 usbip_task_init(&vdev->ud.tcp_tx, "vhci_tx", vhci_tx_loop); 953 vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
950 954
951 vdev->ud.side = USBIP_VHCI; 955 vdev->ud.side = USBIP_VHCI;
952 vdev->ud.status = VDEV_ST_NULL; 956 vdev->ud.status = VDEV_ST_NULL;
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index bf699147094..09bf2355934 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "vhci.h" 24#include "vhci.h"
@@ -269,22 +270,17 @@ static void vhci_rx_pdu(struct usbip_device *ud)
269 270
270/*-------------------------------------------------------------------------*/ 271/*-------------------------------------------------------------------------*/
271 272
272void vhci_rx_loop(struct usbip_task *ut) 273int vhci_rx_loop(void *data)
273{ 274{
274 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); 275 struct usbip_device *ud = data;
275
276
277 while (1) {
278 if (signal_pending(current)) {
279 usbip_dbg_vhci_rx("signal catched!\n");
280 break;
281 }
282 276
283 277
278 while (!kthread_should_stop()) {
284 if (usbip_event_happened(ud)) 279 if (usbip_event_happened(ud))
285 break; 280 break;
286 281
287 vhci_rx_pdu(ud); 282 vhci_rx_pdu(ud);
288 } 283 }
289}
290 284
285 return 0;
286}
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index f6e34e03c8e..3f2459f3041 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -220,16 +220,13 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
220 vdev->ud.tcp_socket = socket; 220 vdev->ud.tcp_socket = socket;
221 vdev->ud.status = VDEV_ST_NOTASSIGNED; 221 vdev->ud.status = VDEV_ST_NOTASSIGNED;
222 222
223 wake_up_process(vdev->ud.tcp_rx);
224 wake_up_process(vdev->ud.tcp_tx);
225
223 spin_unlock(&vdev->ud.lock); 226 spin_unlock(&vdev->ud.lock);
224 spin_unlock(&the_controller->lock); 227 spin_unlock(&the_controller->lock);
225 /* end the lock */ 228 /* end the lock */
226 229
227 /*
228 * this function will sleep, so should be out of the lock. but, it's ok
229 * because we already marked vdev as being used. really?
230 */
231 usbip_start_threads(&vdev->ud);
232
233 rh_port_connect(rhport, speed); 230 rh_port_connect(rhport, speed);
234 231
235 return count; 232 return count;
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c
index e1c1f716a1c..d9ab49d6769 100644
--- a/drivers/staging/usbip/vhci_tx.c
+++ b/drivers/staging/usbip/vhci_tx.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/kthread.h>
21 22
22#include "usbip_common.h" 23#include "usbip_common.h"
23#include "vhci.h" 24#include "vhci.h"
@@ -215,17 +216,12 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev)
215 216
216/*-------------------------------------------------------------------------*/ 217/*-------------------------------------------------------------------------*/
217 218
218void vhci_tx_loop(struct usbip_task *ut) 219int vhci_tx_loop(void *data)
219{ 220{
220 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); 221 struct usbip_device *ud = data;
221 struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); 222 struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
222 223
223 while (1) { 224 while (!kthread_should_stop()) {
224 if (signal_pending(current)) {
225 usbip_uinfo("vhci_tx signal catched\n");
226 break;
227 }
228
229 if (vhci_send_cmd_submit(vdev) < 0) 225 if (vhci_send_cmd_submit(vdev) < 0)
230 break; 226 break;
231 227
@@ -234,8 +230,11 @@ void vhci_tx_loop(struct usbip_task *ut)
234 230
235 wait_event_interruptible(vdev->waitq_tx, 231 wait_event_interruptible(vdev->waitq_tx,
236 (!list_empty(&vdev->priv_tx) || 232 (!list_empty(&vdev->priv_tx) ||
237 !list_empty(&vdev->unlink_tx))); 233 !list_empty(&vdev->unlink_tx) ||
234 kthread_should_stop()));
238 235
239 usbip_dbg_vhci_tx("pending urbs ?, now wake up\n"); 236 usbip_dbg_vhci_tx("pending urbs ?, now wake up\n");
240 } 237 }
238
239 return 0;
241} 240}