Commit 05a1f28e authored by Takahiro Hirofuchi's avatar Takahiro Hirofuchi Committed by Greg Kroah-Hartman

Staging: USB/IP: add common functions needed

This adds the common functions needed by both the host and client side
of the USB/IP code.

Brian Merrell cleaned up a lot of this code and submitted it for
inclusion.  Greg also did a lot of cleanup.
Signed-off-by: default avatarBrian G. Merrell <bgmerrell@novell.com>
Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 866b8695
...@@ -33,4 +33,6 @@ source "drivers/staging/me4000/Kconfig" ...@@ -33,4 +33,6 @@ source "drivers/staging/me4000/Kconfig"
source "drivers/staging/go7007/Kconfig" source "drivers/staging/go7007/Kconfig"
source "drivers/staging/usbip/Kconfig"
endif # STAGING endif # STAGING
...@@ -5,3 +5,4 @@ obj-$(CONFIG_SLICOSS) += slicoss/ ...@@ -5,3 +5,4 @@ obj-$(CONFIG_SLICOSS) += slicoss/
obj-$(CONFIG_SXG) += sxg/ obj-$(CONFIG_SXG) += sxg/
obj-$(CONFIG_ME4000) += me4000/ obj-$(CONFIG_ME4000) += me4000/
obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_VIDEO_GO7007) += go7007/
obj-$(CONFIG_USB_IP_COMMON) += usbip/
config USB_IP_COMMON
tristate "USB IP support (EXPERIMENTAL)"
depends on USB && EXPERIMENTAL
default N
---help---
This enables pushing USB packets over IP to allow remote
machines access to USB devices directly. For more details,
and links to the userspace utility programs to let this work
properly, see http://usbip.naist.jp/
To compile this driver as a module, choose M here: the
module will be called usbip_common_mod.
If unsure, say N.
obj-$(CONFIG_USB_IP_COMMON) += usbip_common_mod.o
usbip_common_mod-objs := usbip_common.o usbip_event.o
ifeq ($(CONFIG_USB_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
TODO:
- more discussion about the protocol
- testing
- review of the userspace interface
Please send patches for this code to Greg Kroah-Hartman <greg@kroah.com>
This diff is collapsed.
This diff is collapsed.
/*
* 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 "usbip_common.h"
static int event_handler(struct usbip_device *ud)
{
dbg_eh("enter\n");
/*
* Events are handled by only this thread.
*/
while (usbip_event_happend(ud)) {
dbg_eh("pending event %lx\n", ud->event);
/*
* NOTE: shutdown must come first.
* Shutdown the device.
*/
if (ud->event & USBIP_EH_SHUTDOWN) {
ud->eh_ops.shutdown(ud);
ud->event &= ~USBIP_EH_SHUTDOWN;
break;
}
/* Stop the error handler. */
if (ud->event & USBIP_EH_BYE)
return -1;
/* Reset the device. */
if (ud->event & USBIP_EH_RESET) {
ud->eh_ops.reset(ud);
ud->event &= ~USBIP_EH_RESET;
break;
}
/* Mark the device as unusable. */
if (ud->event & USBIP_EH_UNUSABLE) {
ud->eh_ops.unusable(ud);
ud->event &= ~USBIP_EH_UNUSABLE;
break;
}
/* NOTREACHED */
printk(KERN_ERR "%s: unknown event\n", __func__);
return -1;
}
return 0;
}
static void event_handler_loop(struct usbip_task *ut)
{
struct usbip_device *ud = container_of(ut, struct usbip_device, eh);
while (1) {
if (signal_pending(current)) {
dbg_eh("signal catched!\n");
break;
}
if (event_handler(ud) < 0)
break;
wait_event_interruptible(ud->eh_waitq, usbip_event_happend(ud));
dbg_eh("wakeup\n");
}
}
void usbip_start_eh(struct usbip_device *ud)
{
struct usbip_task *eh = &ud->eh;
init_waitqueue_head(&ud->eh_waitq);
ud->event = 0;
usbip_task_init(eh, "usbip_eh", event_handler_loop);
kernel_thread(usbip_thread, (void *)eh, 0);
wait_for_completion(&eh->thread_done);
}
EXPORT_SYMBOL_GPL(usbip_start_eh);
void usbip_stop_eh(struct usbip_device *ud)
{
struct usbip_task *eh = &ud->eh;
wait_for_completion(&eh->thread_done);
dbg_eh("usbip_eh has finished\n");
}
EXPORT_SYMBOL_GPL(usbip_stop_eh);
void usbip_event_add(struct usbip_device *ud, unsigned long event)
{
spin_lock(&ud->lock);
ud->event |= event;
wake_up(&ud->eh_waitq);
spin_unlock(&ud->lock);
}
EXPORT_SYMBOL_GPL(usbip_event_add);
int usbip_event_happend(struct usbip_device *ud)
{
int happend = 0;
spin_lock(&ud->lock);
if (ud->event != 0)
happend = 1;
spin_unlock(&ud->lock);
return happend;
}
EXPORT_SYMBOL_GPL(usbip_event_happend);
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