diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 15:19:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 15:19:35 -0700 |
commit | 6445ced8670f37cfc2c5e24a9de9b413dbfc788d (patch) | |
tree | 7c98481159008a4080cda929ea8c7bc7598a2c39 /drivers/staging/usbip | |
parent | e6bee325e49f17c65c1fd66e9e8b348c85788341 (diff) | |
parent | 12bb12fac06d6212be9a5ed282c5670d4e90747f (diff) |
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (961 commits)
staging: hv: fix memory leaks
staging: hv: Remove NULL check before kfree
Staging: hv: Get rid of vmbus_child_dev_add()
Staging: hv: Change the signature for vmbus_child_device_register()
Staging: hv: Get rid of vmbus_cleanup() function
Staging: hv: Get rid of vmbus_dev_rm() function
Staging: hv: Change the signature for vmbus_on_isr()
Staging: hv: Eliminate vmbus_event_dpc()
Staging: hv: Get rid of the function vmbus_msg_dpc()
Staging: hv: Change the signature for vmbus_cleanup()
Staging: hv: Simplify root device management
staging: rtl8192e: Don't copy dev pointer to skb
staging: rtl8192e: Pass priv to cmdpkt functions
staging: rtl8192e: Pass priv to firmware download functions
staging: rtl8192e: Pass priv to rtl8192_interrupt
staging: rtl8192e: Pass rtl8192_priv to dm functions
staging: rtl8192e: Pass ieee80211_device to callbacks
staging: rtl8192e: Pass ieee80211_device to callbacks
staging: rtl8192e: Pass ieee80211_device to callbacks
staging: rtl8192e: Pass ieee80211_device to callbacks
...
Diffstat (limited to 'drivers/staging/usbip')
-rw-r--r-- | drivers/staging/usbip/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/usbip/stub.h | 4 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_dev.c | 12 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_main.c | 6 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_rx.c | 13 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_tx.c | 17 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_common.c | 105 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_common.h | 20 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_event.c | 38 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci.h | 4 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_hcd.c | 10 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_rx.c | 16 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_sysfs.c | 9 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_tx.c | 17 |
14 files changed, 66 insertions, 207 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 @@ config USB_IP_COMMON tristate "USB IP support (EXPERIMENTAL)" - depends on USB && NET && EXPERIMENTAL && BKL + depends on USB && NET && EXPERIMENTAL default N ---help--- 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; /* stub_tx.c */ void stub_complete(struct urb *); -void stub_tx_loop(struct usbip_task *); +int stub_tx_loop(void *data); /* stub_dev.c */ extern struct usb_driver stub_driver; /* stub_rx.c */ -void stub_rx_loop(struct usbip_task *); +int stub_rx_loop(void *data); void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); /* 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 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "stub.h" @@ -138,7 +139,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, spin_unlock(&sdev->ud.lock); - usbip_start_threads(&sdev->ud); + sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx"); + sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx"); spin_lock(&sdev->ud.lock); sdev->ud.status = SDEV_ST_USED; @@ -218,7 +220,8 @@ static void stub_shutdown_connection(struct usbip_device *ud) } /* 1. stop threads */ - usbip_stop_threads(ud); + kthread_stop(ud->tcp_rx); + kthread_stop(ud->tcp_tx); /* 2. close the socket */ /* @@ -336,9 +339,6 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev, */ sdev->devid = (busnum << 16) | devnum; - usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop); - usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop); - sdev->ud.side = USBIP_STUB; sdev->ud.status = SDEV_ST_AVAILABLE; /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */ @@ -543,7 +543,7 @@ static void stub_disconnect(struct usb_interface *interface) stub_remove_files(&interface->dev); /*If usb reset called from event handler*/ - if (busid_priv->sdev->ud.eh.thread == current) { + if (busid_priv->sdev->ud.eh == current) { busid_priv->interf_count--; return; } diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index f3a40968aae..076a7e53109 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -264,11 +264,9 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) kmem_cache_free(stub_priv_cache, priv); - if (urb->transfer_buffer != NULL) - kfree(urb->transfer_buffer); + kfree(urb->transfer_buffer); - if (urb->setup_packet != NULL) - kfree(urb->setup_packet); + kfree(urb->setup_packet); usb_free_urb(urb); } 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 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "stub.h" @@ -616,19 +617,15 @@ static void stub_rx_pdu(struct usbip_device *ud) } -void stub_rx_loop(struct usbip_task *ut) +int stub_rx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); - - while (1) { - if (signal_pending(current)) { - usbip_dbg_stub_rx("signal caught!\n"); - break; - } + struct usbip_device *ud = data; + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; stub_rx_pdu(ud); } + return 0; } 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 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "stub.h" @@ -333,17 +334,12 @@ static int stub_send_ret_unlink(struct stub_device *sdev) /*-------------------------------------------------------------------------*/ -void stub_tx_loop(struct usbip_task *ut) +int stub_tx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); + struct usbip_device *ud = data; struct stub_device *sdev = container_of(ud, struct stub_device, ud); - while (1) { - if (signal_pending(current)) { - usbip_dbg_stub_tx("signal catched\n"); - break; - } - + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; @@ -369,6 +365,9 @@ void stub_tx_loop(struct usbip_task *ut) wait_event_interruptible(sdev->tx_waitq, (!list_empty(&sdev->priv_tx) || - !list_empty(&sdev->unlink_tx))); + !list_empty(&sdev->unlink_tx) || + kthread_should_stop())); } + + return 0; } 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 @@ */ #include <linux/kernel.h> -#include <linux/smp_lock.h> #include <linux/file.h> #include <linux/tcp.h> #include <linux/in.h> @@ -349,110 +348,6 @@ void usbip_dump_header(struct usbip_header *pdu) } EXPORT_SYMBOL_GPL(usbip_dump_header); - -/*-------------------------------------------------------------------------*/ -/* thread routines */ - -int usbip_thread(void *param) -{ - struct usbip_task *ut = param; - - if (!ut) - return -EINVAL; - - lock_kernel(); - daemonize(ut->name); - allow_signal(SIGKILL); - ut->thread = current; - unlock_kernel(); - - /* srv.rb must wait for rx_thread starting */ - complete(&ut->thread_done); - - /* start of while loop */ - ut->loop_ops(ut); - - /* end of loop */ - ut->thread = NULL; - - complete_and_exit(&ut->thread_done, 0); -} - -static void stop_rx_thread(struct usbip_device *ud) -{ - if (ud->tcp_rx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_rx.thread, 1); - wait_for_completion(&ud->tcp_rx.thread_done); - usbip_udbg("rx_thread for ud %p has finished\n", ud); - } -} - -static void stop_tx_thread(struct usbip_device *ud) -{ - if (ud->tcp_tx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_tx.thread, 1); - wait_for_completion(&ud->tcp_tx.thread_done); - usbip_udbg("tx_thread for ud %p has finished\n", ud); - } -} - -int usbip_start_threads(struct usbip_device *ud) -{ - /* - * threads are invoked per one device (per one connection). - */ - struct task_struct *th; - int err = 0; - - th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip"); - if (IS_ERR(th)) { - printk(KERN_WARNING - "Unable to start control thread\n"); - err = PTR_ERR(th); - goto ust_exit; - } - - th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip"); - if (IS_ERR(th)) { - printk(KERN_WARNING - "Unable to start control thread\n"); - err = PTR_ERR(th); - goto tx_thread_err; - } - - /* confirm threads are starting */ - wait_for_completion(&ud->tcp_rx.thread_done); - wait_for_completion(&ud->tcp_tx.thread_done); - - return 0; - -tx_thread_err: - stop_rx_thread(ud); - -ust_exit: - return err; -} -EXPORT_SYMBOL_GPL(usbip_start_threads); - -void usbip_stop_threads(struct usbip_device *ud) -{ - /* kill threads related to this sdev, if v.c. exists */ - stop_rx_thread(ud); - stop_tx_thread(ud); -} -EXPORT_SYMBOL_GPL(usbip_stop_threads); - -void usbip_task_init(struct usbip_task *ut, char *name, - void (*loop_ops)(struct usbip_task *)) -{ - ut->thread = NULL; - init_completion(&ut->thread_done); - ut->name = name; - ut->loop_ops = loop_ops; -} -EXPORT_SYMBOL_GPL(usbip_task_init); - - /*-------------------------------------------------------------------------*/ /* socket routines */ 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); struct usbip_device; -struct usbip_task { - struct task_struct *thread; - struct completion thread_done; - char *name; - void (*loop_ops)(struct usbip_task *); -}; - enum usbip_side { USBIP_VHCI, USBIP_STUB, @@ -346,8 +339,8 @@ struct usbip_device { struct socket *tcp_socket; - struct usbip_task tcp_rx; - struct usbip_task tcp_tx; + struct task_struct *tcp_rx; + struct task_struct *tcp_tx; /* event handler */ #define USBIP_EH_SHUTDOWN (1 << 0) @@ -367,7 +360,7 @@ struct usbip_device { #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) unsigned long event; - struct usbip_task eh; + struct task_struct *eh; wait_queue_head_t eh_waitq; struct eh_ops { @@ -378,13 +371,6 @@ struct usbip_device { }; -void usbip_task_init(struct usbip_task *ut, char *, - void (*loop_ops)(struct usbip_task *)); - -int usbip_start_threads(struct usbip_device *ud); -void usbip_stop_threads(struct usbip_device *ud); -int usbip_thread(void *param); - void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack); 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) return 0; } -static void event_handler_loop(struct usbip_task *ut) +static int event_handler_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, eh); + struct usbip_device *ud = data; - while (1) { - if (signal_pending(current)) { - usbip_dbg_eh("signal catched!\n"); - break; - } + while (!kthread_should_stop()) { + wait_event_interruptible(ud->eh_waitq, + usbip_event_happened(ud) || + kthread_should_stop()); + usbip_dbg_eh("wakeup\n"); if (event_handler(ud) < 0) break; - - wait_event_interruptible(ud->eh_waitq, - usbip_event_happened(ud)); - usbip_dbg_eh("wakeup\n"); } + return 0; } int usbip_start_eh(struct usbip_device *ud) { - struct usbip_task *eh = &ud->eh; - struct task_struct *th; - init_waitqueue_head(&ud->eh_waitq); ud->event = 0; - usbip_task_init(eh, "usbip_eh", event_handler_loop); - - th = kthread_run(usbip_thread, (void *)eh, "usbip"); - if (IS_ERR(th)) { + ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh"); + if (IS_ERR(ud->eh)) { printk(KERN_WARNING "Unable to start control thread\n"); - return PTR_ERR(th); + return PTR_ERR(ud->eh); } - - wait_for_completion(&eh->thread_done); return 0; } EXPORT_SYMBOL_GPL(usbip_start_eh); void usbip_stop_eh(struct usbip_device *ud) { - struct usbip_task *eh = &ud->eh; - - if (eh->thread == current) + if (ud->eh == current) return; /* do not wait for myself */ - wait_for_completion(&eh->thread_done); + kthread_stop(ud->eh); usbip_dbg_eh("usbip_eh has finished\n"); } EXPORT_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; /* vhci_hcd.c */ void rh_port_connect(int rhport, enum usb_device_speed speed); void rh_port_disconnect(int rhport); -void vhci_rx_loop(struct usbip_task *ut); -void vhci_tx_loop(struct usbip_task *ut); +int vhci_rx_loop(void *data); +int vhci_tx_loop(void *data); struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 29ccc015099..e2348499859 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -18,6 +18,7 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "vhci.h" @@ -874,7 +875,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); } - usbip_stop_threads(&vdev->ud); + /* kill threads related to this sdev, if v.c. exists */ + kthread_stop(vdev->ud.tcp_rx); + kthread_stop(vdev->ud.tcp_tx); + usbip_uinfo("stop threads\n"); /* active connection is closed */ @@ -945,8 +949,8 @@ static void vhci_device_init(struct vhci_device *vdev) { memset(vdev, 0, sizeof(*vdev)); - usbip_task_init(&vdev->ud.tcp_rx, "vhci_rx", vhci_rx_loop); - usbip_task_init(&vdev->ud.tcp_tx, "vhci_tx", vhci_tx_loop); + vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); + vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); vdev->ud.side = USBIP_VHCI; 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 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "vhci.h" @@ -269,22 +270,17 @@ static void vhci_rx_pdu(struct usbip_device *ud) /*-------------------------------------------------------------------------*/ -void vhci_rx_loop(struct usbip_task *ut) +int vhci_rx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); - - - while (1) { - if (signal_pending(current)) { - usbip_dbg_vhci_rx("signal catched!\n"); - break; - } + struct usbip_device *ud = data; + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; vhci_rx_pdu(ud); } -} + return 0; +} 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, vdev->ud.tcp_socket = socket; vdev->ud.status = VDEV_ST_NOTASSIGNED; + wake_up_process(vdev->ud.tcp_rx); + wake_up_process(vdev->ud.tcp_tx); + spin_unlock(&vdev->ud.lock); spin_unlock(&the_controller->lock); /* end the lock */ - /* - * this function will sleep, so should be out of the lock. but, it's ok - * because we already marked vdev as being used. really? - */ - usbip_start_threads(&vdev->ud); - rh_port_connect(rhport, speed); 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 @@ */ #include <linux/slab.h> +#include <linux/kthread.h> #include "usbip_common.h" #include "vhci.h" @@ -215,17 +216,12 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev) /*-------------------------------------------------------------------------*/ -void vhci_tx_loop(struct usbip_task *ut) +int vhci_tx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); + struct usbip_device *ud = data; struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); - while (1) { - if (signal_pending(current)) { - usbip_uinfo("vhci_tx signal catched\n"); - break; - } - + while (!kthread_should_stop()) { if (vhci_send_cmd_submit(vdev) < 0) break; @@ -234,8 +230,11 @@ void vhci_tx_loop(struct usbip_task *ut) wait_event_interruptible(vdev->waitq_tx, (!list_empty(&vdev->priv_tx) || - !list_empty(&vdev->unlink_tx))); + !list_empty(&vdev->unlink_tx) || + kthread_should_stop())); usbip_dbg_vhci_tx("pending urbs ?, now wake up\n"); } + + return 0; } |