diff -Naur usbip-0.1.4/drivers/2.6.15/Makefile trunk/drivers/2.6.15/Makefile
--- usbip-0.1.4/drivers/2.6.15/Makefile	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,63 +0,0 @@
-# Makefile for the USB/IP driver
-#
-# $Id: Makefile 97 2006-03-31 16:08:40Z taka-hir $
-#
-# Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
-#
-#
-# 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.
-#
-
- 
-# Please modify here or set environments.
-# KSOURCE should be pointed to the build directory of your kernel.
-# 
-DEBUG ?= n
-KSOURCE ?= /usr/src/linux
-
-
-%.x:%.c
-	gcc -o $@ $<
-
-KBUILD_VERBOSE:=1
-
-HCD_HEADER:=$(KSOURCE)/drivers/usb/core/hcd.h
-
-obj-m += usbip.o
-usbip-objs :=  usbip_common.o usbip_event.o stub_dev.o stub_main.o stub_rx.o stub_tx.o
-
-obj-m += vhci-hcd.o
-vhci-hcd-objs :=  usbip_common.o usbip_event.o vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
-
-
-EXTRA_CFLAGS += -DHCD_HEADER=\"$(HCD_HEADER)\"
-
-ifeq ($(DEBUG),y)
-	EXTRA_CFLAGS += -DCONFIG_USB_DEBUG
-endif
-
-
-default:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` modules
-
-.PHONY: cscope
-cscope:
-	cscope -b -k -R
-
-.PHONY: clean
-clean:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` clean
-	rm -f *.x *~
diff -Naur usbip-0.1.4/drivers/2.6.15/stub_dev.c trunk/drivers/2.6.15/stub_dev.c
--- usbip-0.1.4/drivers/2.6.15/stub_dev.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/stub_dev.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,438 +0,0 @@
-/*
- * $Id: stub_dev.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-
-static int stub_probe(struct usb_interface *interface,  const struct usb_device_id *id);
-static void stub_disconnect(struct usb_interface *interface);
-
-
-/*
- * Define device IDs here if you want to explicitly limit exportable devices.
- * In the most cases, wild card matching will be ok because driver binding can
- * be changed dynamically by a userland program.
- */
-static struct usb_device_id stub_table[] = {
-#if 0
-	/* just an example */
-	{ USB_DEVICE(0x05ac, 0x0301) },   /* Mac 1 button mouse */
-	{ USB_DEVICE(0x0430, 0x0009) },   /* Plat Home Keyboard */
-	{ USB_DEVICE(0x059b, 0x0001) },   /* Iomega USB Zip 100 */
-	{ USB_DEVICE(0x04b3, 0x4427) },   /* IBM USB CD-ROM */
-	{ USB_DEVICE(0x05a9, 0xa511) },   /* LifeView USB cam */
-	{ USB_DEVICE(0x55aa, 0x0201) },   /* Imation card reader */
-	{ USB_DEVICE(0x046d, 0x0870) },   /* Qcam Express(QV-30) */
-	{ USB_DEVICE(0x04bb, 0x0101) },   /* IO-DATA HD 120GB */
-	{ USB_DEVICE(0x04bb, 0x0904) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x04bb, 0x0201) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x08bb, 0x2702) },   /* ONKYO USB Speaker */
-	{ USB_DEVICE(0x046d, 0x08b2) },   /* Logicool Qcam 4000 Pro */
-#endif
-	/* magic for wild card */
-	{ .driver_info = 1 },
-	{ }                                     /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, stub_table);
-
-
-struct usb_driver stub_driver = {
-	.name		= "usbip",
-
-	.probe		= stub_probe,
-	.disconnect 	= stub_disconnect,
-
-	.id_table	= stub_table,
-};
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for a usbip-bound device */
-
-
-/*
- * usbip_status shows status of usbip as long as this driver is bound to the
- * target device.
- */
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct stub_device *sdev = dev_get_drvdata(dev);
-	int status;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	spin_lock(&sdev->ud.lock);
-	status = sdev->ud.status;
-	spin_unlock(&sdev->ud.lock);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", status);
-}
-static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
-
-
-/*
- * 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;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	sscanf(buf, "%d", &sockfd);
-
-	if (sockfd != -1) {
-		uinfo("stub up\n");
-
-		spin_lock(&sdev->ud.lock);
-
-		if (sdev->ud.status != SDEV_ST_AVAILABLE) {
-			uerr("not ready\n");
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		socket = sockfd_to_socket(sockfd);
-		if (!socket) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		setnodelay(socket);
-		setkeepalive(socket);
-		setreuse(socket);
-
-		sdev->ud.tcp_socket = socket;
-
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_start_threads(&sdev->ud);
-
-		spin_lock(&sdev->ud.lock);
-		sdev->ud.status = SDEV_ST_USED;
-		spin_unlock(&sdev->ud.lock);
-
-	} else {
-		uinfo("stub down\n");
-
-		spin_lock(&sdev->ud.lock);
-		if (sdev->ud.status != SDEV_ST_USED) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
-	}
-
-	return count;
-}
-static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
-
-static void stub_add_files(struct device *dev)
-{
-	device_create_file(dev, &dev_attr_usbip_status);
-	device_create_file(dev, &dev_attr_usbip_sockfd);
-	device_create_file(dev, &dev_attr_usbip_debug);
-}
-
-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);
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Event handler functions called by an event handler thread */
-
-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) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	/* 1. stop threads */
-	usbip_stop_threads(ud);
-
-	/* 2. close the socket */
-	/*
-	 * tcp_socket is freed after threads are killed.
-	 * So usbip_xmit do not touch NULL socket.
-	 */
-	if (ud->tcp_socket) {
-		sock_release(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);
-	struct usb_device *udev = interface_to_usbdev(sdev->interface);
-	int ret;
-
-	ret = usb_lock_device_for_reset(udev, sdev->interface);
-	if (ret < 0) {
-		uerr("lock for reset\n");
-
-		spin_lock(&ud->lock);
-		ud->status = SDEV_ST_ERROR;
-		spin_unlock(&ud->lock);
-
-		return;
-	}
-
-	/* try to reset the device */
-	ret = usb_reset_device(udev);
-
-	usb_unlock_device(udev);
-
-	spin_lock(&ud->lock);
-	if (ret) {
-		uerr("device reset\n");
-		ud->status = SDEV_ST_ERROR;
-
-	} else {
-		uinfo("device reset\n");
-		ud->status = SDEV_ST_AVAILABLE;
-
-	}
-	spin_unlock(&ud->lock);
-
-	return;
-}
-
-static void stub_device_unusable(struct usbip_device *ud)
-{
-	spin_lock(&ud->lock);
-	ud->status = SDEV_ST_ERROR;
-	spin_unlock(&ud->lock);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * stub_device_alloc - allocate a new stub_device struct
- * @interface: usb_interface of a new device
- *
- * Allocates and initializes a new stub_devce struct.
- */
-static struct stub_device * stub_device_alloc(struct usb_interface *interface)
-{
-	struct stub_device *sdev;
-
-	/* yes, it's a new device */
-	sdev = (struct stub_device *) kzalloc(sizeof(struct stub_device), GFP_KERNEL);
-	if (!sdev) {
-		uerr("no memory for stub_device\n");
-		return NULL;
-	}
-
-	sdev->interface = interface;
-
-	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;
-	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);
-	sdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	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);
-
-	udbg("register new interface\n");
-	return sdev;
-}
-
-static int stub_device_free(struct stub_device *sdev)
-{
-	if (!sdev)
-		return -EINVAL;
-
-	kfree(sdev);
-	udbg("kfree udev ok\n");
-
-	return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e. not *an*
- * active interface). Currently, a userland program must ensure that it
- * looks at the usbip's sysfs entries of only the first active interface.
- */
-static int stub_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	struct stub_device *sdev = NULL;
-	char *udev_busid = interface->dev.parent->bus_id;
-
-	udbg("Enter\n");
-
-	/* check we should claim or not by busid_table */
-	if (match_busid(udev_busid)) {
-		uinfo("this device %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) {
-		udbg("this device %s is a usb hub device. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		udbg("this device %s is attached on vhci_hcd. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	/* ok. this is my device. */
-
-	if ((sdev = stub_device_alloc(interface))) {
-		struct usb_device *udev = interface_to_usbdev(interface);
-
-		uinfo("USB/IP Stub: register a new interface (bus %u dev %u ifn %u)\n",
-				udev->bus->busnum, udev->devnum,
-				interface->cur_altsetting->desc.bInterfaceNumber);
-	} else
-		return -ENOMEM;
-
-	/* set private data to usb_interface */
-	usb_set_intfdata(interface, sdev);
-
-	stub_add_files(&interface->dev);
-
-	return 0;
-}
-
-
-/*
- * called in usb_disconnect() or usb_deregister()
- * but only if actconfig(active configuration) exists
- */
-static void stub_disconnect(struct usb_interface *interface)
-{
-	struct stub_device *sdev = usb_get_intfdata(interface);
-
-	udbg("Enter\n");
-
-	/* get stub_device */
-	if (!sdev)
-		BUG();
-
-	usb_set_intfdata(interface, NULL);
-
-
-	/*
-	 * NOTE:
-	 * rx/tx threads are invoked for each usb_device.
-	 */
-	stub_remove_files(&interface->dev);
-
-	/* 1. shutdown the current connection */
-	usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
-
-	/* 2. wait for the stop of the event handler */
-	usbip_stop_eh(&sdev->ud);
-
-	/* 3. free sdev */
-	stub_device_free(sdev);
-
-
-	udbg("bye\n");
-}
diff -Naur usbip-0.1.4/drivers/2.6.15/stub.h trunk/drivers/2.6.15/stub.h
--- usbip-0.1.4/drivers/2.6.15/stub.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/stub.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,96 +0,0 @@
-/*
- * $Id: stub.h 173 2006-07-21 09:48:40Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-
-struct stub_device {
-	struct usb_interface *interface;
-	struct list_head list;
-
-	struct usbip_device ud;
-
-	/*
-	 * stub_priv preserves private data of each urb.
-	 * It is allocated as stub_priv_cache and assigned to urb->context.
-	 *
-	 * stub_priv is always linked to any one of 3 lists;
-	 * 	priv_init: linked to this until the comletion of a urb.
-	 * 	priv_tx  : linked to this after the completion of a urb.
-	 * 	priv_free: linked to this after the sending of the result.
-	 *
-	 * Any of these list operations should be locked by priv_lock.
-	 */
-	spinlock_t priv_lock;
-	struct list_head priv_init;
-	struct list_head priv_tx;
-	struct list_head priv_free;
-
-	/* see comments for unlinking in stub_rx.c */
-	struct list_head unlink_tx;
-	struct list_head unlink_free;
-
-
-	wait_queue_head_t tx_waitq;
-};
-
-/* private data into urb->priv */
-struct stub_priv {
-	unsigned long seqnum;
-	struct list_head list;
-	struct stub_device *sdev;
-	struct urb *urb;
-
-	int unlinking;
-};
-
-struct stub_unlink {
-	unsigned long seqnum;
-	struct list_head list;
-	__u32 status;
-};
-
-
-extern kmem_cache_t *stub_priv_cache;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declarations */
-
-/* stub_tx.c */
-void stub_complete(struct urb*, struct pt_regs *);
-void stub_tx_loop(struct usbip_task *);
-
-/* stub_dev.c */
-extern struct usb_driver stub_driver;
-
-/* stub_rx.c */
-void stub_rx_loop(struct usbip_task *);
-void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
-
-/* stub_main.c */
-int match_busid(char *busid);
-void stub_device_cleanup_urbs(struct stub_device *sdev);
diff -Naur usbip-0.1.4/drivers/2.6.15/stub_main.c trunk/drivers/2.6.15/stub_main.c
--- usbip-0.1.4/drivers/2.6.15/stub_main.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/stub_main.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,300 +0,0 @@
-/*
- * $Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-/* Version Information */
-#define DRIVER_VERSION "$Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $"
-#define DRIVER_AUTHOR "Takahiro Hirofuchi <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Stub Driver for USB/IP"
-
-
-
-/* stub_priv is allocated from stub_priv_cache */
-kmem_cache_t *stub_priv_cache = NULL;
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for the usbip driver */
-
-
-/*
- * busid_tables defines matching busids that usbip can grab. A user can change
- * dynamically what device is locally used and what device is exported to a
- * remote host.
- */
-#define MAX_BUSID 16
-static char busid_table[MAX_BUSID][BUS_ID_SIZE];
-spinlock_t busid_table_lock = SPIN_LOCK_UNLOCKED;
-
-
-int match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-				/* already registerd */
-				spin_unlock(&busid_table_lock);
-				return 0;
-			}
-
-	spin_unlock(&busid_table_lock);
-
-	return 1;
-}
-
-static ssize_t show_match_busid(struct device_driver *drv, char *buf)
-{
-	int i;
-	char *out = buf;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			out += sprintf(out, "%s ", busid_table[i]);
-
-	spin_unlock(&busid_table_lock);
-
-	out += sprintf(out, "\n");
-
-	return out - buf;
-}
-
-static int add_match_busid(char *busid)
-{
-	int i;
-
-	if (!match_busid(busid))
-		return 0;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!busid_table[i][0]) {
-			strncpy(busid_table[i], busid, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static int del_match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-			/* found */
-			memset(busid_table[i], 0, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
-		size_t count)
-{
-	int len;
-	char busid[BUS_ID_SIZE];
-
-	if (count < 5)
-		return -EINVAL;
-
-	/* strnlen() does not include \0 */
-	len = strnlen(buf + 4, BUS_ID_SIZE);
-
-	/* busid needs to include \0 termination */
-	if (!(len < BUS_ID_SIZE))
-		return -EINVAL;
-
-	strncpy(busid, buf + 4, BUS_ID_SIZE);
-
-
-	if (!strncmp(buf, "add ", 4)) {
-		if (add_match_busid(busid) < 0)
-			return -ENOMEM;
-		else {
-			udbg("add busid %s\n", busid);
-			return count;
-		}
-	} else if (!strncmp(buf, "del ", 4)) {
-		if (del_match_busid(busid) < 0)
-			return -ENODEV;
-		else {
-			udbg("del busid %s\n", busid);
-			return count;
-		}
-	} else
-		return -EINVAL;
-}
-
-static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, store_match_busid);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Cleanup functions used to free private data */
-
-static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
-{
-	struct stub_priv *priv, *tmp;
-
-	list_for_each_entry_safe(priv, tmp, listhead, list) {
-		list_del(&priv->list);
-		return priv;
-	}
-
-	return NULL;
-}
-
-static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_init);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_free);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-	return NULL;
-}
-
-void stub_device_cleanup_urbs(struct stub_device *sdev)
-{
-	struct stub_priv *priv;
-
-	udbg("free sdev %p\n", sdev);
-
-	while ((priv = stub_priv_pop(sdev))) {
-		struct urb *urb = priv->urb;
-
-		udbg("   free urb %p\n", urb);
-		usb_kill_urb(urb);
-
-		kmem_cache_free(stub_priv_cache, priv);
-
-		if (urb->transfer_buffer != NULL)
-			kfree(urb->transfer_buffer);
-
-		if (urb->setup_packet != NULL)
-			kfree(urb->setup_packet);
-
-		usb_free_urb(urb);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init usb_stub_init(void)
-{
-	int ret;
-
-	stub_priv_cache = kmem_cache_create("stub_priv", sizeof(struct stub_priv),
-			0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!stub_priv_cache) {
-		uerr("create stub_priv_cache\n");
-		return -ENOMEM;
-	}
-
-	ret = usb_register(&stub_driver);
-	if (ret) {
-		uerr("usb_register failed %d\n", ret);
-		return ret;
-	}
-
-
-	info(DRIVER_DESC "" DRIVER_VERSION);
-
-	memset(busid_table, 0, sizeof(busid_table));
-
-	driver_create_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	return ret;
-}
-
-static void __exit usb_stub_exit(void)
-{
-	int ret;
-
-	udbg("enter\n");
-
-	driver_remove_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	/*
-	 * deregister() calls stub_disconnect() for all devices. Device
-	 * specific data is cleared in stub_disconnect().
-	 */
-	usb_deregister(&stub_driver);
-
-	ret = kmem_cache_destroy(stub_priv_cache);
-	if (ret != 0) {
-		uerr("memory leak of stub_priv, %d\n", ret);
-	}
-
-	udbg("bye\n");
-}
-
-
-
-
-module_init (usb_stub_init);
-module_exit (usb_stub_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff -Naur usbip-0.1.4/drivers/2.6.15/stub_rx.c trunk/drivers/2.6.15/stub_rx.c
--- usbip-0.1.4/drivers/2.6.15/stub_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/stub_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,442 +0,0 @@
-/*
- * $Id: stub_rx.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static int is_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	 return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
-		 (req->bRequestType == USB_RECIP_ENDPOINT) &&
-		 (req->wValue == USB_ENDPOINT_HALT);
-}
-
-static int is_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_INTERFACE) &&
-		   (req->bRequestType == USB_RECIP_INTERFACE);
-}
-
-static int is_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
-		   (req->bRequestType == USB_RECIP_DEVICE);
-}
-
-static int tweak_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	int target_endp;
-	int target_dir;
-	int target_pipe;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	/*
-	 * The stalled endpoint is specified in the wIndex value. The endpoint
-	 * of the urb is the target of this clear_halt request (i.e. control
-	 * endpoint).
-	 */
-	target_endp = le16_to_cpu(req->wIndex) & 0x000f;
-
-	/* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
-	target_dir = le16_to_cpu(req->wIndex) & 0x0080;
-
-	if (target_dir)
-		target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
-	else
-		target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
-
-	ret = usb_clear_halt(urb->dev, target_pipe);
-	if (ret < 0)
-		uinfo("clear_halt error: devnum %d endp %d, %d\n",
-				urb->dev->devnum, target_endp, ret);
-	else
-		uinfo("clear_halt done: devnum %d endp %d\n",
-				urb->dev->devnum, target_endp);
-
-	return ret;
-}
-
-static int tweak_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 alternate;
-	__u16 interface;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	alternate = le16_to_cpu(req->wValue);
-	interface = le16_to_cpu(req->wIndex);
-
-	dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
-
-	ret = usb_set_interface(urb->dev, interface, alternate);
-	if (ret < 0)
-		uinfo("set_interface error: inf %u alt %u, %d\n",
-				interface, alternate, ret);
-	else
-		uinfo("set_interface done: inf %u alt %u\n", interface, alternate);
-
-	return ret;
-}
-
-static int tweak_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 config;
-
-	info("set_configuration is not fully supported yet\n");
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	config = le16_to_cpu(req->wValue);
-
-	uinfo("set_configuration: devnum %d %d\n", urb->dev->devnum, config);
-
-#if 0
-	return usb_set_configuration(urb->dev, config);
-#endif
-	return 0;
-}
-
-/*
- * clear_halt, set_interface, and set_configuration require special tricks.
- * TODO: set_configuration. but I have never seen a multi-config device.
- */
-static void tweak_special_requests(struct urb *urb)
-{
-	if (!urb || !urb->setup_packet)
-		return;
-
-	if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
-		return;
-
-	if (is_clear_halt_cmd(urb))
-		/* treak clear_halt */
-		 tweak_clear_halt_cmd(urb);
-
-	else if (is_set_interface_cmd(urb))
-		/* tweak set_interface */
-		tweak_set_interface_cmd(urb);
-
-	else if (is_set_configuration_cmd(urb))
-		/* tweak set_configuration */
-		tweak_set_configuration_cmd(urb);
-
-	else
-		dbg_stub_rx("no need to tweak\n");
-}
-
-/*
- * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
- * By unlinking the urb asynchronously, stub_rx can continuously
- * process coming urbs.  Even if the urb is unlinked, its completion
- * handler will be called and stub_tx will send a return pdu.
- *
- * See also comments about unlinking strategy in vhci_hcd.c.
- */
-static int stub_recv_cmd_unlink(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct list_head *listhead = &sdev->priv_init;
-	struct list_head *ptr;
-	unsigned long flags;
-
-	struct stub_priv *priv;
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
-		priv = list_entry(ptr, struct stub_priv, list);
-		if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
-			int ret;
-
-			uinfo("unlink urb %p\n", priv->urb);
-
-			/*
-			 * This matched urb is not completed yet (i.e. be in
-			 * flight in usb hcd hardware/driver). Now we are
-			 * cancelling it. The unlinking flag means that we are
-			 * now not going to return the normal result pdu of a
-			 * submittion request, but going to return a result pdu
-			 * of the unlink request.
-			 */
-			priv->unlinking = 1;
-
-			/*
-			 * In the case that unlinking flag is on, prev->seqnum
-			 * is changed from the seqnum of the cancelling urb to
-			 * the seqnum of the unlink request. This will be used
-			 * to make the result pdu of the unlink request.
-			 */
-			priv->seqnum = pdu->base.seqnum;
-
-			spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-			/*
-			 * usb_unlink_urb() is now out of spinlocking to avoid
-			 * spinlock recursion since stub_complete() is
-			 * sometimes called in this context but not in the
-			 * interrupt context.  If stub_complete() is executed
-			 * before we call usb_unlink_urb(), usb_unlink_urb()
-			 * will return an error value. In this case, stub_tx
-			 * will return the result pdu of this unlink request
-			 * though submission is completed and actual unlinking
-			 * is not executed. OK?
-			 */
-			ret = usb_unlink_urb(priv->urb);
-			if (ret != -EINPROGRESS)
-				uerr("faild to unlink a urb %p, ret %d\n", priv->urb, ret);
-
-			return 0;
-		}
-	}
-
-	dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
-
-	/*
-	 * The urb of the unlink target is not found in priv_init queue. It was
-	 * already completed and its results is/was going to be sent by a
-	 * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
-	 * return the completeness of this unlink request to vhci_hcd.
-	 */
-	stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-
-	return 0;
-}
-
-static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &sdev->ud;
-
-	int bus = interface_to_busnum(sdev->interface);
-	int dev = interface_to_devnum(sdev->interface);
-
-	if (pdu->base.busnum == bus && pdu->base.devnum == dev) {
-		spin_lock(&ud->lock);
-		if (ud->status == SDEV_ST_USED) {
-			/* A request is valid. */
-			spin_unlock(&ud->lock);
-			return 1;
-		}
-		spin_unlock(&ud->lock);
-	}
-
-	return 0;
-}
-
-static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
-		struct usbip_header *pdu)
-{
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
-	if (!priv) {
-		uerr("alloc stub_priv\n");
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return NULL;
-	}
-
-	memset(priv, 0, sizeof(struct stub_priv));
-
-	priv->seqnum = pdu->base.seqnum;
-	priv->sdev = sdev;
-
-	/*
-	 * After a stub_priv is linked to a list_head,
-	 * our error handler can free allocated data.
-	 */
-	list_add_tail(&priv->list, &sdev->priv_init);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return priv;
-}
-
-static void stub_recv_cmd_submit(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	int ret;
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-
-
-	priv = stub_priv_alloc(sdev, pdu);
-	if (!priv)
-		return;
-
-	/* setup a urb */
-	if (usb_pipeisoc(pdu->base.pipe))
-		priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, GFP_KERNEL);
-	else
-		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
-
-	if (!priv->urb) {
-		uerr("malloc urb\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	/* set priv->urb->transfer_buffer */
-	if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
-		priv->urb->transfer_buffer =
-			kzalloc(pdu->u.cmd_submit.transfer_buffer_length, GFP_KERNEL);
-		if (!priv->urb->transfer_buffer) {
-			uerr("malloc x_buff\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-			return;
-		}
-	}
-
-	/* set priv->urb->setup_packet */
-	priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
-	if (!priv->urb->setup_packet) {
-		uerr("allocate setup_packet\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-	memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
-
-	/* set other members from the base header of pdu */
-	priv->urb->context                = (void *) priv;
-	priv->urb->dev                    = interface_to_usbdev(sdev->interface);
-	priv->urb->pipe                   = pdu->base.pipe;
-	priv->urb->complete               = stub_complete;
-
-	usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
-
-
-	if (usbip_recv_xbuff(ud, priv->urb) < 0)
-		return;
-
-	if (usbip_recv_iso(ud, priv->urb) < 0)
-		return;
-
-	tweak_special_requests(priv->urb);
-
-	/* urb is now ready to submit */
-	ret = usb_submit_urb(priv->urb, GFP_KERNEL);
-
-	if (ret == 0)
-		dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
-	else {
-		uerr("submit_urb error, %d\n", ret);
-
-		/*
-		 * Pessimistic.
-		 * This connection will be discared.
-		 */
-		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
-	}
-
-	dbg_stub_rx("Leave\n");
-	return;
-}
-
-/* recv a pdu */
-static void stub_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-
-	dbg_stub_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_stub_rx)
-		usbip_dump_header(&pdu);
-
-	if (!valid_request(sdev, &pdu)) {
-		uerr("recv invalid request\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	switch (pdu.base.command) {
-		case USBIP_CMD_UNLINK:
-			stub_recv_cmd_unlink(sdev, &pdu);
-			break;
-
-		case USBIP_CMD_SUBMIT:
-			stub_recv_cmd_submit(sdev, &pdu);
-			break;
-
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-			return;
-	}
-
-}
-
-void stub_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_rx("signal catched!\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		stub_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.15/stub_tx.c trunk/drivers/2.6.15/stub_tx.c
--- usbip-0.1.4/drivers/2.6.15/stub_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/stub_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,374 +0,0 @@
-/*
- * $Id: stub_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static void stub_free_priv_and_urb(struct stub_priv *priv)
-{
-	struct urb *urb = priv->urb;
-
-	if (urb->setup_packet)
-		kfree(urb->setup_packet);
-
-	if (urb->transfer_buffer)
-		kfree(urb->transfer_buffer);
-
-	list_del(&priv->list);
-	kmem_cache_free(stub_priv_cache, priv);
-
-	usb_free_urb(urb);
-}
-
-/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
-void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, __u32 status)
-{
-	struct stub_unlink *unlink;
-
-	unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
-	if (!unlink) {
-		uerr("alloc stub_unlink\n");
-		usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	unlink->seqnum = seqnum;
-	unlink->status = status;
-
-	list_add_tail(&unlink->list, &sdev->unlink_tx);
-}
-
-/**
- * stub_complete - completion handler of a usbip urb
- * @urb: pointer to the urb completed
- * @regs:
- *
- * When a urb has completed, the USB core driver calls this function mostly in
- * the interrupt context. To return the result of a urb, the completed urb is
- * linked to the pending list of returning.
- *
- */
-void stub_complete(struct urb *urb, struct pt_regs *regs)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-	struct stub_device *sdev = priv->sdev;
-	unsigned long flags;
-
-	dbg_stub_tx("complete! status %d\n", urb->status);
-
-
-	switch (urb->status) {
-		case 0:
-			/* OK */
-			break;
-		case -ENOENT:
-			uinfo("stopped by a call of usb_kill_urb()"
-					"because of cleaning up a virtual connection\n");
-			return;
-		case -ECONNRESET:
-			uinfo("unlinked by a call of usb_unlink_urb()\n");
-			break;
-		case -EPIPE:
-			uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
-			break;
-		case -ESHUTDOWN:
-			uinfo("device removed?\n");
-			break;
-		default:
-			uinfo("urb completion with non-zero status %d\n", urb->status);
-	}
-
-	/* link a urb to the queue of tx. */
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	if (priv->unlinking) {
-		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
-		stub_free_priv_and_urb(priv);
-	} else
-		list_move_tail(&priv->list, &sdev->priv_tx);
-
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	/* wake up tx_thread */
-	wake_up(&sdev->tx_waitq);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* fill PDU */
-
-static inline void setup_base_pdu(struct usbip_header_basic *base,
-		__u32 command, __u32 seqnum)
-{
-	base->command = command;
-	base->busnum  = 0;
-	base->devnum  = 0;
-	base->seqnum  = seqnum;
-	base->pipe    = 0;
-}
-
-static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-
-	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
-
-	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
-}
-
-static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
-		struct stub_unlink *unlink)
-{
-	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
-
-	rpdu->u.ret_unlink.status = unlink->status;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_SUBMIT */
-
-static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
-		list_move_tail(&priv->list, &sdev->priv_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int stub_send_ret_submit(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_ret_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->actual_length;
-			txsize += urb->actual_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
-		stub_free_priv_and_urb(priv);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_UNLINK */
-
-static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
-{
-	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_move_tail(&unlink->list, &sdev->unlink_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-static int stub_send_ret_unlink(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_unlink *unlink, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[1];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
-
-		/* 1. setup usbip_header */
-		setup_ret_unlink_pdu(&pdu_header, unlink);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void stub_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_tx("signal catched\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		/*
-		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
-		 * looks at only priv_init queue. If the completion of a URB is
-		 * earlier than the recieve of CMD_UNLINK, priv is moved to
-		 * priv_tx queue and stub_rx does not find the target priv. In
-		 * this case, vhci_rx recieves the result of the submit request
-		 * and then recieves the result of the unlink request. The
-		 * result of the submit is given back to the usbcore as the
-		 * completion of the unlink request. The request of the
-		 * unlink is ignored. This is ok because a driver who calls
-		 * usb_unlink_urb() understands the unlink was too late by
-		 * getting the status of the given-backed URB which has the
-		 * status of usb_submit_urb().
-		 */
-		if (stub_send_ret_submit(sdev) < 0)
-			break;
-
-		if (stub_send_ret_unlink(sdev) < 0)
-			break;
-
-		wait_event_interruptible(sdev->tx_waitq,
-				(!list_empty(&sdev->priv_tx) ||
-				 !list_empty(&sdev->unlink_tx)));
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.15/usbip_common.c trunk/drivers/2.6.15/usbip_common.c
--- usbip-0.1.4/drivers/2.6.15/usbip_common.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/usbip_common.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,935 +0,0 @@
-/*
- * $Id: usbip_common.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/file.h>
-#include <linux/tcp.h>
-#include <linux/in.h>
-#include "usbip_common.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* debug routines */
-
-#ifdef CONFIG_USB_DEBUG
-unsigned long usbip_debug_flag = 0xffffffff;
-#else
-unsigned long usbip_debug_flag = 0;
-#endif
-
-static ssize_t show_flag(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%lx\n", usbip_debug_flag);
-}
-
-static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	unsigned long flag;
-
-	sscanf(buf, "%lx", &flag);
-	usbip_debug_flag = flag;
-
-	return count;
-}
-DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
-
-static void usbip_dump_buffer(char *buff, int bufflen)
-{
-	int i;
-
-	if (bufflen > 128) {
-		for (i = 0; i< 128; i++) {
-			if (i%24 == 0)
-				printk("   ");
-			printk("%02x ", (unsigned char ) buff[i]);
-			if (i%4 == 3) printk("| ");
-			if (i%24 == 23) printk("\n");
-		}
-		printk("... (%d byte)\n", bufflen);
-		return;
-	}
-
-	for (i = 0; i< bufflen; i++) {
-		if (i%24 == 0)
-			printk("   ");
-		printk("%02x ", (unsigned char ) buff[i]);
-		if (i%4 == 3)
-			printk("| ");
-		if (i%24 == 23)
-			printk("\n");
-	}
-	printk("\n");
-
-}
-
-static void usbip_dump_pipe(unsigned int p)
-{
-	unsigned char type = usb_pipetype(p);
-	unsigned char ep = usb_pipeendpoint(p);
-	unsigned char dev = usb_pipedevice(p);
-	unsigned char dir = usb_pipein(p);
-
-	printk("dev(%d) ", dev);
-	printk("ep(%d) ",  ep);
-	printk("%s ", dir ? "IN" : "OUT");
-
-	switch(type) {
-		case PIPE_ISOCHRONOUS :
-			printk("%s ", "ISO");
-			break;
-		case PIPE_INTERRUPT :
-			printk("%s ", "INT");
-			break;
-		case PIPE_CONTROL :
-			printk("%s ", "CTL");
-			break;
-		case PIPE_BULK :
-			printk("%s ", "BLK");
-			break;
-		default :
-			printk("ERR");
-	}
-
-	printk("\n");
-
-}
-
-static void usbip_dump_usb_device(struct usb_device *dev)
-{
-	int i;
-
-	if (!dev) {
-		printk("      dump usb dev: null pointer!!\n");
-		return;
-	}
-
-	printk("       devnum(%d) devpath(%s)", dev->devnum, dev->devpath);
-
-	switch(dev->speed) {
-		case USB_SPEED_HIGH :
-			printk(" SPD_HIGH");
-			break;
-		case USB_SPEED_FULL :
-			printk(" SPD_FULL");
-			break;
-		case USB_SPEED_LOW :
-			printk(" SPD_LOW");
-			break;
-		case USB_SPEED_UNKNOWN :
-			printk(" SPD_UNKNOWN");
-			break;
-		default :
-			printk(" SPD_ERROR");
-	}
-
-	printk(" tt %p, ttport %d", dev->tt, dev->ttport);
-	printk("\n");
-
-	printk("                    ");
-	for (i = 0; i < 16; i++) {
-		printk(" %2u", i);
-	}
-
-	printk("\n");
-
-	printk("       toggle0(IN) :");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[0] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-	printk("       toggle1(OUT):");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[1] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-
-	printk("       epmaxp_in   :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_in[i])
-			printk(" %2u",  dev->ep_in[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n");
-
-	printk("       epmaxp_out  :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_out[i])
-			printk(" %2u",  dev->ep_out[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n       ");
-
-	printk("parent %p, bus %p", dev->parent, dev->bus);
-	printk("\n       ");
-
-	printk("descriptor %p, config %p, actconfig %p, rawdescriptors %p",
-			&dev->descriptor, dev->config, dev->actconfig, dev->rawdescriptors);
-	printk("\n       ");
-
-	printk("have_langid %d, string_langid %d", dev->have_langid, dev->string_langid);
-	printk("\n       ");
-
-	printk("maxchild %d, children %p", dev->maxchild, dev->children);
-
-	printk("\n");
-}
-
-static void usbip_dump_request_type(__u8 rt)
-{
-	switch(rt & USB_RECIP_MASK) {
-		case USB_RECIP_DEVICE:
-			printk("DEVICE");
-			break;
-		case USB_RECIP_INTERFACE:
-			printk("INTERF");
-			break;
-		case USB_RECIP_ENDPOINT:
-			printk("ENDPOI");
-			break;
-		case USB_RECIP_OTHER:
-			printk("OTHER ");
-			break;
-		default:
-			printk("------");
-	}
-}
-
-static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
-{
-	if (!cmd) {
-		printk("      %s : null pointer\n", __FUNCTION__);
-		return;
-	}
-
-	printk("       ");
-	printk("bRequestType(%02X) ", cmd->bRequestType);
-	printk("bRequest(%02X) " , cmd->bRequest);
-	printk("wValue(%04X) ", cmd->wValue);
-	printk("wIndex(%04X) ", cmd->wIndex);
-	printk("wLength(%04X) ", cmd->wLength);
-
-	printk("\n       ");
-
-	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk("STANDARD ");
-		switch(cmd->bRequest) {
-			case USB_REQ_GET_STATUS:
-				printk("GET_STATUS");
-				break;
-			case USB_REQ_CLEAR_FEATURE:
-				printk("CLEAR_FEAT");
-				break;
-			case USB_REQ_SET_FEATURE:
-				printk("SET_FEAT  ");
-				break;
-			case USB_REQ_SET_ADDRESS:
-				printk("SET_ADDRRS");
-				break;
-			case USB_REQ_GET_DESCRIPTOR:
-				printk("GET_DESCRI");
-				break;
-			case USB_REQ_SET_DESCRIPTOR:
-				printk("SET_DESCRI");
-				break;
-			case USB_REQ_GET_CONFIGURATION:
-				printk("GET_CONFIG");
-				break;
-			case USB_REQ_SET_CONFIGURATION:
-				printk("SET_CONFIG");
-				break;
-			case USB_REQ_GET_INTERFACE:
-				printk("GET_INTERF");
-				break;
-			case USB_REQ_SET_INTERFACE:
-				printk("SET_INTERF");
-				break;
-			case USB_REQ_SYNCH_FRAME:
-				printk("SYNC_FRAME");
-				break;
-			default:
-				printk("REQ(%02X) ", cmd->bRequest);
-		}
-
-		printk(" ");
-		usbip_dump_request_type(cmd->bRequestType);
-
-	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk("CLASS   ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk("VENDOR  ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk("RESERVED");
-
-	printk("\n");
-}
-
-void usbip_dump_urb (struct urb *purb)
-{
-	if (!purb) {
-		printk("   dump urb: null pointer!!\n");
-		return;
-	}
-
-	printk("   urb                   :%p\n", purb);
-	printk("   dev                   :%p\n", purb->dev);
-
-	usbip_dump_usb_device(purb->dev);
-
-	printk("   pipe                  :%08x ", purb->pipe);
-
-	usbip_dump_pipe(purb->pipe);
-
-	printk("   status                :%d\n", purb->status);
-	printk("   transfer_flags        :%08X\n", purb->transfer_flags);
-	printk("   transfer_buffer       :%p\n", purb->transfer_buffer);
-	printk("   transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("   actual_length         :%d\n", purb->actual_length);
-	printk("   bandwidth             :%d\n", purb->actual_length);
-	printk("   setup_packet          :%p\n", purb->setup_packet);
-
-	if (purb->setup_packet && usb_pipetype(purb->pipe) == PIPE_CONTROL)
-		usbip_dump_usb_ctrlrequest((struct usb_ctrlrequest *) purb->setup_packet);
-
-	printk("   start_frame           :%d\n", purb->start_frame);
-	printk("   number_of_packets     :%d\n", purb->number_of_packets);
-	printk("   interval              :%d\n", purb->interval);
-	printk("   error_count           :%d\n", purb->error_count);
-	printk("   context               :%p\n", purb->context);
-	printk("   complete              :%p\n", purb->complete);
-}
-
-void usbip_dump_header(struct usbip_header *pdu)
-{
-	udbg("BASE: cmd %u bus %u dev %u seq %u pipe %04x\n",
-			pdu->base.command,
-			pdu->base.busnum,
-			pdu->base.devnum,
-			pdu->base.seqnum,
-			pdu->base.pipe);
-
-	usbip_dump_pipe(pdu->base.pipe);
-
-	switch(pdu->base.command) {
-		case USBIP_CMD_SUBMIT:
-			udbg("CMD_SUBMIT: x_flags %u x_len %u bw %u sf %u #p %u iv %u\n",
-					pdu->u.cmd_submit.transfer_flags,
-					pdu->u.cmd_submit.transfer_buffer_length,
-					pdu->u.cmd_submit.bandwidth,
-					pdu->u.cmd_submit.start_frame,
-					pdu->u.cmd_submit.number_of_packets,
-					pdu->u.cmd_submit.interval);
-					break;
-		case USBIP_CMD_UNLINK:
-			udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
-			break;
-		case USBIP_RET_SUBMIT:
-			udbg("RET_SUBMIT: st %d al %u bw %u sf %d ec %d\n",
-					pdu->u.ret_submit.status,
-					pdu->u.ret_submit.actual_length,
-					pdu->u.ret_submit.bandwidth,
-					pdu->u.ret_submit.start_frame,
-					pdu->u.ret_submit.error_count);
-		case USBIP_RET_UNLINK:
-			udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
-			break;
-		default:
-			/* NOT REACHED */
-			udbg("UNKNOWN\n");
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* thread routines */
-
-int usbip_thread(void *param)
-{
-	struct usbip_task *ut = (struct usbip_task *) 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);
-}
-
-void usbip_start_threads(struct usbip_device *ud)
-{
-	/*
-	 * threads are invoked per one device (per one connection).
-	 */
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_rx, 0);
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_tx, 0);
-
-	/* confirm threads are starting */
-	wait_for_completion(&ud->tcp_rx.thread_done);
-	wait_for_completion(&ud->tcp_tx.thread_done);
-}
-
-void usbip_stop_threads(struct usbip_device *ud)
-{
-        /* kill threads related to this sdev, if v.c. exists */
-	if (ud->tcp_rx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
-		wait_for_completion(&ud->tcp_rx.thread_done);
-		udbg("rx_thread for ud %p has finished\n", ud);
-	}
-
-	if (ud->tcp_tx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
-		wait_for_completion(&ud->tcp_tx.thread_done);
-		udbg("tx_thread for ud %p has finished\n", ud);
-	}
-}
-
-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;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* socket routines */
-
- /*  Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags)
-{
-	int result;
-	struct msghdr msg;
-	struct kvec iov;
-	int total = 0;
-
-	/* for blocks of if (dbg_flag_xmit) */
-	char *bp = buf;
-	int osize= size;
-
-	dbg_xmit("enter\n");
-
-	if (!sock || !buf || !size) {
-		uerr("usbip_xmit: invalid arg, sock %p buff %p size %d\n",
-				sock, buf, size);
-		return -EINVAL;
-	}
-
-
-	if (dbg_flag_xmit) {
-		if (send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: sending... , sock %p, buf %p, size %d, msg_flags %d\n",
-					sock, buf, size, msg_flags);
-			usbip_dump_buffer(buf, size);
-		}
-	}
-
-
-	do {
-		sock->sk->sk_allocation = GFP_NOIO;
-		iov.iov_base    = buf;
-		iov.iov_len     = size;
-		msg.msg_name    = NULL;
-		msg.msg_namelen = 0;
-		msg.msg_control = NULL;
-		msg.msg_controllen = 0;
-		msg.msg_namelen    = 0;
-		msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
-
-		if (send)
-			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
-		else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL);
-
-		if (result <= 0) {
-			udbg("usbip_xmit: %s sock %p buf %p size %u ret %d total %d\n",
-					send ? "send" : "receive", sock, buf, size, result, total);
-			goto err;
-		}
-
-		size -= result;
-		buf += result;
-		total += result;
-
-	} while (size > 0);
-
-
-	if (dbg_flag_xmit) {
-		if (!send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: receiving....\n");
-			usbip_dump_buffer(bp, osize);
-			printk("usbip_xmit: received, osize %d ret %d size %d total %d\n",
-					osize, result, size, total);
-		}
-
-		if (send) {
-			printk("usbip_xmit: send, total %d\n", total);
-		}
-	}
-
-	return total;
-
-err:
-	return result;
-}
-
-int setquickack(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-void setreuse(struct socket *socket)
-{
-	socket->sk->sk_reuse = 1;
-}
-
-struct socket *sockfd_to_socket(unsigned int sockfd)
-{
-	struct socket *socket;
-	struct file *file;
-	struct inode *inode;
-
-	file = fget(sockfd);
-	if (!file) {
-		uerr("invalid sockfd\n");
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-
-	if (!inode || !S_ISSOCK(inode->i_mode))
-		return NULL;
-
-	socket = SOCKET_I(inode);
-
-	return socket;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/* pdu routines */
-
-/* there may be more cases to tweak the flags. */
-static unsigned int tweak_transfer_flags(unsigned int flags)
-{
-
-	if (flags & URB_NO_TRANSFER_DMA_MAP)
-		/*
-		 * vhci_hcd does not provide DMA-mapped I/O. The upper
-		 * driver does not need to set this flag. The remote
-		 * usbip.ko does not still perform DMA-mapped I/O for
-		 * DMA-caplable host controllers. So, clear this flag.
-		 */
-		flags &= ~URB_NO_TRANSFER_DMA_MAP;
-
-	if (flags & URB_NO_SETUP_DMA_MAP)
-		flags &= ~URB_NO_SETUP_DMA_MAP;
-
-	return flags;
-}
-
-static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
-
-	/*
-	 * Some members are not still implemented in usbip. I hope this issue
-	 * will be discussed when usbip is ported to other operating systems.
-	 */
-	if (pack) {
-		/* vhci_tx.c */
-		spdu->transfer_flags		= tweak_transfer_flags(urb->transfer_flags);
-
-		spdu->transfer_buffer_length	= urb->transfer_buffer_length;
-		spdu->bandwidth			= urb->bandwidth;
-		spdu->start_frame		= urb->start_frame;
-		spdu->number_of_packets		= urb->number_of_packets;
-		spdu->interval			= urb->interval;
-	} else  {
-		/* stub_rx.c */
-		urb->transfer_flags         = spdu->transfer_flags;
-
-		urb->transfer_buffer_length = spdu->transfer_buffer_length;
-		urb->bandwidth              = spdu->bandwidth;
-		urb->start_frame            = spdu->start_frame;
-		urb->number_of_packets      = spdu->number_of_packets;
-		urb->interval               = spdu->interval;
-	}
-}
-
-static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
-
-	if (pack) {
-		/* stub_tx.c */
-
-		rpdu->status		= urb->status;
-		rpdu->actual_length	= urb->actual_length;
-		rpdu->bandwidth		= urb->bandwidth;
-		rpdu->start_frame	= urb->start_frame;
-		rpdu->error_count	= urb->error_count;
-	} else {
-		/* vhci_rx.c */
-
-		urb->status		= rpdu->status;
-		urb->actual_length	= rpdu->actual_length;
-		urb->bandwidth		= rpdu->bandwidth;
-		urb->start_frame	= rpdu->start_frame;
-		urb->error_count	= rpdu->error_count;
-	}
-}
-
-
-void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack)
-{
-	switch(cmd) {
-		case USBIP_CMD_SUBMIT:
-			usbip_pack_cmd_submit(pdu, urb, pack);
-			break;
-		case USBIP_RET_SUBMIT:
-			usbip_pack_ret_submit(pdu, urb, pack);
-			break;
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-
-
-static void correct_endian_basic(struct usbip_header_basic *base, int send)
-{
-	if (send) {
-		base->command	= cpu_to_be32(base->command);
-		base->busnum	= cpu_to_be32(base->busnum);
-		base->devnum	= cpu_to_be32(base->devnum);
-		base->seqnum	= cpu_to_be32(base->seqnum);
-		base->pipe	= cpu_to_be32(base->pipe);
-	} else {
-		base->command	= be32_to_cpu(base->command);
-		base->busnum	= be32_to_cpu(base->busnum);
-		base->devnum	= be32_to_cpu(base->devnum);
-		base->seqnum	= be32_to_cpu(base->seqnum);
-		base->pipe	= be32_to_cpu(base->pipe);
-	}
-}
-
-static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, int send)
-{
-	if (send) {
-		pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
-
-		cpu_to_be32s(&pdu->transfer_buffer_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->number_of_packets);
-		cpu_to_be32s(&pdu->interval);
-	} else {
-		pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags);
-
-		be32_to_cpus(&pdu->transfer_buffer_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->number_of_packets);
-		be32_to_cpus(&pdu->interval);
-	}
-}
-
-static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, int send)
-{
-	if (send) {
-		cpu_to_be32s(&pdu->status);
-		cpu_to_be32s(&pdu->actual_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->error_count);
-	} else {
-		be32_to_cpus(&pdu->status);
-		be32_to_cpus(&pdu->actual_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->error_count);
-	}
-}
-
-static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, int send)
-{
-	if (send)
-		pdu->seqnum = cpu_to_be32(pdu->seqnum);
-	else
-		pdu->seqnum = be32_to_cpu(pdu->seqnum);
-}
-
-static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, int send)
-{
-	if (send)
-		cpu_to_be32s(&pdu->status);
-	else
-		be32_to_cpus(&pdu->status);
-}
-
-void usbip_header_correct_endian(struct usbip_header *pdu, int send)
-{
-	__u32 cmd = 0;
-
-	if (send)
-		cmd = pdu->base.command;
-
-	correct_endian_basic(&pdu->base, send);
-
-	if (!send)
-		cmd = pdu->base.command;
-
-	switch (cmd) {
-		case USBIP_CMD_SUBMIT:
-			correct_endian_cmd_submit(&pdu->u.cmd_submit, send);
-			break;
-		case USBIP_RET_SUBMIT:
-			correct_endian_ret_submit(&pdu->u.ret_submit, send);
-			break;
-
-		case USBIP_CMD_UNLINK:
-			correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send);
-			break;
-		case USBIP_RET_UNLINK:
-			correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
-			break;
-
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-	
-static void usbip_iso_pakcet_correct_endian(struct usbip_iso_packet_descriptor *iso, int send)
-{
-	/* does not need all members. but copy all simply. */
-	if (send) {
-		iso->offset	= cpu_to_be32(iso->offset);
-		iso->length	= cpu_to_be32(iso->length);
-		iso->status	= cpu_to_be32(iso->status);
-		iso->actual_length = cpu_to_be32(iso->actual_length);
-	} else {
-		iso->offset	= be32_to_cpu(iso->offset);
-		iso->length	= be32_to_cpu(iso->length);
-		iso->status	= be32_to_cpu(iso->status);
-		iso->actual_length = be32_to_cpu(iso->actual_length);
-	}
-}
-
-static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
-		struct usb_iso_packet_descriptor *uiso, int pack)
-{
-	if (pack) {
-		iso->offset		= uiso->offset;
-		iso->length		= uiso->length;
-		iso->status		= uiso->status;
-		iso->actual_length	= uiso->actual_length;
-	} else {
-		uiso->offset		= iso->offset;
-		uiso->length		= iso->length;
-		uiso->status		= iso->status;
-		uiso->actual_length	= iso->actual_length;
-	}
-}
-
-
-/* must free buffer */
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	ssize_t size = np * sizeof(*iso);
-	int i;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return NULL;
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
-		usbip_iso_pakcet_correct_endian(iso, 1);
-	}
-
-	*bufflen = size;
-
-	return buff;
-}
-
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	int size = np * sizeof(*iso);
-	int i;
-	int ret;
-
-	if (!usb_pipeisoc(urb->pipe))
-		return 0;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-
-	ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
-	if (ret != size) {
-		uerr("recv iso_frame_descriptor, %d\n", ret);
-		kfree(buff);
-
-		if (ud->side == USBIP_STUB)
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		else
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-
-		return -EPIPE;
-	}
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_iso_pakcet_correct_endian(iso, 0);
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
-	}
-
-
-	kfree(buff);
-
-	return ret;
-}
-
-
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
-{
-	int ret;
-	int size;
-
-	if (ud->side == USBIP_STUB) {
-		/* stub_rx.c */
-		/* the direction of urb must be OUT. */
-		if (usb_pipein(urb->pipe))
-			return 0;
-
-		size = urb->transfer_buffer_length;
-	} else {
-		/* vhci_rx.c */
-		/* the direction of urb must be IN. */
-		if (usb_pipeout(urb->pipe))
-			return 0;
-
-		size = urb->actual_length;
-	}
-
-	/* no need to recv xbuff */
-	if (!(size > 0))
-		return 0;
-
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) urb->transfer_buffer, size, 0);
-	if (ret != size) {
-		uerr("recv xbuf, %d\n", ret);
-		if (ud->side == USBIP_STUB) {
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		} else {
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-			return -EPIPE;
-		}
-	}
-
-	return ret;
-}
diff -Naur usbip-0.1.4/drivers/2.6.15/usbip_common.h trunk/drivers/2.6.15/usbip_common.h
--- usbip-0.1.4/drivers/2.6.15/usbip_common.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,364 +0,0 @@
-/*
- * $Id: usbip_common.h 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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.
- */
-
-#ifndef  __VHCI_COMMON_H
-#define  __VHCI_COMMON_H
-
-
-#include <linux/usb.h>
-#include <net/sock.h>
-#include <asm/byteorder.h>
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * define macros to print messages
- */
-
-/**
- * udbg - print debug messages if CONFIG_USB_DEBUG is defined
- * @fmt:
- * @args:
- */
-
-#ifdef CONFIG_USB_DEBUG
-
-#define udbg(fmt, args...)						\
-	do{								\
-		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	}while(0)
-
-#else  /* CONFIG_USB_DEBUG */
-
-#define udbg(fmt, args...)		do{ }while(0)
-
-#endif /* CONFIG_USB_DEBUG */
-
-
-enum {
-	usbip_debug_xmit	= (1 << 0),
-	usbip_debug_sysfs	= (1 << 1),
-	usbip_debug_urb		= (1 << 2),
-	usbip_debug_eh		= (1 << 3),
-
-	usbip_debug_stub_cmp	= (1 << 8),
-	usbip_debug_stub_dev	= (1 << 9),
-	usbip_debug_stub_rx	= (1 << 10),
-	usbip_debug_stub_tx	= (1 << 11),
-
-	usbip_debug_vhci_rh	= (1 << 8),
-	usbip_debug_vhci_hc	= (1 << 9),
-	usbip_debug_vhci_rx	= (1 << 10),
-	usbip_debug_vhci_tx	= (1 << 11),
-	usbip_debug_vhci_sysfs  = (1 << 12)
-};
-
-#define dbg_flag_xmit		(usbip_debug_flag & usbip_debug_xmit)
-#define dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
-#define dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
-#define dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
-#define dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
-#define dbg_flag_vhci_sysfs	(usbip_debug_flag & usbip_debug_vhci_sysfs)
-#define dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
-#define dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
-
-extern unsigned long usbip_debug_flag;
-extern struct device_attribute dev_attr_usbip_debug;
-
-#define dbg_with_flag(flag, fmt, args...)		\
-	do {						\
-		if(flag & usbip_debug_flag) 		\
-			udbg(fmt , ##args);		\
-	} while(0)
-
-#define dbg_sysfs(fmt, args...)	dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define dbg_xmit(fmt, args...)	dbg_with_flag(usbip_debug_xmit,  fmt , ##args)
-#define dbg_urb(fmt, args...)	dbg_with_flag(usbip_debug_urb,   fmt , ##args)
-#define dbg_eh(fmt, args...)	dbg_with_flag(usbip_debug_eh,   fmt , ##args)
-
-#define dbg_vhci_rh(fmt, args...) dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
-#define dbg_vhci_hc(fmt, args...) dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
-#define dbg_vhci_rx(fmt, args...) dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
-#define dbg_vhci_tx(fmt, args...) dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define dbg_vhci_sysfs(fmt, args...) dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
-
-#define dbg_stub_cmp(fmt, args...) dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define dbg_stub_rx(fmt, args...) dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define dbg_stub_tx(fmt, args...) dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
-
-
-/**
- * uerr - print error messages
- * @fmt:
- * @args:
- */
-#define uerr(fmt, args...)						\
-	do {								\
-		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	} while(0)
-
-/**
- * uinfo - print information messages
- * @fmt:
- * @args:
- */
-#define uinfo(fmt, args...)					\
-	do {							\
-		printk(KERN_INFO "usbip: " fmt , ## args);	\
-	} while(0)
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * USB/IP packet headers.
- * At now, we define 4 packet types:
- *
- *  - CMD_SUBMIT transfers a USB request. This is corresponding to usb_submit_urb().
- *  - RET_RETURN transfers a result of a USB request.
- *  - CMD_UNLINK transfers an unlink request of a pending USB request.
- *  - RET_UNLINK transfers an unlink request of a pending USB request.
- *
- * TODO:
- *
- *  - inter-operability between other OSs
- */
-
-/*
- * A basic header followed by other additional headers.
- */
-struct usbip_header_basic {
-#define USBIP_CMD_SUBMIT	0x0001
-#define USBIP_CMD_UNLINK	0x0002
-#define USBIP_RET_SUBMIT	0x0003
-#define USBIP_RET_UNLINK	0x0004
-	__u32 command;
-
-	__u32 busnum;
-	__u32 devnum;
-	__u32 seqnum; /* seaquencial number which identifies URBs */
-	__u32 pipe;
-} __attribute__ ((packed));
-
-/*
- * An additional header for a CMD_SUBMIT packet.
- */
-struct usbip_header_cmd_submit {
-	__u32 transfer_flags;
-	__s32 transfer_buffer_length;
-	__s32 bandwidth;
-	__s32 start_frame;
-	__s32 number_of_packets;
-	__s32 interval;
-	unsigned char setup[8]; /* CTRL only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a RET_SUBMIT packet.
- */
-struct usbip_header_ret_submit {
-	__s32 status;
-	__s32 actual_length; /* returned data length */
-	__s32 bandwidth;
-	__s32 start_frame; /* ISO and INT */
-	__s32 number_of_packets;  /* ISO only */
-	__s32 error_count; /* ISO only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a CMD_UNLINK packet.
- */
-struct usbip_header_cmd_unlink {
-	__u32 seqnum; /* URB's seqnum which will be unlinked */
-}__attribute__ ((packed));
-
-
-/*
- * An additional header for a RET_UNLINK packet.
- */
-struct usbip_header_ret_unlink {
-	__s32 status;
-}__attribute__ ((packed));
-
-
-/* the same as usb_iso_packet_descriptor but packed for pdu */
-struct usbip_iso_packet_descriptor {
-	__u32 offset;
-	__u32 length;            /* expected length */
-	__u32 actual_length;
-	__u32 status;
-}__attribute__ ((packed));
-
-
-/*
- * All usbip packets use a common header to keep code simple.
- */
-struct usbip_header {
-	struct usbip_header_basic base;
-
-	union {
-		struct usbip_header_cmd_submit	cmd_submit;
-		struct usbip_header_ret_submit	ret_submit;
-		struct usbip_header_cmd_unlink	cmd_unlink;
-		struct usbip_header_ret_unlink	ret_unlink;
-	} u;
-}__attribute__ ((packed));
-
-
-
-
-/*-------------------------------------------------------------------------*/
-
-
-int usbip_xmit(int , struct socket *, char *, int , int );
-int usbip_sendmsg(struct socket *, struct msghdr *, int );
-
-
-static inline int interface_to_busnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->bus->busnum;
-}
-
-static inline int interface_to_devnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->devnum;
-}
-
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
-	return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-struct socket *sockfd_to_socket(unsigned int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-
-
-void usbip_dump_urb (struct urb *purb);
-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,
-};
-
-enum usbip_status {
-	/* sdev is available. */
-	SDEV_ST_AVAILABLE = 0x01,
-	/* sdev is now used. */
-	SDEV_ST_USED,
-	/* sdev is unusable because of a fatal error. */
-	SDEV_ST_ERROR,
-
-	/* vdev does not connect a remote device. */
-	VDEV_ST_NULL,
-	/* vdev is used, but the USB address is not assigned yet */
-	VDEV_ST_NOTASSIGNED,
-	VDEV_ST_USED,
-	VDEV_ST_ERROR
-};
-
-/* a common structure for stub_device and vhci_device */
-struct usbip_device{
-	enum usbip_side side;
-
-	enum usbip_status status;
-
-	/* lock for status */
-	spinlock_t lock;
-
-	struct socket *tcp_socket;
-
-	struct usbip_task tcp_rx;
-	struct usbip_task tcp_tx;
-
-	/* event handler */
-#define USBIP_EH_SHUTDOWN	(1 << 0)
-#define USBIP_EH_BYE		(1 << 1)
-#define USBIP_EH_RESET		(1 << 2)
-#define USBIP_EH_UNUSABLE	(1 << 3)
-
-#define SDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
-#define	SDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_SUBMIT		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE )
-
-#define	VDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
-#define	VDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
-
-	unsigned long event;
-	struct usbip_task eh;
-	wait_queue_head_t eh_waitq;
-
-	struct eh_ops {
-		void (*shutdown)(struct usbip_device *);
-		void (*reset)(struct usbip_device *);
-		void (*unusable)(struct usbip_device *);
-	} eh_ops;
-};
-
-
-void usbip_task_init(struct usbip_task *ut, char *, void (*loop_ops)(struct usbip_task *));
-
-void 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);
-void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
-
-
-/* usbip_event.c */
-void usbip_start_eh(struct usbip_device *ud);
-void usbip_stop_eh(struct usbip_device *ud);
-void usbip_event_add(struct usbip_device *ud, unsigned long event);
-int usbip_event_happend(struct usbip_device *ud);
-
-
-#endif
diff -Naur usbip-0.1.4/drivers/2.6.15/usbip_event.c trunk/drivers/2.6.15/usbip_event.c
--- usbip-0.1.4/drivers/2.6.15/usbip_event.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/usbip_event.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,153 +0,0 @@
-/*
- * $Id: usbip_event.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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 void event_handler_loop(struct usbip_task *eh);
-
-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((int(*)(void *)) usbip_thread, (void *) eh, 0);
-
-	wait_for_completion(&eh->thread_done);
-}
-
-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");
-}
-
-
-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);
-}
-
-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;
-}
-
-
-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 */
-		uerr("unknown event\n");
-		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");
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.15/vhci.h trunk/drivers/2.6.15/vhci.h
--- usbip-0.1.4/drivers/2.6.15/vhci.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/vhci.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,143 +0,0 @@
-/*
- * $Id: vhci.h 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/platform_device.h>
-#include HCD_HEADER
-
-
-struct vhci_device {
-	struct usb_device *udev;
-
-	/* busnum and devnum of a remote device */
-	__u32 busnum;
-	__u32 devnum;
-
-	/* speed of a remote device */
-	enum usb_device_speed speed;
-
-	/*  vhci root-hub port to which this device is attached  */
-	__u32 rhport;
-
-	struct usbip_device ud;
-
-
-	/* lock for the below link lists */
-	spinlock_t priv_lock;
-
-	/* vhci_priv is linked to one of them. */
-	struct list_head priv_tx;
-	struct list_head priv_rx;
-
-	/* vhci_unlink is linked to one of them */
-	struct list_head unlink_tx;
-	struct list_head unlink_rx;
-
-	/* vhci_tx thread sleeps for this queue */
-	wait_queue_head_t waitq_tx;
-};
-
-
-/* urb->hcpriv, use container_of() */
-struct vhci_priv {
-	unsigned long seqnum;
-	struct list_head list;
-
-	struct vhci_device *vdev;
-	struct urb *urb;
-};
-
-
-struct vhci_unlink {
-	/* seqnum of this request */
-	unsigned long seqnum;
-
-	struct list_head list;
-
-	/* seqnum of the unlink target */
-	unsigned long unlink_seqnum;
-};
-
-/*
- * The number of ports is less than 16 ?
- * USB_MAXCHILDREN is statically defined to 16 in usb.h.  Its maximum value
- * would be 31 because the event_bits[1] of struct usb_hub is defined as
- * unsigned long in hub.h
- */
-#define VHCI_NPORTS 8
-
-/* for usb_bus.hcpriv */
-struct vhci_hcd {
-	spinlock_t	lock;
-
-	u32	port_status[VHCI_NPORTS];
-
-	unsigned	resuming:1;
-	unsigned long	re_timeout;
-
-	atomic_t seqnum;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 * But, the index of this array begins from 0.
-	 */
-	struct vhci_device vdev[VHCI_NPORTS];
-
-	/* vhci_device which has not been assiged its address yet */
-	int pending_port;
-};
-
-
-extern struct vhci_hcd *the_controller;
-extern struct attribute_group dev_attr_group;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declaration */
-
-/* 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);
-
-#define hardware		(&the_controller->pdev.dev)
-
-static inline struct vhci_device *port_to_vdev(__u32 port)
-{
-	return &the_controller->vdev[port];
-}
-
-static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd)
-{
-	return (struct vhci_hcd *) (hcd->hcd_priv);
-}
-
-static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci)
-{
-	return container_of((void *) vhci, struct usb_hcd, hcd_priv);
-}
-
-static inline struct device *vhci_dev(struct vhci_hcd *vhci)
-{
-	return vhci_to_hcd(vhci)->self.controller;
-}
diff -Naur usbip-0.1.4/drivers/2.6.15/vhci_hcd.c trunk/drivers/2.6.15/vhci_hcd.c
--- usbip-0.1.4/drivers/2.6.15/vhci_hcd.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/vhci_hcd.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1174 +0,0 @@
-/*
- * $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-#define DRIVER_VERSION " $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $ "
-#define DRIVER_AUTHOR "HIROFUCHI Takahiro <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
-#define DRIVER_LICENCE "GPL"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENCE);
-
-
-
-/*
- * TODO
- * 	- update root hub emulation
- * 	- move the emulation code to userland ?
- * 		poring to other operating systems
- * 		minimize kernel code
- * 	- add suspend/resume code
- * 	- clean up everything
- */
-
-
-/* See usb gadget dummy hcd */
-
-
-static int vhci_hub_status (struct usb_hcd *hcd, char *buff);
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buff, u16 wLength);
-static int vhci_urb_enqueue (struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags);
-static int vhci_urb_dequeue( struct usb_hcd *hcd, struct urb *urb);
-static int vhci_start(struct usb_hcd *vhci_hcd);
-static void vhci_stop(struct usb_hcd *hcd);
-static int vhci_get_frame_number(struct usb_hcd *hcd);
-
-static const char driver_name[] = "vhci_hcd";
-static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
-
-
-
-
-struct vhci_hcd *the_controller = NULL;
-
-
-static const char *bit_desc[] = {
-	"CONNECTION",		/*0*/
-	"ENABLE",		/*1*/
-	"SUSPEND",		/*2*/
-	"OVER_CURRENT",		/*3*/
-	"RESET",		/*4*/
-	"R5",		/*5*/
-	"R6",		/*6*/
-	"R7",		/*7*/
-	"POWER",		/*8*/
-	"LOWSPEED",		/*9*/
-	"HIGHSPEED",		/*10*/
-	"PORT_TEST",		/*11*/
-	"INDICATOR",		/*12*/
-	"R13",		/*13*/
-	"R14",		/*14*/
-	"R15",		/*15*/
-	"C_CONNECTION",		/*16*/
-	"C_ENABLE",		/*17*/
-	"C_SUSPEND",		/*18*/
-	"C_OVER_CURRENT",	/*19*/
-	"C_RESET",		/*20*/
-	"R21",		/*21*/
-	"R22",		/*22*/
-	"R23",		/*23*/
-	"R24",		/*24*/
-	"R25",		/*25*/
-	"R26",		/*26*/
-	"R27",		/*27*/
-	"R28",		/*28*/
-	"R29",		/*29*/
-	"R30",		/*30*/
-	"R31",		/*31*/
-};
-
-
-static void dump_port_status(u32 status)
-{
-	int i = 0;
-
-	printk("status %08x:", status);
-	for (i = 0; i < 32; i++) {
-		if (status & (1 << i)) {
-			printk(" %s", bit_desc[i]);
-		}
-	}
-
-	printk("\n");
-}
-
-
-
-void rh_port_connect(int rhport, enum usb_device_speed speed)
-{
-	unsigned long	flags;
-
-	dbg_vhci_rh("rh_port_connect %d\n", rhport);
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
-		| (1 << USB_PORT_FEAT_C_CONNECTION);
-
-	switch (speed) {
-		case USB_SPEED_HIGH:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-			break;
-		case USB_SPEED_LOW:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-			break;
-		default:
-			break;
-	}
-
-	//spin_lock(&the_controller->vdev[rhport].ud.lock);
-	//the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
-	//spin_unlock(&the_controller->vdev[rhport].ud.lock);
-
-	the_controller->pending_port = rhport;
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-}
-
-void rh_port_disconnect(int rhport)
-{
-	unsigned long flags;
-
-	dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-	//stop_activity (dum, driver);
-	the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
-	the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION);
-
-
-	/* not yet complete the disconnection */
-	//spin_lock(&vdev->ud.lock);
-	//vdev->ud.status = VHC_ST_DISCONNECT;
-	//spin_unlock(&vdev->ud.lock);
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-#define PORT_C_MASK \
-	((USB_PORT_STAT_C_CONNECTION \
-	  | USB_PORT_STAT_C_ENABLE \
-	  | USB_PORT_STAT_C_SUSPEND \
-	  | USB_PORT_STAT_C_OVERCURRENT \
-	  | USB_PORT_STAT_C_RESET) << 16)
-
-/*
- * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without
- * suspend/resume support. But, it is modified to provide multiple ports.
- *
- * @buf: a bitmap to show which port status has been changed.
- *  bit  0: reserved or used for another purpose?
- *  bit  1: the status of port 0 has been changed.
- *  bit  2: the status of port 1 has been changed.
- *  ...
- *  bit  7: the status of port 6 has been changed.
- *  bit  8: the status of port 7 has been changed.
- *  ...
- *  bit 15: the status of port 14 has been changed.
- *
- * So, the maximum number of ports is 31 ( port 0 to port 30) ?
- *
- * The return value is the actual transfered length in byte. If nothing has
- * been changed, return 0. In the case that the number of ports is less than or
- * equal to 6 (VHCI_NPORTS==7), return 1.
- *
- */
-static int vhci_hub_status (struct usb_hcd *hcd, char *buf)
-{
-	struct vhci_hcd	*vhci;
-	unsigned long	flags;
-	int		retval = 0;
-
-	/* the enough buffer is allocated according to USB_MAXCHILDREN */
-	unsigned long	*event_bits = (unsigned long *) buf;
-	int		rhport;
-	int		changed = 0;
-
-
-	*event_bits = 0;
-
-	vhci = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&vhci->lock, flags);
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		dbg_vhci_rh("hw accessible flag in on?\n");
-		goto done;
-	}
-
-	/* check pseudo status register for each port */
-	for(rhport = 0; rhport < VHCI_NPORTS; rhport++) {
-		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
-			/* The status of a port has been changed, */
-			dbg_vhci_rh("port %d is changed\n", rhport);
-
-			*event_bits |= 1 << ( rhport + 1);
-			changed = 1;
-		}
-	}
-
-	if (changed)
-		retval = 1 + (VHCI_NPORTS / 8);
-	else
-		retval = 0;
-
-done:
-	spin_unlock_irqrestore (&vhci->lock, flags);
-	return retval;
-}
-
-/* See hub_configure in hub.c */
-static inline void hub_descriptor(struct usb_hub_descriptor *desc)
-{
-	memset(desc, 0, sizeof(*desc));
-	desc->bDescriptorType = 0x29;
-	desc->bDescLength = 9;
-	desc->wHubCharacteristics = (__force __u16)
-		(__constant_cpu_to_le16 (0x0001));
-	desc->bNbrPorts = VHCI_NPORTS;
-	desc->bitmap [0] = 0xff;
-	desc->bitmap [1] = 0xff;
-}
-
-
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
-{
-	struct vhci_hcd	*dum;
-	int             retval = 0;
-	unsigned long   flags;
-	int		rhport;
-
-	u32 prev_port_status[VHCI_NPORTS];
-
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
-		return -ETIMEDOUT;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 */
-	dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex);
-	if (wIndex > VHCI_NPORTS)
-		uerr("invalid port number %d\n", wIndex);
-	rhport = ((__u8 ) (wIndex & 0x00ff)) -1;
-
-	dum = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&dum->lock, flags);
-
-	/* store old status and compare now and old later */
-	if (dbg_flag_vhci_rh) {
-		int i = 0;
-		for (i = 0; i < VHCI_NPORTS; i++)
-			prev_port_status[i] = dum->port_status[i];
-	}
-
-	switch (typeReq) {
-		case ClearHubFeature:
-			dbg_vhci_rh(" ClearHubFeature\n");
-			break;
-		case ClearPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					if (dum->port_status[rhport] & (1 << USB_PORT_FEAT_SUSPEND)) {
-						/* 20msec signaling */
-						dum->resuming = 1;
-						dum->re_timeout = jiffies + msecs_to_jiffies(20);
-					}
-					break;
-				case USB_PORT_FEAT_POWER:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
-					dum->port_status[rhport] = 0;
-					//dum->address = 0;
-					//dum->hdev = 0;
-					dum->resuming = 0;
-					break;
-				case USB_PORT_FEAT_C_RESET:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_C_RESET\n");
-					switch (dum->vdev[rhport].speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							break;
-					}
-				default:
-					dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
-					dum->port_status[rhport] &= ~(1 << wValue);
-			}
-			break;
-		case GetHubDescriptor:
-			dbg_vhci_rh(" GetHubDescriptor\n");
-			hub_descriptor ((struct usb_hub_descriptor *) buf);
-			break;
-		case GetHubStatus:
-			dbg_vhci_rh(" GetHubStatus\n");
-			*(u32 *) buf = __constant_cpu_to_le32 (0);
-			break;
-		case GetPortStatus:
-			dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
-			if (wIndex > VHCI_NPORTS || wIndex < 1) {
-				uerr(" invalid port number %d\n", wIndex);
-				retval = -EPIPE;
-			}
-
-			/* we do no care of resume. */
-
-			/* whoever resets or resumes must GetPortStatus to
-			 * complete it!!
-			 *                                   */
-			if (dum->resuming && time_after (jiffies, dum->re_timeout)) {
-				uerr(" not yet\n");
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_SUSPEND);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_SUSPEND);
-				dum->resuming = 0;
-				dum->re_timeout = 0;
-				//if (dum->driver && dum->driver->resume) {
-				//	spin_unlock (&dum->lock);
-				//	dum->driver->resume (&dum->gadget);
-				//	spin_lock (&dum->lock);
-				//}
-			}
-
-			if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != 0
-					&& time_after (jiffies, dum->re_timeout)) {
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_RESET);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_RESET);
-				dum->re_timeout = 0;
-
-				if (dum->vdev[rhport].ud.status == VDEV_ST_NOTASSIGNED) {
-					dbg_vhci_rh(" enable rhport %d (status %u)\n", rhport, dum->vdev[rhport].ud.status);
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-				}
-#if 0
-				if (dum->driver) {
-
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-					/* give it the best speed we agree on */
-					dum->gadget.speed = dum->driver->speed;
-					dum->gadget.ep0->maxpacket = 64;
-					switch (dum->gadget.speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->gadget.ep0->maxpacket = 8;
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							dum->gadget.speed = USB_SPEED_FULL;
-							break;
-					}
-				}
-#endif
-
-			}
-			((u16 *) buf)[0] = cpu_to_le16 (dum->port_status[rhport]);
-			((u16 *) buf)[1] = cpu_to_le16 (dum->port_status[rhport] >> 16);
-
-			dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], ((u16 *)buf)[1] );
-			break;
-		case SetHubFeature:
-			dbg_vhci_rh(" SetHubFeature\n");
-			retval = -EPIPE;
-			break;
-		case SetPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_SUSPEND\n");
-					uerr(" not yet\n");
-#if 0
-					dum->port_status[rhport] |= (1 << USB_PORT_FEAT_SUSPEND);
-					if (dum->driver->suspend) {
-						spin_unlock (&dum->lock);
-						dum->driver->suspend (&dum->gadget);
-						spin_lock (&dum->lock);
-					}
-#endif
-					break;
-				case USB_PORT_FEAT_RESET:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
-					/* if it's already running, disconnect first */
-					if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
-						dum->port_status[rhport] &= ~(USB_PORT_STAT_ENABLE
-								| USB_PORT_STAT_LOW_SPEED
-								| USB_PORT_STAT_HIGH_SPEED);
-#if 0
-						if (dum->driver) {
-							dev_dbg (hardware, "disconnect\n");
-							stop_activity (dum, dum->driver);
-						}
-#endif
-
-						/* FIXME test that code path! */
-					}
-					/* 50msec reset signaling */
-					dum->re_timeout = jiffies + msecs_to_jiffies(50);
-
-					/* FALLTHROUGH */
-				default:
-					dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
-					dum->port_status[rhport] |= (1 << wValue);
-			}
-			break;
-
-		default:
-			uerr(" default: no such request\n");
-			//dev_dbg (hardware,
-			//		"hub control req%04x v%04x i%04x l%d\n",
-			//		typeReq, wValue, wIndex, wLength);
-
-			/* "protocol stall" on error */
-			retval = -EPIPE;
-	}
-
-	if (dbg_flag_vhci_rh) {
-		printk("port %d\n", rhport);
-		dump_port_status(prev_port_status[rhport]);
-		dump_port_status(dum->port_status[rhport]);
-	}
-	dbg_vhci_rh(" bye\n");
-
-	spin_unlock_irqrestore (&dum->lock, flags);
-
-	return retval;
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-static struct vhci_device *get_vdev(struct usb_device *udev)
-{
-	int i;
-
-	if (!udev)
-		return NULL;
-
-	for (i=0; i < VHCI_NPORTS; i++)
-		if (the_controller->vdev[i].udev == udev)
-			return port_to_vdev(i);
-
-	return NULL;
-}
-
-static void vhci_tx_urb(struct urb *urb)
-{
-	struct vhci_device *vdev = get_vdev(urb->dev);
-	struct vhci_priv *priv;
-	unsigned long flag;
-
-	if (!vdev)
-		BUG();
-
-	spin_lock_irqsave(&vdev->priv_lock, flag);
-
-	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
-	if (!priv) {
-		uerr("malloc vhci_priv\n");
-		spin_unlock_irqrestore(&vdev->priv_lock, flag);
-		usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
-	if (priv->seqnum == 0xffff)
-		uinfo("seqnum max\n");
-
-	priv->vdev = vdev;
-	priv->urb = urb;
-
-	urb->hcpriv = (void *) priv;
-
-
-	list_add_tail(&priv->list, &vdev->priv_tx);
-
-	wake_up(&vdev->waitq_tx);
-	spin_unlock_irqrestore(&vdev->priv_lock, flag);
-}
-
-static int vhci_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags);
-
-
-
-	/* patch to usb_sg_init() is in 2.5.60 */
-	BUG_ON (!urb->transfer_buffer && urb->transfer_buffer_length);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-
-	/* check HC is active or not */
-	if (!HC_IS_RUNNING(hcd->state)) {
-		uerr("HC is not running\n");
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return  -ENODEV;
-	}
-
-	if (urb->status != -EINPROGRESS) {
-		uerr("URB already unlinked!, status %d\n", urb->status);
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return urb->status;
-	}
-
-	/*
-	 * The enumelation process is as follows;
-	 *
-	 *  1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
-	 *     to get max packet length of default pipe
-	 *
-	 *  2. Set_Address request to DevAddr(0) EndPoint(0)
-	 *
-	 */
-
-	if (usb_pipedevice(urb->pipe) == 0) {
-		__u8 type = usb_pipetype(urb->pipe);
-		struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet;
-		struct vhci_device *vdev = port_to_vdev(the_controller->pending_port);
-
-		if (type != PIPE_CONTROL || !ctrlreq ) {
-			uerr("invalid request to devnum 0\n");
-			ret = EINVAL;
-			goto no_need_xmit;
-		}
-
-		switch (ctrlreq->bRequest) {
-
-			case USB_REQ_SET_ADDRESS:
-				vdev->udev = urb->dev;
-				dbg_vhci_hc("SetAddress Request (%d) to port %d\n",
-						ctrlreq->wValue, vdev->rhport);
-
-				spin_lock(&vdev->ud.lock);
-				vdev->ud.status = VDEV_ST_USED;
-				spin_unlock(&vdev->ud.lock);
-
-				spin_lock (&urb->lock);
-				if (urb->status == -EINPROGRESS) {
-					/* This request is successfully completed. */
-					/* If not -EINPROGRESS, possibly unlinked. */
-					urb->status = 0;
-				}
-				spin_unlock (&urb->lock);
-
-				goto no_need_xmit;
-
-			case USB_REQ_GET_DESCRIPTOR:
-				if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
-					dbg_vhci_hc("Not yet?: Get_Descriptor to device 0 (get max pipe size)\n");
-
-				vdev->udev = urb->dev;
-				goto out;
-
-			default:
-				/* NOT REACHED */
-				uerr("invalid request to devnum 0 bRequest %u, wValue %u\n",
-						ctrlreq->bRequest, ctrlreq->wValue);
-				ret =  -EINVAL;
-				goto no_need_xmit;
-		}
-
-	}
-
-out:
-
-
-	vhci_tx_urb(urb);
-
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-
-	return 0;
-
-
-no_need_xmit:
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-	return 0;
-}
-
-
-/*
- * vhci_rx gives back the urb after recieving the reply of the urb.  If an
- * unlink pdu is sent or not, vhci_rx recieves a normal return pdu and gives
- * back its urb. For the driver unlinking the urb, the content of the urb is
- * not important, but the calling to its completion handler is important; the
- * completion of unlinking is notified by the completion handler.
- *
- *
- * CLIENT SIDE
- *
- * - When vhci_hcd recieves RET_SUBMIT,
- *
- *	- case 1a). the urb of the pdu is not unlinking.
- *		- normal case
- *		=> just give back the urb
- *
- *	- case 1b). the urb of the pdu is unlinking.
- *		- usbip.ko will return a reply of the unlinking request.
- *		=> give back the urb now and go to case 2b).
- *
- * - When vhci_hcd recieves RET_UNLINK,
- *
- *   	- case 2a). a submit request is still pending in vhci_hcd.
- *   		- urb was really pending in usbip.ko and urb_unlink_urb() was
- *   		  completed there.
- *   		=> free a pending submit request
- *   		=> notify unlink completeness by giving back the urb
- *
- *   	- case 2b). a submit request is *not* pending in vhci_hcd.
- *   		- urb was already given back to the core driver.
- *   		=> do not give back the urb
- *
- *
- * SERVER SIDE
- *
- * - When usbip recieves CMD_UNLINK,
- *
- *	- case 3a). the urb of the unlink request is now in submission.
- *		=> do usb_unlink_urb().
- *		=> after the unlink is completed, send RET_UNLINK.
- *
- *	- case 3b). the urb of the unlink request is not in submission.
- *		- may be already completed or never be recieved
- *		=> send RET_UNLINK
- *
- */
-static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-{
-	unsigned long flags;
-	struct vhci_priv *priv;
-	struct vhci_device *vdev;
-
-	uinfo("vhci_hcd: dequeue a urb %p\n", urb);
-
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	priv = urb->hcpriv;
-	if (!priv) {
-		/* URB was never linked! or will be soon given back by vhci_rx. */
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return 0;
-	}
-
-	 /* send unlink request here? */
-	vdev = priv->vdev;
-
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		unsigned long flags2;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
-		list_del(&priv->list);
-		kfree(priv);
-		urb->hcpriv = NULL;
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-
-	} else {
-		/* tcp connection is alive */
-		unsigned long flags2;
-		struct vhci_unlink *unlink;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		/* setup CMD_UNLINK pdu */
-		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
-		if (!unlink) {
-			uerr("malloc vhci_unlink\n");
-			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-			spin_unlock_irqrestore(&the_controller->lock, flags);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-			return -ENOMEM;
-		}
-
-		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
-		if (unlink->seqnum == 0xffff)
-			uinfo("seqnum max\n");
-
-		unlink->unlink_seqnum = priv->seqnum;
-
-		uinfo("vhci_hcd: device %p seems to be still connected\n", vdev);
-
-		/* send cmd_unlink and try to cancel the pending URB in the peer */
-		list_add_tail(&unlink->list, &vdev->unlink_tx);
-		wake_up(&vdev->waitq_tx);
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-	}
-	
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-	/*
-	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will recieve RET_UNLINK and giveb back the URB.
-	 * Otherwise, we give back it here.
-	 */
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	dbg_vhci_hc("leave\n");
-	return 0;
-}
-
-
-static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock(&vdev->priv_lock);
-}
-
-/*
- * The important thing is that only one context begins cleanup.
- * This is why error handling and cleanup become simple.
- * We do not want to consider race condition as possible.
- */
-static void vhci_shutdown_connection(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	/* need this? see stub_dev.c */
-	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	usbip_stop_threads(&vdev->ud);
-	uinfo("stop threads\n");
-
-	/* active connection is closed */
-	if (vdev->ud.tcp_socket != NULL) {
-		sock_release(vdev->ud.tcp_socket);
-		vdev->ud.tcp_socket = NULL;
-	}
-	uinfo("release socket\n");
-
-	vhci_device_unlink_cleanup(vdev);
-
-	/*
-	 * rh_port_disconnect() is a trigger of ...
-	 *   usb_disable_device():
-	 * 	disable all the endpoints for a USB device.
-	 *   usb_disable_endpoint():
-	 * 	disable endpoints. pending urbs are unlinked(dequeued).
-	 *
-	 * NOTE: After calling rh_port_disconnect(), the USB device driver of a
-	 * deteched device should release used urbs in a cleanup function(i.e.
-	 * xxx_disconnect()). Therefore, vhci_hcd does not need to release
-	 * pushed urbs and their private data in this function.
-	 *
-	 * NOTE: vhci_dequeue() must be considered carefully. When shutdowning
-	 * a connection, vhci_shutdown_connection() expects vhci_dequeue()
-	 * gives back pushed urbs and frees their private data by request of
-	 * the cleanup function of a USB driver. When unlinking a urb with an
-	 * active connection, vhci_dequeue() does not give back the urb which
-	 * is actually given back by vhci_rx after recieving its return pdu.
-	 *
-	 */
-	rh_port_disconnect(vdev->rhport);
-
-	uinfo("disconnect device\n");
-}
-
-
-static void vhci_device_reset(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	spin_lock(&ud->lock);
-
-	vdev->busnum = 0;
-	vdev->devnum = 0;
-	vdev->speed  = 0;
-
-	ud->tcp_socket = NULL;
-
-	ud->status = VDEV_ST_NULL;
-
-	spin_unlock(&ud->lock);
-}
-
-static void vhci_device_unusable(struct usbip_device* ud)
-{
-	spin_lock(&ud->lock);
-
-	ud->status = VDEV_ST_ERROR;
-
-	spin_unlock(&ud->lock);
-}
-
-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.side   = USBIP_VHCI;
-	vdev->ud.status = VDEV_ST_NULL;
-	vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
-
-	INIT_LIST_HEAD(&vdev->priv_rx);
-	INIT_LIST_HEAD(&vdev->priv_tx);
-	INIT_LIST_HEAD(&vdev->unlink_tx);
-	INIT_LIST_HEAD(&vdev->unlink_rx);
-	vdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	init_waitqueue_head(&vdev->waitq_tx);
-
-	vdev->ud.eh_ops.shutdown = vhci_shutdown_connection;
-	vdev->ud.eh_ops.reset = vhci_device_reset;
-	vdev->ud.eh_ops.unusable= vhci_device_unusable;
-
-	usbip_start_eh(&vdev->ud);
-}
-
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_start(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport;
-
-	dbg_vhci_hc("enter vhci_start\n");
-
-
-	/* initialize private data of usb_hcd */
-
-	for(rhport=0; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-		vhci_device_init(vdev);
-		vdev->rhport = rhport;
-	}
-
-	atomic_set(&vhci->seqnum, 0);
-	spin_lock_init(&vhci->lock);
-
-
-
-	//hcd->power_budget = 0; /* no limit ? */
-	hcd->state  = HC_STATE_RUNNING;
-	//hcd->uses_new_polling = 1;
-
-
-	/* vhci_hcd is now ready to be controlled through sysfs */
-	sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	return 0;
-}
-
-static void vhci_stop(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport = 0;
-
-	dbg_vhci_hc("stop VHCI controller\n");
-
-
-	/* 1. remove the userland interface of vhci_hcd */
-	sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	/* 2. shutdown all the ports of vhci_hcd */
-	for(rhport = 0 ; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-
-		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
-		usbip_stop_eh(&vdev->ud);
-	}
-
-
-	uinfo("vhci_stop done\n");
-}
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_get_frame_number(struct usb_hcd *hcd)
-{
-	uerr("Not yet implemented\n");
-	return 0;
-}
-
-
-#ifdef  CONFIG_PM
-
-static int vhci_bus_suspend(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-static int vhci_bus_resume(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-#else
-
-#define vhci_bus_suspend      NULL
-#define vhci_bus_resume       NULL
-#endif
-
-
-
-static struct hc_driver vhci_hc_driver = {
-	.description	= driver_name,
-	.product_desc	= driver_desc,
-	.hcd_priv_size	= sizeof(struct vhci_hcd),
-
-	.flags		= HCD_USB2,
-
-	.start		= vhci_start,
-	.stop 		= vhci_stop,
-
-	.urb_enqueue	= vhci_urb_enqueue,
-	.urb_dequeue	= vhci_urb_dequeue,
-
-	.get_frame_number = vhci_get_frame_number,
-
-	.hub_status_data = vhci_hub_status,
-	.hub_control    = vhci_hub_control,
-	.bus_suspend	= vhci_bus_suspend,
-	.bus_resume	= vhci_bus_resume,
-};
-
-static int vhci_hcd_probe(struct platform_device *pdev)
-{
-	struct usb_hcd		*hcd;
-	int			ret;
-
-	uinfo("proving...\n");
-
-	dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
-
-
-	/* will be removed */
-	if (pdev->dev.dma_mask) {
-		info("vhci_hcd DMA not supported\n");
-		return -EINVAL;
-	}
-
-
-	/*
-	 * Allocate and initialize hcd.
-	 * Our private data is also allocated automatically.
-	 */
-	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id);
-	if (!hcd) {
-		uerr("create hcd failed\n");
-		return -ENOMEM;
-	}
-
-
-	/* this is private data for vhci_hcd */
-	the_controller = hcd_to_vhci(hcd);
-
-	/*
-	 * Finish generic HCD structure initialization and register.
-	 * Call the driver's reset() and start() routines.
-	 */
-	ret = usb_add_hcd(hcd, 0, 0);
-	if (ret != 0) {
-		uerr("usb_add_hcd failed %d\n", ret);
-		usb_put_hcd(hcd);
-		the_controller = NULL;
-		return ret;
-	}
-	
-
-	dbg_vhci_hc("bye\n");
-	return 0;
-}
-
-
-static int vhci_hcd_remove(struct platform_device *pdev)
-{
-	struct usb_hcd	*hcd;
-
-
-	hcd = platform_get_drvdata(pdev);
-	if(!hcd)
-		return 0;
-
-	/*
-	 * Disconnects the root hub,
-	 * then reverses the effects of usb_add_hcd(),
-	 * invoking the HCD's stop() methods.
-	 */
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-	the_controller = NULL;
-
-
-	return 0;
-}
-
-
-
-#ifdef CONFIG_PM
-
-/* what should happen for USB/IP under suspend/resume? */
-static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = state;
-
-	return 0;
-}
-
-static int vhci_hcd_resume(struct platform_device *pdev)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	return 0;
-}
-
-#else
-
-#define vhci_hcd_suspend	NULL
-#define vhci_hcd_resume		NULL
-
-#endif
-
-
-static struct platform_driver vhci_driver = {
-	.probe	= vhci_hcd_probe,
-	.remove	= __devexit_p(vhci_hcd_remove),
-	.suspend = vhci_hcd_suspend,
-	.resume	= vhci_hcd_resume,
-	.driver	= {
-		.name = (char *) driver_name,
-		.owner = THIS_MODULE,
-	},
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
- * We need to add this virtual device as a platform device arbitrarily:
- * 	1. platform_device_register()
- */
-static void the_pdev_release(struct device *dev)
-{
-	return;
-}
-
-static struct platform_device the_pdev = {
-	/* should be the same name as driver_name */
-	.name = (char *) driver_name,
-	.id = -1,
-	.dev = {
-		//.driver = &vhci_driver,
-		.release = the_pdev_release,
-	},
-};
-
-static int __init vhci_init(void)
-{
-	int ret;
-
-	dbg_vhci_hc("enter\n");
-	if (usb_disabled())
-		return -ENODEV;
-
-	info("driver %s, %s\n", driver_name, DRIVER_VERSION);
-
-	ret = platform_driver_register(&vhci_driver);
-	if (ret < 0)
-		goto err_driver_register;
-
-	ret = platform_device_register(&the_pdev);
-	if (ret < 0)
-		goto err_platform_device_register;
-
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-
-
-
-	/* error occurred */
-
-err_platform_device_register:
-	platform_driver_unregister(&vhci_driver);
-
-err_driver_register:
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-}
-module_init(vhci_init);
-
-
-static void __exit vhci_cleanup(void)
-{
-	dbg_vhci_hc("enter\n");
-
-	platform_device_unregister(&the_pdev);
-	platform_driver_unregister(&vhci_driver);
-
-	dbg_vhci_hc("bye\n");
-}
-module_exit(vhci_cleanup);
diff -Naur usbip-0.1.4/drivers/2.6.15/vhci_rx.c trunk/drivers/2.6.15/vhci_rx.c
--- usbip-0.1.4/drivers/2.6.15/vhci_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/vhci_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,239 +0,0 @@
-/*
- * $Id: vhci_rx.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
-{
-	struct vhci_priv *priv, *tmp;
-	struct urb *urb = NULL;
-
-
-	spin_lock(&vdev->priv_lock);
-
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
-		if (priv->seqnum == seqnum) {
-			urb = priv->urb;
-			dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", urb, priv, seqnum);
-
-
-			if (urb->status != -EINPROGRESS) {
-				 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
-					 uinfo("urb %p was unlinked %ssynchronuously.\n",
-							 urb, urb->status == -ENOENT ? "" : "a");
-				 } else {
-					 uinfo("urb %p may be in a error, status %d\n",
-							 urb, urb->status);
-				 }
-			}
-
-
-			list_del(&priv->list);
-			kfree(priv);
-			urb->hcpriv = NULL;
-
-
-			break;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-
-	return urb;
-}
-
-static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &vdev->ud;
-	struct urb *urb;
-
-
-	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
-
-
-	if (!urb) {
-		uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
-		uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-
-	/* unpack the pdu to a urb */
-	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
-
-
-	/* recv transfer buffer */
-	if (usbip_recv_xbuff(ud, urb) < 0)
-		return;
-
-
-	/* recv iso_packet_descriptor */
-	if (usbip_recv_iso(ud, urb) < 0)
-		return;
-
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_urb(urb);
-
-
-	dbg_vhci_rx("now giveback urb %p\n", urb);
-
-
-
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-
-	dbg_vhci_rx("Leave\n");
-
-	return;
-}
-
-
-static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
-		struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		uinfo("unlink->seqnum %lu\n", unlink->seqnum);
-		if (unlink->seqnum == pdu->base.seqnum) {
-			dbg_vhci_rx("found pending unlink, %lu\n", unlink->seqnum);
-			list_del(&unlink->list);
-
-			spin_unlock(&vdev->priv_lock);
-			return unlink;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-	return NULL;
-}
-
-
-static void vhci_recv_ret_unlink(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink;
-	struct urb *urb;
-	
-	usbip_dump_header(pdu);
-
-	unlink = dequeue_pending_unlink(vdev, pdu);
-	if (!unlink) {
-		uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
-		return;
-	}
-
-	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
-	if (!urb) {
-		/*
-		 * I get the result of a unlink request. But, it seems that I
-		 * already recieved the result of its submit result and gave
-		 * back the URB.
-		 */
-		uinfo("the urb (seqnum %d) was already given backed\n", pdu->base.seqnum);
-	} else {
-		dbg_vhci_rx("now giveback urb %p\n", urb);
-
-		/* If unlink is succeed, status is -ECONNRESET */
-		urb->status = pdu->u.ret_unlink.status;
-		uinfo("%d\n", urb->status);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	kfree(unlink);
-
-	return;
-}
-
-/* recv a pdu */
-static void vhci_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-
-	dbg_vhci_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_header(&pdu);
-
-	switch(pdu.base.command) {
-		case USBIP_RET_SUBMIT:
-			vhci_recv_ret_submit(vdev, &pdu);
-			break;
-
-		case USBIP_RET_UNLINK:
-			vhci_recv_ret_unlink(vdev, &pdu);
-			break;
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu %u\n", pdu.base.command);
-			usbip_dump_header(&pdu);
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_vhci_rx("signal catched!\n");
-			break;
-		}
-
-
-		if (usbip_event_happend(ud)) break;
-
-		vhci_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.15/vhci_sysfs.c trunk/drivers/2.6.15/vhci_sysfs.c
--- usbip-0.1.4/drivers/2.6.15/vhci_sysfs.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/vhci_sysfs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,286 +0,0 @@
-/*
- * $Id: vhci_sysfs.c 195 2006-10-24 10:11:08Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* TODO: refine locking ?*/
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to show port status */
-
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-		char *out)
-{
-	char *s = out;
-	int i = 0;
-
-	if (!the_controller || !out)
-		BUG();
-
-	spin_lock(&the_controller->lock);
-
-	/*
-	 * output example:
-	 * prt sta bus dev socket           local_busid
-	 * 000 004 000 000         c5a7bb80 1-2.3
-	 * 001 004 000 000         d8cee980 2-3.4
-	 *
-	 * IP address can be retrieved from a socket pointer address by looking
-	 * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
-	 * port number and its peer IP address.
-	 */
-	out += sprintf(out, "prt sta spd bus dev socket           local_busid\n");
-
-	for (i=0; i < VHCI_NPORTS; i++) {
-		struct vhci_device *vdev = port_to_vdev(i);
-
-		spin_lock(&vdev->ud.lock);
-
-		out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
-
-		if (vdev->ud.status == VDEV_ST_USED) {
-			out += sprintf(out, "%03u %03u %03u ",
-					vdev->speed, vdev->busnum, vdev->devnum);
-			out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
-			out += sprintf(out, "%s", vdev->udev->dev.bus_id);
-
-		} else
-			out += sprintf(out, "000 000 000 0000000000000000 0-0");
-
-		out += sprintf(out, "\n");
-
-		spin_unlock(&vdev->ud.lock);
-	}
-
-	spin_unlock(&the_controller->lock);
-
-	return out - s ;
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to shutdown a virtual connection */
-
-static int vhci_port_disconnect(__u32 rhport)
-{
-	struct vhci_device *vdev;
-
-	dbg_vhci_sysfs("enter\n");
-
-	/* lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-	if (vdev->ud.status == VDEV_ST_NULL) {
-		uerr("not connected %d\n", vdev->ud.status);
-
-		/* unlock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		return -EINVAL;
-	}
-
-	/* unlock */
-	spin_unlock(&vdev->ud.lock);
-	spin_unlock(&the_controller->lock);
-
-	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
-
-	return 0;
-}
-
-static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count) {
-	int err;
-	__u32 rhport = 0;
-
-	sscanf(buf, "%u", &rhport);
-
-	/* check rhport */
-	if (rhport >= VHCI_NPORTS) {
-		uerr("invalid port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	err = vhci_port_disconnect(rhport);
-	if (err < 0) {
-		return -EINVAL;
-	}
-
-	dbg_vhci_sysfs("Leave\n");
-	return count;
-}
-
-static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to establish a virtual connection */
-
-static int valid_args(__u32 rhport, __u32 busnum, __u32 devnum,
-		enum usb_device_speed speed)
-{
-	/* check rhport */
-	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		uerr("port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	/* check busnum & devnum */
-	if ((busnum <= 0) || (busnum >= 128) || (devnum <= 0) || (devnum >= 128)) {
-		uerr("busnum %u devnum %u\n", busnum, devnum);
-		return -EINVAL;
-	}
-
-	/* check speed */
-	switch(speed) {
-		case USB_SPEED_LOW:
-		case USB_SPEED_FULL:
-		case USB_SPEED_HIGH:
-		case USB_SPEED_VARIABLE:
-			break;
-
-		default:
-			uerr("speed %d\n", speed);
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * To start a new USB/IP attachment, a userland program needs to setup a TCP
- * connection and then write its socket descriptor with remote device
- * information into this sysfs file.
- *
- * A remote device is virtually attached to the root-hub port of @rhport with
- * @speed. @busnum and @devnum are used to convert URBs between a client host
- * and a server host.
- *
- * write() returns 0 on success, else negative errno.
- */
-static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct vhci_device *vdev;
-	struct socket *socket;
-	int sockfd = 0;
-	__u32 rhport=0, busnum=0, devnum=0, speed=0;
-
-
-	/*
-	 * @rhport: port number of vhci_hcd
-	 * @sockfd: socket descriptor of an established TCP connection
-	 * @busnum: usb bus number in a remote host
-	 * @devnum: usb device number in a remote host
-	 * @speed: usb device speed in a remote host
-	 */
-	sscanf(buf, "%u %u %u %u %u", &rhport, &sockfd, &busnum, &devnum, &speed);
-
-	dbg_vhci_sysfs("rhport(%u) sockfd(%u) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-
-	/* check recieved parameters */
-	if (valid_args(rhport, busnum, devnum, speed) < 0)
-		return -EINVAL;
-
-	/* check sockfd */
-	socket = sockfd_to_socket(sockfd);
-	if (!socket)
-		return  -EINVAL;
-
-	setnodelay(socket);
-
-
-	/* now need lock until setting vdev status as used */
-
-	/* begin a lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-
-	if (vdev->ud.status != VDEV_ST_NULL) {
-		/* end of the lock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		uerr("port %d already used\n", rhport);
-		return -EINVAL;
-	}
-
-	uinfo("rhport(%u) sockfd(%d) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-	vdev->busnum        = busnum;
-	vdev->devnum        = devnum;
-	vdev->speed         = speed;
-	vdev->ud.tcp_socket = socket;
-	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
-
-	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;
-}
-
-static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_status.attr,
-	&dev_attr_detach.attr,
-	&dev_attr_attach.attr,
-	&dev_attr_usbip_debug.attr,
-	NULL,
-};
-
-struct attribute_group dev_attr_group = {
-	.attrs = dev_attrs,
-};
diff -Naur usbip-0.1.4/drivers/2.6.15/vhci_tx.c trunk/drivers/2.6.15/vhci_tx.c
--- usbip-0.1.4/drivers/2.6.15/vhci_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.15/vhci_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,264 +0,0 @@
-/*
- * $Id: vhci_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* @p: pipe whose dev number modified
- * @pdev: new devive number */
-static unsigned long tweak_pipe_devnum(__u32 p, __u8 pdev)
-{
-	__u32 oldp;
-	oldp = p;
-
-	if (pdev > 0x7f)
-		uerr("invalid devnum %u\n", pdev);
-
-	pdev &= 0x7f;    // 0XXX XXXX  confirm MSB be 0
-
-	p &= 0xffff80ff; /* clear p's devnum */
-
-	p |= (pdev << 8);
-
-	dbg_vhci_tx("return new pipe, devnum %u -> %u \n",
-		    usb_pipedevice(oldp), usb_pipedevice(p));
-	dbg_vhci_tx("           pipe %08x -> %08x\n", oldp, p);
-
-	return p;
-}
-
-static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
-{
-	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
-	struct vhci_device *vdev = priv->vdev;
-
-	dbg_vhci_tx("URB, local devnum(%u), busnum(%u) devnum(%u)\n",
-	            usb_pipedevice(urb->pipe), vdev->busnum, vdev->devnum);
-
-	pdup->base.command = USBIP_CMD_SUBMIT;
-	pdup->base.busnum  = vdev->busnum;
-	pdup->base.devnum  = vdev->devnum;
-	pdup->base.seqnum  = priv->seqnum;
-	pdup->base.pipe	   = tweak_pipe_devnum(urb->pipe, vdev->devnum);
-
-	usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
-
-	if (urb->setup_packet)
-		memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8);
-}
-
-static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_priv *priv, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) {
-		list_move_tail(&priv->list, &vdev->priv_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-
-static int vhci_send_cmd_submit(struct vhci_device *vdev)
-{
-	struct vhci_priv *priv = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(vdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_cmd_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->transfer_buffer_length;
-			txsize += urb->transfer_buffer_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_move_tail(&unlink->list, &vdev->unlink_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int vhci_send_cmd_unlink(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
-
-
-		/* 1. setup usbip_header */
-		pdu_header.base.command = USBIP_CMD_UNLINK;
-		pdu_header.base.busnum  = vdev->busnum;
-		pdu_header.base.devnum  = vdev->devnum;
-		pdu_header.base.seqnum  = unlink->seqnum;
-		pdu_header.base.pipe	= 0;
-		pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum;
-
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			uinfo("vhci_tx signal catched\n");
-			break;
-		}
-
-		if (vhci_send_cmd_submit(vdev) < 0)
-			break;
-
-		if (vhci_send_cmd_unlink(vdev) < 0)
-			break;
-
-		wait_event_interruptible(vdev->waitq_tx,
-				(!list_empty(&vdev->priv_tx) ||
-				 !list_empty(&vdev->unlink_tx)));
-
-		dbg_vhci_tx("pending urbs ?, now wake up\n");
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.16/Makefile trunk/drivers/2.6.16/Makefile
--- usbip-0.1.4/drivers/2.6.16/Makefile	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,63 +0,0 @@
-# Makefile for the USB/IP driver
-#
-# $Id: Makefile 97 2006-03-31 16:08:40Z taka-hir $
-#
-# Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
-#
-#
-# 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.
-#
-
- 
-# Please modify here or set environments.
-# KSOURCE should be pointed to the build directory of your kernel.
-# 
-DEBUG ?= n
-KSOURCE ?= /usr/src/linux
-
-
-%.x:%.c
-	gcc -o $@ $<
-
-KBUILD_VERBOSE:=1
-
-HCD_HEADER:=$(KSOURCE)/drivers/usb/core/hcd.h
-
-obj-m += usbip.o
-usbip-objs :=  usbip_common.o usbip_event.o stub_dev.o stub_main.o stub_rx.o stub_tx.o
-
-obj-m += vhci-hcd.o
-vhci-hcd-objs :=  usbip_common.o usbip_event.o vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
-
-
-EXTRA_CFLAGS += -DHCD_HEADER=\"$(HCD_HEADER)\"
-
-ifeq ($(DEBUG),y)
-	EXTRA_CFLAGS += -DCONFIG_USB_DEBUG
-endif
-
-
-default:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` modules
-
-.PHONY: cscope
-cscope:
-	cscope -b -k -R
-
-.PHONY: clean
-clean:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` clean
-	rm -f *.x *~
diff -Naur usbip-0.1.4/drivers/2.6.16/stub_dev.c trunk/drivers/2.6.16/stub_dev.c
--- usbip-0.1.4/drivers/2.6.16/stub_dev.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/stub_dev.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,438 +0,0 @@
-/*
- * $Id: stub_dev.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-
-static int stub_probe(struct usb_interface *interface,  const struct usb_device_id *id);
-static void stub_disconnect(struct usb_interface *interface);
-
-
-/*
- * Define device IDs here if you want to explicitly limit exportable devices.
- * In the most cases, wild card matching will be ok because driver binding can
- * be changed dynamically by a userland program.
- */
-static struct usb_device_id stub_table[] = {
-#if 0
-	/* just an example */
-	{ USB_DEVICE(0x05ac, 0x0301) },   /* Mac 1 button mouse */
-	{ USB_DEVICE(0x0430, 0x0009) },   /* Plat Home Keyboard */
-	{ USB_DEVICE(0x059b, 0x0001) },   /* Iomega USB Zip 100 */
-	{ USB_DEVICE(0x04b3, 0x4427) },   /* IBM USB CD-ROM */
-	{ USB_DEVICE(0x05a9, 0xa511) },   /* LifeView USB cam */
-	{ USB_DEVICE(0x55aa, 0x0201) },   /* Imation card reader */
-	{ USB_DEVICE(0x046d, 0x0870) },   /* Qcam Express(QV-30) */
-	{ USB_DEVICE(0x04bb, 0x0101) },   /* IO-DATA HD 120GB */
-	{ USB_DEVICE(0x04bb, 0x0904) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x04bb, 0x0201) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x08bb, 0x2702) },   /* ONKYO USB Speaker */
-	{ USB_DEVICE(0x046d, 0x08b2) },   /* Logicool Qcam 4000 Pro */
-#endif
-	/* magic for wild card */
-	{ .driver_info = 1 },
-	{ }                                     /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, stub_table);
-
-
-struct usb_driver stub_driver = {
-	.name		= "usbip",
-
-	.probe		= stub_probe,
-	.disconnect 	= stub_disconnect,
-
-	.id_table	= stub_table,
-};
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for a usbip-bound device */
-
-
-/*
- * usbip_status shows status of usbip as long as this driver is bound to the
- * target device.
- */
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct stub_device *sdev = dev_get_drvdata(dev);
-	int status;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	spin_lock(&sdev->ud.lock);
-	status = sdev->ud.status;
-	spin_unlock(&sdev->ud.lock);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", status);
-}
-static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
-
-
-/*
- * 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;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	sscanf(buf, "%d", &sockfd);
-
-	if (sockfd != -1) {
-		uinfo("stub up\n");
-
-		spin_lock(&sdev->ud.lock);
-
-		if (sdev->ud.status != SDEV_ST_AVAILABLE) {
-			uerr("not ready\n");
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		socket = sockfd_to_socket(sockfd);
-		if (!socket) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		setnodelay(socket);
-		setkeepalive(socket);
-		setreuse(socket);
-
-		sdev->ud.tcp_socket = socket;
-
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_start_threads(&sdev->ud);
-
-		spin_lock(&sdev->ud.lock);
-		sdev->ud.status = SDEV_ST_USED;
-		spin_unlock(&sdev->ud.lock);
-
-	} else {
-		uinfo("stub down\n");
-
-		spin_lock(&sdev->ud.lock);
-		if (sdev->ud.status != SDEV_ST_USED) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
-	}
-
-	return count;
-}
-static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
-
-static void stub_add_files(struct device *dev)
-{
-	device_create_file(dev, &dev_attr_usbip_status);
-	device_create_file(dev, &dev_attr_usbip_sockfd);
-	device_create_file(dev, &dev_attr_usbip_debug);
-}
-
-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);
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Event handler functions called by an event handler thread */
-
-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) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	/* 1. stop threads */
-	usbip_stop_threads(ud);
-
-	/* 2. close the socket */
-	/*
-	 * tcp_socket is freed after threads are killed.
-	 * So usbip_xmit do not touch NULL socket.
-	 */
-	if (ud->tcp_socket) {
-		sock_release(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);
-	struct usb_device *udev = interface_to_usbdev(sdev->interface);
-	int ret;
-
-	ret = usb_lock_device_for_reset(udev, sdev->interface);
-	if (ret < 0) {
-		uerr("lock for reset\n");
-
-		spin_lock(&ud->lock);
-		ud->status = SDEV_ST_ERROR;
-		spin_unlock(&ud->lock);
-
-		return;
-	}
-
-	/* try to reset the device */
-	ret = usb_reset_device(udev);
-
-	usb_unlock_device(udev);
-
-	spin_lock(&ud->lock);
-	if (ret) {
-		uerr("device reset\n");
-		ud->status = SDEV_ST_ERROR;
-
-	} else {
-		uinfo("device reset\n");
-		ud->status = SDEV_ST_AVAILABLE;
-
-	}
-	spin_unlock(&ud->lock);
-
-	return;
-}
-
-static void stub_device_unusable(struct usbip_device *ud)
-{
-	spin_lock(&ud->lock);
-	ud->status = SDEV_ST_ERROR;
-	spin_unlock(&ud->lock);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * stub_device_alloc - allocate a new stub_device struct
- * @interface: usb_interface of a new device
- *
- * Allocates and initializes a new stub_devce struct.
- */
-static struct stub_device * stub_device_alloc(struct usb_interface *interface)
-{
-	struct stub_device *sdev;
-
-	/* yes, it's a new device */
-	sdev = (struct stub_device *) kzalloc(sizeof(struct stub_device), GFP_KERNEL);
-	if (!sdev) {
-		uerr("no memory for stub_device\n");
-		return NULL;
-	}
-
-	sdev->interface = interface;
-
-	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;
-	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);
-	sdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	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);
-
-	udbg("register new interface\n");
-	return sdev;
-}
-
-static int stub_device_free(struct stub_device *sdev)
-{
-	if (!sdev)
-		return -EINVAL;
-
-	kfree(sdev);
-	udbg("kfree udev ok\n");
-
-	return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e. not *an*
- * active interface). Currently, a userland program must ensure that it
- * looks at the usbip's sysfs entries of only the first active interface.
- */
-static int stub_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	struct stub_device *sdev = NULL;
-	char *udev_busid = interface->dev.parent->bus_id;
-
-	udbg("Enter\n");
-
-	/* check we should claim or not by busid_table */
-	if (match_busid(udev_busid)) {
-		uinfo("this device %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) {
-		udbg("this device %s is a usb hub device. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		udbg("this device %s is attached on vhci_hcd. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	/* ok. this is my device. */
-
-	if ((sdev = stub_device_alloc(interface))) {
-		struct usb_device *udev = interface_to_usbdev(interface);
-
-		uinfo("USB/IP Stub: register a new interface (bus %u dev %u ifn %u)\n",
-				udev->bus->busnum, udev->devnum,
-				interface->cur_altsetting->desc.bInterfaceNumber);
-	} else
-		return -ENOMEM;
-
-	/* set private data to usb_interface */
-	usb_set_intfdata(interface, sdev);
-
-	stub_add_files(&interface->dev);
-
-	return 0;
-}
-
-
-/*
- * called in usb_disconnect() or usb_deregister()
- * but only if actconfig(active configuration) exists
- */
-static void stub_disconnect(struct usb_interface *interface)
-{
-	struct stub_device *sdev = usb_get_intfdata(interface);
-
-	udbg("Enter\n");
-
-	/* get stub_device */
-	if (!sdev)
-		BUG();
-
-	usb_set_intfdata(interface, NULL);
-
-
-	/*
-	 * NOTE:
-	 * rx/tx threads are invoked for each usb_device.
-	 */
-	stub_remove_files(&interface->dev);
-
-	/* 1. shutdown the current connection */
-	usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
-
-	/* 2. wait for the stop of the event handler */
-	usbip_stop_eh(&sdev->ud);
-
-	/* 3. free sdev */
-	stub_device_free(sdev);
-
-
-	udbg("bye\n");
-}
diff -Naur usbip-0.1.4/drivers/2.6.16/stub.h trunk/drivers/2.6.16/stub.h
--- usbip-0.1.4/drivers/2.6.16/stub.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/stub.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,96 +0,0 @@
-/*
- * $Id: stub.h 173 2006-07-21 09:48:40Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-
-struct stub_device {
-	struct usb_interface *interface;
-	struct list_head list;
-
-	struct usbip_device ud;
-
-	/*
-	 * stub_priv preserves private data of each urb.
-	 * It is allocated as stub_priv_cache and assigned to urb->context.
-	 *
-	 * stub_priv is always linked to any one of 3 lists;
-	 * 	priv_init: linked to this until the comletion of a urb.
-	 * 	priv_tx  : linked to this after the completion of a urb.
-	 * 	priv_free: linked to this after the sending of the result.
-	 *
-	 * Any of these list operations should be locked by priv_lock.
-	 */
-	spinlock_t priv_lock;
-	struct list_head priv_init;
-	struct list_head priv_tx;
-	struct list_head priv_free;
-
-	/* see comments for unlinking in stub_rx.c */
-	struct list_head unlink_tx;
-	struct list_head unlink_free;
-
-
-	wait_queue_head_t tx_waitq;
-};
-
-/* private data into urb->priv */
-struct stub_priv {
-	unsigned long seqnum;
-	struct list_head list;
-	struct stub_device *sdev;
-	struct urb *urb;
-
-	int unlinking;
-};
-
-struct stub_unlink {
-	unsigned long seqnum;
-	struct list_head list;
-	__u32 status;
-};
-
-
-extern kmem_cache_t *stub_priv_cache;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declarations */
-
-/* stub_tx.c */
-void stub_complete(struct urb*, struct pt_regs *);
-void stub_tx_loop(struct usbip_task *);
-
-/* stub_dev.c */
-extern struct usb_driver stub_driver;
-
-/* stub_rx.c */
-void stub_rx_loop(struct usbip_task *);
-void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
-
-/* stub_main.c */
-int match_busid(char *busid);
-void stub_device_cleanup_urbs(struct stub_device *sdev);
diff -Naur usbip-0.1.4/drivers/2.6.16/stub_main.c trunk/drivers/2.6.16/stub_main.c
--- usbip-0.1.4/drivers/2.6.16/stub_main.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/stub_main.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,300 +0,0 @@
-/*
- * $Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-/* Version Information */
-#define DRIVER_VERSION "$Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $"
-#define DRIVER_AUTHOR "Takahiro Hirofuchi <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Stub Driver for USB/IP"
-
-
-
-/* stub_priv is allocated from stub_priv_cache */
-kmem_cache_t *stub_priv_cache = NULL;
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for the usbip driver */
-
-
-/*
- * busid_tables defines matching busids that usbip can grab. A user can change
- * dynamically what device is locally used and what device is exported to a
- * remote host.
- */
-#define MAX_BUSID 16
-static char busid_table[MAX_BUSID][BUS_ID_SIZE];
-spinlock_t busid_table_lock = SPIN_LOCK_UNLOCKED;
-
-
-int match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-				/* already registerd */
-				spin_unlock(&busid_table_lock);
-				return 0;
-			}
-
-	spin_unlock(&busid_table_lock);
-
-	return 1;
-}
-
-static ssize_t show_match_busid(struct device_driver *drv, char *buf)
-{
-	int i;
-	char *out = buf;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			out += sprintf(out, "%s ", busid_table[i]);
-
-	spin_unlock(&busid_table_lock);
-
-	out += sprintf(out, "\n");
-
-	return out - buf;
-}
-
-static int add_match_busid(char *busid)
-{
-	int i;
-
-	if (!match_busid(busid))
-		return 0;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!busid_table[i][0]) {
-			strncpy(busid_table[i], busid, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static int del_match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-			/* found */
-			memset(busid_table[i], 0, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
-		size_t count)
-{
-	int len;
-	char busid[BUS_ID_SIZE];
-
-	if (count < 5)
-		return -EINVAL;
-
-	/* strnlen() does not include \0 */
-	len = strnlen(buf + 4, BUS_ID_SIZE);
-
-	/* busid needs to include \0 termination */
-	if (!(len < BUS_ID_SIZE))
-		return -EINVAL;
-
-	strncpy(busid, buf + 4, BUS_ID_SIZE);
-
-
-	if (!strncmp(buf, "add ", 4)) {
-		if (add_match_busid(busid) < 0)
-			return -ENOMEM;
-		else {
-			udbg("add busid %s\n", busid);
-			return count;
-		}
-	} else if (!strncmp(buf, "del ", 4)) {
-		if (del_match_busid(busid) < 0)
-			return -ENODEV;
-		else {
-			udbg("del busid %s\n", busid);
-			return count;
-		}
-	} else
-		return -EINVAL;
-}
-
-static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, store_match_busid);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Cleanup functions used to free private data */
-
-static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
-{
-	struct stub_priv *priv, *tmp;
-
-	list_for_each_entry_safe(priv, tmp, listhead, list) {
-		list_del(&priv->list);
-		return priv;
-	}
-
-	return NULL;
-}
-
-static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_init);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_free);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-	return NULL;
-}
-
-void stub_device_cleanup_urbs(struct stub_device *sdev)
-{
-	struct stub_priv *priv;
-
-	udbg("free sdev %p\n", sdev);
-
-	while ((priv = stub_priv_pop(sdev))) {
-		struct urb *urb = priv->urb;
-
-		udbg("   free urb %p\n", urb);
-		usb_kill_urb(urb);
-
-		kmem_cache_free(stub_priv_cache, priv);
-
-		if (urb->transfer_buffer != NULL)
-			kfree(urb->transfer_buffer);
-
-		if (urb->setup_packet != NULL)
-			kfree(urb->setup_packet);
-
-		usb_free_urb(urb);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init usb_stub_init(void)
-{
-	int ret;
-
-	stub_priv_cache = kmem_cache_create("stub_priv", sizeof(struct stub_priv),
-			0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!stub_priv_cache) {
-		uerr("create stub_priv_cache\n");
-		return -ENOMEM;
-	}
-
-	ret = usb_register(&stub_driver);
-	if (ret) {
-		uerr("usb_register failed %d\n", ret);
-		return ret;
-	}
-
-
-	info(DRIVER_DESC "" DRIVER_VERSION);
-
-	memset(busid_table, 0, sizeof(busid_table));
-
-	driver_create_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	return ret;
-}
-
-static void __exit usb_stub_exit(void)
-{
-	int ret;
-
-	udbg("enter\n");
-
-	driver_remove_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	/*
-	 * deregister() calls stub_disconnect() for all devices. Device
-	 * specific data is cleared in stub_disconnect().
-	 */
-	usb_deregister(&stub_driver);
-
-	ret = kmem_cache_destroy(stub_priv_cache);
-	if (ret != 0) {
-		uerr("memory leak of stub_priv, %d\n", ret);
-	}
-
-	udbg("bye\n");
-}
-
-
-
-
-module_init (usb_stub_init);
-module_exit (usb_stub_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff -Naur usbip-0.1.4/drivers/2.6.16/stub_rx.c trunk/drivers/2.6.16/stub_rx.c
--- usbip-0.1.4/drivers/2.6.16/stub_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/stub_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,442 +0,0 @@
-/*
- * $Id: stub_rx.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static int is_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	 return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
-		 (req->bRequestType == USB_RECIP_ENDPOINT) &&
-		 (req->wValue == USB_ENDPOINT_HALT);
-}
-
-static int is_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_INTERFACE) &&
-		   (req->bRequestType == USB_RECIP_INTERFACE);
-}
-
-static int is_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
-		   (req->bRequestType == USB_RECIP_DEVICE);
-}
-
-static int tweak_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	int target_endp;
-	int target_dir;
-	int target_pipe;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	/*
-	 * The stalled endpoint is specified in the wIndex value. The endpoint
-	 * of the urb is the target of this clear_halt request (i.e. control
-	 * endpoint).
-	 */
-	target_endp = le16_to_cpu(req->wIndex) & 0x000f;
-
-	/* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
-	target_dir = le16_to_cpu(req->wIndex) & 0x0080;
-
-	if (target_dir)
-		target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
-	else
-		target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
-
-	ret = usb_clear_halt(urb->dev, target_pipe);
-	if (ret < 0)
-		uinfo("clear_halt error: devnum %d endp %d, %d\n",
-				urb->dev->devnum, target_endp, ret);
-	else
-		uinfo("clear_halt done: devnum %d endp %d\n",
-				urb->dev->devnum, target_endp);
-
-	return ret;
-}
-
-static int tweak_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 alternate;
-	__u16 interface;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	alternate = le16_to_cpu(req->wValue);
-	interface = le16_to_cpu(req->wIndex);
-
-	dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
-
-	ret = usb_set_interface(urb->dev, interface, alternate);
-	if (ret < 0)
-		uinfo("set_interface error: inf %u alt %u, %d\n",
-				interface, alternate, ret);
-	else
-		uinfo("set_interface done: inf %u alt %u\n", interface, alternate);
-
-	return ret;
-}
-
-static int tweak_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 config;
-
-	info("set_configuration is not fully supported yet\n");
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	config = le16_to_cpu(req->wValue);
-
-	uinfo("set_configuration: devnum %d %d\n", urb->dev->devnum, config);
-
-#if 0
-	return usb_set_configuration(urb->dev, config);
-#endif
-	return 0;
-}
-
-/*
- * clear_halt, set_interface, and set_configuration require special tricks.
- * TODO: set_configuration. but I have never seen a multi-config device.
- */
-static void tweak_special_requests(struct urb *urb)
-{
-	if (!urb || !urb->setup_packet)
-		return;
-
-	if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
-		return;
-
-	if (is_clear_halt_cmd(urb))
-		/* treak clear_halt */
-		 tweak_clear_halt_cmd(urb);
-
-	else if (is_set_interface_cmd(urb))
-		/* tweak set_interface */
-		tweak_set_interface_cmd(urb);
-
-	else if (is_set_configuration_cmd(urb))
-		/* tweak set_configuration */
-		tweak_set_configuration_cmd(urb);
-
-	else
-		dbg_stub_rx("no need to tweak\n");
-}
-
-/*
- * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
- * By unlinking the urb asynchronously, stub_rx can continuously
- * process coming urbs.  Even if the urb is unlinked, its completion
- * handler will be called and stub_tx will send a return pdu.
- *
- * See also comments about unlinking strategy in vhci_hcd.c.
- */
-static int stub_recv_cmd_unlink(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct list_head *listhead = &sdev->priv_init;
-	struct list_head *ptr;
-	unsigned long flags;
-
-	struct stub_priv *priv;
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
-		priv = list_entry(ptr, struct stub_priv, list);
-		if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
-			int ret;
-
-			uinfo("unlink urb %p\n", priv->urb);
-
-			/*
-			 * This matched urb is not completed yet (i.e. be in
-			 * flight in usb hcd hardware/driver). Now we are
-			 * cancelling it. The unlinking flag means that we are
-			 * now not going to return the normal result pdu of a
-			 * submittion request, but going to return a result pdu
-			 * of the unlink request.
-			 */
-			priv->unlinking = 1;
-
-			/*
-			 * In the case that unlinking flag is on, prev->seqnum
-			 * is changed from the seqnum of the cancelling urb to
-			 * the seqnum of the unlink request. This will be used
-			 * to make the result pdu of the unlink request.
-			 */
-			priv->seqnum = pdu->base.seqnum;
-
-			spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-			/*
-			 * usb_unlink_urb() is now out of spinlocking to avoid
-			 * spinlock recursion since stub_complete() is
-			 * sometimes called in this context but not in the
-			 * interrupt context.  If stub_complete() is executed
-			 * before we call usb_unlink_urb(), usb_unlink_urb()
-			 * will return an error value. In this case, stub_tx
-			 * will return the result pdu of this unlink request
-			 * though submission is completed and actual unlinking
-			 * is not executed. OK?
-			 */
-			ret = usb_unlink_urb(priv->urb);
-			if (ret != -EINPROGRESS)
-				uerr("faild to unlink a urb %p, ret %d\n", priv->urb, ret);
-
-			return 0;
-		}
-	}
-
-	dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
-
-	/*
-	 * The urb of the unlink target is not found in priv_init queue. It was
-	 * already completed and its results is/was going to be sent by a
-	 * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
-	 * return the completeness of this unlink request to vhci_hcd.
-	 */
-	stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-
-	return 0;
-}
-
-static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &sdev->ud;
-
-	int bus = interface_to_busnum(sdev->interface);
-	int dev = interface_to_devnum(sdev->interface);
-
-	if (pdu->base.busnum == bus && pdu->base.devnum == dev) {
-		spin_lock(&ud->lock);
-		if (ud->status == SDEV_ST_USED) {
-			/* A request is valid. */
-			spin_unlock(&ud->lock);
-			return 1;
-		}
-		spin_unlock(&ud->lock);
-	}
-
-	return 0;
-}
-
-static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
-		struct usbip_header *pdu)
-{
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
-	if (!priv) {
-		uerr("alloc stub_priv\n");
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return NULL;
-	}
-
-	memset(priv, 0, sizeof(struct stub_priv));
-
-	priv->seqnum = pdu->base.seqnum;
-	priv->sdev = sdev;
-
-	/*
-	 * After a stub_priv is linked to a list_head,
-	 * our error handler can free allocated data.
-	 */
-	list_add_tail(&priv->list, &sdev->priv_init);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return priv;
-}
-
-static void stub_recv_cmd_submit(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	int ret;
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-
-
-	priv = stub_priv_alloc(sdev, pdu);
-	if (!priv)
-		return;
-
-	/* setup a urb */
-	if (usb_pipeisoc(pdu->base.pipe))
-		priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, GFP_KERNEL);
-	else
-		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
-
-	if (!priv->urb) {
-		uerr("malloc urb\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	/* set priv->urb->transfer_buffer */
-	if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
-		priv->urb->transfer_buffer =
-			kzalloc(pdu->u.cmd_submit.transfer_buffer_length, GFP_KERNEL);
-		if (!priv->urb->transfer_buffer) {
-			uerr("malloc x_buff\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-			return;
-		}
-	}
-
-	/* set priv->urb->setup_packet */
-	priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
-	if (!priv->urb->setup_packet) {
-		uerr("allocate setup_packet\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-	memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
-
-	/* set other members from the base header of pdu */
-	priv->urb->context                = (void *) priv;
-	priv->urb->dev                    = interface_to_usbdev(sdev->interface);
-	priv->urb->pipe                   = pdu->base.pipe;
-	priv->urb->complete               = stub_complete;
-
-	usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
-
-
-	if (usbip_recv_xbuff(ud, priv->urb) < 0)
-		return;
-
-	if (usbip_recv_iso(ud, priv->urb) < 0)
-		return;
-
-	tweak_special_requests(priv->urb);
-
-	/* urb is now ready to submit */
-	ret = usb_submit_urb(priv->urb, GFP_KERNEL);
-
-	if (ret == 0)
-		dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
-	else {
-		uerr("submit_urb error, %d\n", ret);
-
-		/*
-		 * Pessimistic.
-		 * This connection will be discared.
-		 */
-		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
-	}
-
-	dbg_stub_rx("Leave\n");
-	return;
-}
-
-/* recv a pdu */
-static void stub_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-
-	dbg_stub_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_stub_rx)
-		usbip_dump_header(&pdu);
-
-	if (!valid_request(sdev, &pdu)) {
-		uerr("recv invalid request\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	switch (pdu.base.command) {
-		case USBIP_CMD_UNLINK:
-			stub_recv_cmd_unlink(sdev, &pdu);
-			break;
-
-		case USBIP_CMD_SUBMIT:
-			stub_recv_cmd_submit(sdev, &pdu);
-			break;
-
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-			return;
-	}
-
-}
-
-void stub_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_rx("signal catched!\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		stub_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.16/stub_tx.c trunk/drivers/2.6.16/stub_tx.c
--- usbip-0.1.4/drivers/2.6.16/stub_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/stub_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,374 +0,0 @@
-/*
- * $Id: stub_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static void stub_free_priv_and_urb(struct stub_priv *priv)
-{
-	struct urb *urb = priv->urb;
-
-	if (urb->setup_packet)
-		kfree(urb->setup_packet);
-
-	if (urb->transfer_buffer)
-		kfree(urb->transfer_buffer);
-
-	list_del(&priv->list);
-	kmem_cache_free(stub_priv_cache, priv);
-
-	usb_free_urb(urb);
-}
-
-/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
-void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, __u32 status)
-{
-	struct stub_unlink *unlink;
-
-	unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
-	if (!unlink) {
-		uerr("alloc stub_unlink\n");
-		usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	unlink->seqnum = seqnum;
-	unlink->status = status;
-
-	list_add_tail(&unlink->list, &sdev->unlink_tx);
-}
-
-/**
- * stub_complete - completion handler of a usbip urb
- * @urb: pointer to the urb completed
- * @regs:
- *
- * When a urb has completed, the USB core driver calls this function mostly in
- * the interrupt context. To return the result of a urb, the completed urb is
- * linked to the pending list of returning.
- *
- */
-void stub_complete(struct urb *urb, struct pt_regs *regs)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-	struct stub_device *sdev = priv->sdev;
-	unsigned long flags;
-
-	dbg_stub_tx("complete! status %d\n", urb->status);
-
-
-	switch (urb->status) {
-		case 0:
-			/* OK */
-			break;
-		case -ENOENT:
-			uinfo("stopped by a call of usb_kill_urb()"
-					"because of cleaning up a virtual connection\n");
-			return;
-		case -ECONNRESET:
-			uinfo("unlinked by a call of usb_unlink_urb()\n");
-			break;
-		case -EPIPE:
-			uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
-			break;
-		case -ESHUTDOWN:
-			uinfo("device removed?\n");
-			break;
-		default:
-			uinfo("urb completion with non-zero status %d\n", urb->status);
-	}
-
-	/* link a urb to the queue of tx. */
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	if (priv->unlinking) {
-		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
-		stub_free_priv_and_urb(priv);
-	} else
-		list_move_tail(&priv->list, &sdev->priv_tx);
-
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	/* wake up tx_thread */
-	wake_up(&sdev->tx_waitq);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* fill PDU */
-
-static inline void setup_base_pdu(struct usbip_header_basic *base,
-		__u32 command, __u32 seqnum)
-{
-	base->command = command;
-	base->busnum  = 0;
-	base->devnum  = 0;
-	base->seqnum  = seqnum;
-	base->pipe    = 0;
-}
-
-static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-
-	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
-
-	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
-}
-
-static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
-		struct stub_unlink *unlink)
-{
-	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
-
-	rpdu->u.ret_unlink.status = unlink->status;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_SUBMIT */
-
-static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
-		list_move_tail(&priv->list, &sdev->priv_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int stub_send_ret_submit(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_ret_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->actual_length;
-			txsize += urb->actual_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
-		stub_free_priv_and_urb(priv);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_UNLINK */
-
-static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
-{
-	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_move_tail(&unlink->list, &sdev->unlink_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-static int stub_send_ret_unlink(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_unlink *unlink, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[1];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
-
-		/* 1. setup usbip_header */
-		setup_ret_unlink_pdu(&pdu_header, unlink);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void stub_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_tx("signal catched\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		/*
-		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
-		 * looks at only priv_init queue. If the completion of a URB is
-		 * earlier than the recieve of CMD_UNLINK, priv is moved to
-		 * priv_tx queue and stub_rx does not find the target priv. In
-		 * this case, vhci_rx recieves the result of the submit request
-		 * and then recieves the result of the unlink request. The
-		 * result of the submit is given back to the usbcore as the
-		 * completion of the unlink request. The request of the
-		 * unlink is ignored. This is ok because a driver who calls
-		 * usb_unlink_urb() understands the unlink was too late by
-		 * getting the status of the given-backed URB which has the
-		 * status of usb_submit_urb().
-		 */
-		if (stub_send_ret_submit(sdev) < 0)
-			break;
-
-		if (stub_send_ret_unlink(sdev) < 0)
-			break;
-
-		wait_event_interruptible(sdev->tx_waitq,
-				(!list_empty(&sdev->priv_tx) ||
-				 !list_empty(&sdev->unlink_tx)));
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.16/usbip_common.c trunk/drivers/2.6.16/usbip_common.c
--- usbip-0.1.4/drivers/2.6.16/usbip_common.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/usbip_common.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,935 +0,0 @@
-/*
- * $Id: usbip_common.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/file.h>
-#include <linux/tcp.h>
-#include <linux/in.h>
-#include "usbip_common.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* debug routines */
-
-#ifdef CONFIG_USB_DEBUG
-unsigned long usbip_debug_flag = 0xffffffff;
-#else
-unsigned long usbip_debug_flag = 0;
-#endif
-
-static ssize_t show_flag(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%lx\n", usbip_debug_flag);
-}
-
-static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	unsigned long flag;
-
-	sscanf(buf, "%lx", &flag);
-	usbip_debug_flag = flag;
-
-	return count;
-}
-DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
-
-static void usbip_dump_buffer(char *buff, int bufflen)
-{
-	int i;
-
-	if (bufflen > 128) {
-		for (i = 0; i< 128; i++) {
-			if (i%24 == 0)
-				printk("   ");
-			printk("%02x ", (unsigned char ) buff[i]);
-			if (i%4 == 3) printk("| ");
-			if (i%24 == 23) printk("\n");
-		}
-		printk("... (%d byte)\n", bufflen);
-		return;
-	}
-
-	for (i = 0; i< bufflen; i++) {
-		if (i%24 == 0)
-			printk("   ");
-		printk("%02x ", (unsigned char ) buff[i]);
-		if (i%4 == 3)
-			printk("| ");
-		if (i%24 == 23)
-			printk("\n");
-	}
-	printk("\n");
-
-}
-
-static void usbip_dump_pipe(unsigned int p)
-{
-	unsigned char type = usb_pipetype(p);
-	unsigned char ep = usb_pipeendpoint(p);
-	unsigned char dev = usb_pipedevice(p);
-	unsigned char dir = usb_pipein(p);
-
-	printk("dev(%d) ", dev);
-	printk("ep(%d) ",  ep);
-	printk("%s ", dir ? "IN" : "OUT");
-
-	switch(type) {
-		case PIPE_ISOCHRONOUS :
-			printk("%s ", "ISO");
-			break;
-		case PIPE_INTERRUPT :
-			printk("%s ", "INT");
-			break;
-		case PIPE_CONTROL :
-			printk("%s ", "CTL");
-			break;
-		case PIPE_BULK :
-			printk("%s ", "BLK");
-			break;
-		default :
-			printk("ERR");
-	}
-
-	printk("\n");
-
-}
-
-static void usbip_dump_usb_device(struct usb_device *dev)
-{
-	int i;
-
-	if (!dev) {
-		printk("      dump usb dev: null pointer!!\n");
-		return;
-	}
-
-	printk("       devnum(%d) devpath(%s)", dev->devnum, dev->devpath);
-
-	switch(dev->speed) {
-		case USB_SPEED_HIGH :
-			printk(" SPD_HIGH");
-			break;
-		case USB_SPEED_FULL :
-			printk(" SPD_FULL");
-			break;
-		case USB_SPEED_LOW :
-			printk(" SPD_LOW");
-			break;
-		case USB_SPEED_UNKNOWN :
-			printk(" SPD_UNKNOWN");
-			break;
-		default :
-			printk(" SPD_ERROR");
-	}
-
-	printk(" tt %p, ttport %d", dev->tt, dev->ttport);
-	printk("\n");
-
-	printk("                    ");
-	for (i = 0; i < 16; i++) {
-		printk(" %2u", i);
-	}
-
-	printk("\n");
-
-	printk("       toggle0(IN) :");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[0] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-	printk("       toggle1(OUT):");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[1] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-
-	printk("       epmaxp_in   :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_in[i])
-			printk(" %2u",  dev->ep_in[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n");
-
-	printk("       epmaxp_out  :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_out[i])
-			printk(" %2u",  dev->ep_out[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n       ");
-
-	printk("parent %p, bus %p", dev->parent, dev->bus);
-	printk("\n       ");
-
-	printk("descriptor %p, config %p, actconfig %p, rawdescriptors %p",
-			&dev->descriptor, dev->config, dev->actconfig, dev->rawdescriptors);
-	printk("\n       ");
-
-	printk("have_langid %d, string_langid %d", dev->have_langid, dev->string_langid);
-	printk("\n       ");
-
-	printk("maxchild %d, children %p", dev->maxchild, dev->children);
-
-	printk("\n");
-}
-
-static void usbip_dump_request_type(__u8 rt)
-{
-	switch(rt & USB_RECIP_MASK) {
-		case USB_RECIP_DEVICE:
-			printk("DEVICE");
-			break;
-		case USB_RECIP_INTERFACE:
-			printk("INTERF");
-			break;
-		case USB_RECIP_ENDPOINT:
-			printk("ENDPOI");
-			break;
-		case USB_RECIP_OTHER:
-			printk("OTHER ");
-			break;
-		default:
-			printk("------");
-	}
-}
-
-static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
-{
-	if (!cmd) {
-		printk("      %s : null pointer\n", __FUNCTION__);
-		return;
-	}
-
-	printk("       ");
-	printk("bRequestType(%02X) ", cmd->bRequestType);
-	printk("bRequest(%02X) " , cmd->bRequest);
-	printk("wValue(%04X) ", cmd->wValue);
-	printk("wIndex(%04X) ", cmd->wIndex);
-	printk("wLength(%04X) ", cmd->wLength);
-
-	printk("\n       ");
-
-	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk("STANDARD ");
-		switch(cmd->bRequest) {
-			case USB_REQ_GET_STATUS:
-				printk("GET_STATUS");
-				break;
-			case USB_REQ_CLEAR_FEATURE:
-				printk("CLEAR_FEAT");
-				break;
-			case USB_REQ_SET_FEATURE:
-				printk("SET_FEAT  ");
-				break;
-			case USB_REQ_SET_ADDRESS:
-				printk("SET_ADDRRS");
-				break;
-			case USB_REQ_GET_DESCRIPTOR:
-				printk("GET_DESCRI");
-				break;
-			case USB_REQ_SET_DESCRIPTOR:
-				printk("SET_DESCRI");
-				break;
-			case USB_REQ_GET_CONFIGURATION:
-				printk("GET_CONFIG");
-				break;
-			case USB_REQ_SET_CONFIGURATION:
-				printk("SET_CONFIG");
-				break;
-			case USB_REQ_GET_INTERFACE:
-				printk("GET_INTERF");
-				break;
-			case USB_REQ_SET_INTERFACE:
-				printk("SET_INTERF");
-				break;
-			case USB_REQ_SYNCH_FRAME:
-				printk("SYNC_FRAME");
-				break;
-			default:
-				printk("REQ(%02X) ", cmd->bRequest);
-		}
-
-		printk(" ");
-		usbip_dump_request_type(cmd->bRequestType);
-
-	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk("CLASS   ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk("VENDOR  ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk("RESERVED");
-
-	printk("\n");
-}
-
-void usbip_dump_urb (struct urb *purb)
-{
-	if (!purb) {
-		printk("   dump urb: null pointer!!\n");
-		return;
-	}
-
-	printk("   urb                   :%p\n", purb);
-	printk("   dev                   :%p\n", purb->dev);
-
-	usbip_dump_usb_device(purb->dev);
-
-	printk("   pipe                  :%08x ", purb->pipe);
-
-	usbip_dump_pipe(purb->pipe);
-
-	printk("   status                :%d\n", purb->status);
-	printk("   transfer_flags        :%08X\n", purb->transfer_flags);
-	printk("   transfer_buffer       :%p\n", purb->transfer_buffer);
-	printk("   transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("   actual_length         :%d\n", purb->actual_length);
-	printk("   bandwidth             :%d\n", purb->actual_length);
-	printk("   setup_packet          :%p\n", purb->setup_packet);
-
-	if (purb->setup_packet && usb_pipetype(purb->pipe) == PIPE_CONTROL)
-		usbip_dump_usb_ctrlrequest((struct usb_ctrlrequest *) purb->setup_packet);
-
-	printk("   start_frame           :%d\n", purb->start_frame);
-	printk("   number_of_packets     :%d\n", purb->number_of_packets);
-	printk("   interval              :%d\n", purb->interval);
-	printk("   error_count           :%d\n", purb->error_count);
-	printk("   context               :%p\n", purb->context);
-	printk("   complete              :%p\n", purb->complete);
-}
-
-void usbip_dump_header(struct usbip_header *pdu)
-{
-	udbg("BASE: cmd %u bus %u dev %u seq %u pipe %04x\n",
-			pdu->base.command,
-			pdu->base.busnum,
-			pdu->base.devnum,
-			pdu->base.seqnum,
-			pdu->base.pipe);
-
-	usbip_dump_pipe(pdu->base.pipe);
-
-	switch(pdu->base.command) {
-		case USBIP_CMD_SUBMIT:
-			udbg("CMD_SUBMIT: x_flags %u x_len %u bw %u sf %u #p %u iv %u\n",
-					pdu->u.cmd_submit.transfer_flags,
-					pdu->u.cmd_submit.transfer_buffer_length,
-					pdu->u.cmd_submit.bandwidth,
-					pdu->u.cmd_submit.start_frame,
-					pdu->u.cmd_submit.number_of_packets,
-					pdu->u.cmd_submit.interval);
-					break;
-		case USBIP_CMD_UNLINK:
-			udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
-			break;
-		case USBIP_RET_SUBMIT:
-			udbg("RET_SUBMIT: st %d al %u bw %u sf %d ec %d\n",
-					pdu->u.ret_submit.status,
-					pdu->u.ret_submit.actual_length,
-					pdu->u.ret_submit.bandwidth,
-					pdu->u.ret_submit.start_frame,
-					pdu->u.ret_submit.error_count);
-		case USBIP_RET_UNLINK:
-			udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
-			break;
-		default:
-			/* NOT REACHED */
-			udbg("UNKNOWN\n");
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* thread routines */
-
-int usbip_thread(void *param)
-{
-	struct usbip_task *ut = (struct usbip_task *) 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);
-}
-
-void usbip_start_threads(struct usbip_device *ud)
-{
-	/*
-	 * threads are invoked per one device (per one connection).
-	 */
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_rx, 0);
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_tx, 0);
-
-	/* confirm threads are starting */
-	wait_for_completion(&ud->tcp_rx.thread_done);
-	wait_for_completion(&ud->tcp_tx.thread_done);
-}
-
-void usbip_stop_threads(struct usbip_device *ud)
-{
-        /* kill threads related to this sdev, if v.c. exists */
-	if (ud->tcp_rx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
-		wait_for_completion(&ud->tcp_rx.thread_done);
-		udbg("rx_thread for ud %p has finished\n", ud);
-	}
-
-	if (ud->tcp_tx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
-		wait_for_completion(&ud->tcp_tx.thread_done);
-		udbg("tx_thread for ud %p has finished\n", ud);
-	}
-}
-
-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;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* socket routines */
-
- /*  Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags)
-{
-	int result;
-	struct msghdr msg;
-	struct kvec iov;
-	int total = 0;
-
-	/* for blocks of if (dbg_flag_xmit) */
-	char *bp = buf;
-	int osize= size;
-
-	dbg_xmit("enter\n");
-
-	if (!sock || !buf || !size) {
-		uerr("usbip_xmit: invalid arg, sock %p buff %p size %d\n",
-				sock, buf, size);
-		return -EINVAL;
-	}
-
-
-	if (dbg_flag_xmit) {
-		if (send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: sending... , sock %p, buf %p, size %d, msg_flags %d\n",
-					sock, buf, size, msg_flags);
-			usbip_dump_buffer(buf, size);
-		}
-	}
-
-
-	do {
-		sock->sk->sk_allocation = GFP_NOIO;
-		iov.iov_base    = buf;
-		iov.iov_len     = size;
-		msg.msg_name    = NULL;
-		msg.msg_namelen = 0;
-		msg.msg_control = NULL;
-		msg.msg_controllen = 0;
-		msg.msg_namelen    = 0;
-		msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
-
-		if (send)
-			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
-		else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL);
-
-		if (result <= 0) {
-			udbg("usbip_xmit: %s sock %p buf %p size %u ret %d total %d\n",
-					send ? "send" : "receive", sock, buf, size, result, total);
-			goto err;
-		}
-
-		size -= result;
-		buf += result;
-		total += result;
-
-	} while (size > 0);
-
-
-	if (dbg_flag_xmit) {
-		if (!send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: receiving....\n");
-			usbip_dump_buffer(bp, osize);
-			printk("usbip_xmit: received, osize %d ret %d size %d total %d\n",
-					osize, result, size, total);
-		}
-
-		if (send) {
-			printk("usbip_xmit: send, total %d\n", total);
-		}
-	}
-
-	return total;
-
-err:
-	return result;
-}
-
-int setquickack(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-void setreuse(struct socket *socket)
-{
-	socket->sk->sk_reuse = 1;
-}
-
-struct socket *sockfd_to_socket(unsigned int sockfd)
-{
-	struct socket *socket;
-	struct file *file;
-	struct inode *inode;
-
-	file = fget(sockfd);
-	if (!file) {
-		uerr("invalid sockfd\n");
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-
-	if (!inode || !S_ISSOCK(inode->i_mode))
-		return NULL;
-
-	socket = SOCKET_I(inode);
-
-	return socket;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/* pdu routines */
-
-/* there may be more cases to tweak the flags. */
-static unsigned int tweak_transfer_flags(unsigned int flags)
-{
-
-	if (flags & URB_NO_TRANSFER_DMA_MAP)
-		/*
-		 * vhci_hcd does not provide DMA-mapped I/O. The upper
-		 * driver does not need to set this flag. The remote
-		 * usbip.ko does not still perform DMA-mapped I/O for
-		 * DMA-caplable host controllers. So, clear this flag.
-		 */
-		flags &= ~URB_NO_TRANSFER_DMA_MAP;
-
-	if (flags & URB_NO_SETUP_DMA_MAP)
-		flags &= ~URB_NO_SETUP_DMA_MAP;
-
-	return flags;
-}
-
-static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
-
-	/*
-	 * Some members are not still implemented in usbip. I hope this issue
-	 * will be discussed when usbip is ported to other operating systems.
-	 */
-	if (pack) {
-		/* vhci_tx.c */
-		spdu->transfer_flags		= tweak_transfer_flags(urb->transfer_flags);
-
-		spdu->transfer_buffer_length	= urb->transfer_buffer_length;
-		spdu->bandwidth			= urb->bandwidth;
-		spdu->start_frame		= urb->start_frame;
-		spdu->number_of_packets		= urb->number_of_packets;
-		spdu->interval			= urb->interval;
-	} else  {
-		/* stub_rx.c */
-		urb->transfer_flags         = spdu->transfer_flags;
-
-		urb->transfer_buffer_length = spdu->transfer_buffer_length;
-		urb->bandwidth              = spdu->bandwidth;
-		urb->start_frame            = spdu->start_frame;
-		urb->number_of_packets      = spdu->number_of_packets;
-		urb->interval               = spdu->interval;
-	}
-}
-
-static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
-
-	if (pack) {
-		/* stub_tx.c */
-
-		rpdu->status		= urb->status;
-		rpdu->actual_length	= urb->actual_length;
-		rpdu->bandwidth		= urb->bandwidth;
-		rpdu->start_frame	= urb->start_frame;
-		rpdu->error_count	= urb->error_count;
-	} else {
-		/* vhci_rx.c */
-
-		urb->status		= rpdu->status;
-		urb->actual_length	= rpdu->actual_length;
-		urb->bandwidth		= rpdu->bandwidth;
-		urb->start_frame	= rpdu->start_frame;
-		urb->error_count	= rpdu->error_count;
-	}
-}
-
-
-void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack)
-{
-	switch(cmd) {
-		case USBIP_CMD_SUBMIT:
-			usbip_pack_cmd_submit(pdu, urb, pack);
-			break;
-		case USBIP_RET_SUBMIT:
-			usbip_pack_ret_submit(pdu, urb, pack);
-			break;
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-
-
-static void correct_endian_basic(struct usbip_header_basic *base, int send)
-{
-	if (send) {
-		base->command	= cpu_to_be32(base->command);
-		base->busnum	= cpu_to_be32(base->busnum);
-		base->devnum	= cpu_to_be32(base->devnum);
-		base->seqnum	= cpu_to_be32(base->seqnum);
-		base->pipe	= cpu_to_be32(base->pipe);
-	} else {
-		base->command	= be32_to_cpu(base->command);
-		base->busnum	= be32_to_cpu(base->busnum);
-		base->devnum	= be32_to_cpu(base->devnum);
-		base->seqnum	= be32_to_cpu(base->seqnum);
-		base->pipe	= be32_to_cpu(base->pipe);
-	}
-}
-
-static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, int send)
-{
-	if (send) {
-		pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
-
-		cpu_to_be32s(&pdu->transfer_buffer_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->number_of_packets);
-		cpu_to_be32s(&pdu->interval);
-	} else {
-		pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags);
-
-		be32_to_cpus(&pdu->transfer_buffer_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->number_of_packets);
-		be32_to_cpus(&pdu->interval);
-	}
-}
-
-static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, int send)
-{
-	if (send) {
-		cpu_to_be32s(&pdu->status);
-		cpu_to_be32s(&pdu->actual_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->error_count);
-	} else {
-		be32_to_cpus(&pdu->status);
-		be32_to_cpus(&pdu->actual_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->error_count);
-	}
-}
-
-static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, int send)
-{
-	if (send)
-		pdu->seqnum = cpu_to_be32(pdu->seqnum);
-	else
-		pdu->seqnum = be32_to_cpu(pdu->seqnum);
-}
-
-static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, int send)
-{
-	if (send)
-		cpu_to_be32s(&pdu->status);
-	else
-		be32_to_cpus(&pdu->status);
-}
-
-void usbip_header_correct_endian(struct usbip_header *pdu, int send)
-{
-	__u32 cmd = 0;
-
-	if (send)
-		cmd = pdu->base.command;
-
-	correct_endian_basic(&pdu->base, send);
-
-	if (!send)
-		cmd = pdu->base.command;
-
-	switch (cmd) {
-		case USBIP_CMD_SUBMIT:
-			correct_endian_cmd_submit(&pdu->u.cmd_submit, send);
-			break;
-		case USBIP_RET_SUBMIT:
-			correct_endian_ret_submit(&pdu->u.ret_submit, send);
-			break;
-
-		case USBIP_CMD_UNLINK:
-			correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send);
-			break;
-		case USBIP_RET_UNLINK:
-			correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
-			break;
-
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-	
-static void usbip_iso_pakcet_correct_endian(struct usbip_iso_packet_descriptor *iso, int send)
-{
-	/* does not need all members. but copy all simply. */
-	if (send) {
-		iso->offset	= cpu_to_be32(iso->offset);
-		iso->length	= cpu_to_be32(iso->length);
-		iso->status	= cpu_to_be32(iso->status);
-		iso->actual_length = cpu_to_be32(iso->actual_length);
-	} else {
-		iso->offset	= be32_to_cpu(iso->offset);
-		iso->length	= be32_to_cpu(iso->length);
-		iso->status	= be32_to_cpu(iso->status);
-		iso->actual_length = be32_to_cpu(iso->actual_length);
-	}
-}
-
-static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
-		struct usb_iso_packet_descriptor *uiso, int pack)
-{
-	if (pack) {
-		iso->offset		= uiso->offset;
-		iso->length		= uiso->length;
-		iso->status		= uiso->status;
-		iso->actual_length	= uiso->actual_length;
-	} else {
-		uiso->offset		= iso->offset;
-		uiso->length		= iso->length;
-		uiso->status		= iso->status;
-		uiso->actual_length	= iso->actual_length;
-	}
-}
-
-
-/* must free buffer */
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	ssize_t size = np * sizeof(*iso);
-	int i;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return NULL;
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
-		usbip_iso_pakcet_correct_endian(iso, 1);
-	}
-
-	*bufflen = size;
-
-	return buff;
-}
-
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	int size = np * sizeof(*iso);
-	int i;
-	int ret;
-
-	if (!usb_pipeisoc(urb->pipe))
-		return 0;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-
-	ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
-	if (ret != size) {
-		uerr("recv iso_frame_descriptor, %d\n", ret);
-		kfree(buff);
-
-		if (ud->side == USBIP_STUB)
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		else
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-
-		return -EPIPE;
-	}
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_iso_pakcet_correct_endian(iso, 0);
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
-	}
-
-
-	kfree(buff);
-
-	return ret;
-}
-
-
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
-{
-	int ret;
-	int size;
-
-	if (ud->side == USBIP_STUB) {
-		/* stub_rx.c */
-		/* the direction of urb must be OUT. */
-		if (usb_pipein(urb->pipe))
-			return 0;
-
-		size = urb->transfer_buffer_length;
-	} else {
-		/* vhci_rx.c */
-		/* the direction of urb must be IN. */
-		if (usb_pipeout(urb->pipe))
-			return 0;
-
-		size = urb->actual_length;
-	}
-
-	/* no need to recv xbuff */
-	if (!(size > 0))
-		return 0;
-
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) urb->transfer_buffer, size, 0);
-	if (ret != size) {
-		uerr("recv xbuf, %d\n", ret);
-		if (ud->side == USBIP_STUB) {
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		} else {
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-			return -EPIPE;
-		}
-	}
-
-	return ret;
-}
diff -Naur usbip-0.1.4/drivers/2.6.16/usbip_common.h trunk/drivers/2.6.16/usbip_common.h
--- usbip-0.1.4/drivers/2.6.16/usbip_common.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,364 +0,0 @@
-/*
- * $Id: usbip_common.h 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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.
- */
-
-#ifndef  __VHCI_COMMON_H
-#define  __VHCI_COMMON_H
-
-
-#include <linux/usb.h>
-#include <net/sock.h>
-#include <asm/byteorder.h>
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * define macros to print messages
- */
-
-/**
- * udbg - print debug messages if CONFIG_USB_DEBUG is defined
- * @fmt:
- * @args:
- */
-
-#ifdef CONFIG_USB_DEBUG
-
-#define udbg(fmt, args...)						\
-	do{								\
-		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	}while(0)
-
-#else  /* CONFIG_USB_DEBUG */
-
-#define udbg(fmt, args...)		do{ }while(0)
-
-#endif /* CONFIG_USB_DEBUG */
-
-
-enum {
-	usbip_debug_xmit	= (1 << 0),
-	usbip_debug_sysfs	= (1 << 1),
-	usbip_debug_urb		= (1 << 2),
-	usbip_debug_eh		= (1 << 3),
-
-	usbip_debug_stub_cmp	= (1 << 8),
-	usbip_debug_stub_dev	= (1 << 9),
-	usbip_debug_stub_rx	= (1 << 10),
-	usbip_debug_stub_tx	= (1 << 11),
-
-	usbip_debug_vhci_rh	= (1 << 8),
-	usbip_debug_vhci_hc	= (1 << 9),
-	usbip_debug_vhci_rx	= (1 << 10),
-	usbip_debug_vhci_tx	= (1 << 11),
-	usbip_debug_vhci_sysfs  = (1 << 12)
-};
-
-#define dbg_flag_xmit		(usbip_debug_flag & usbip_debug_xmit)
-#define dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
-#define dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
-#define dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
-#define dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
-#define dbg_flag_vhci_sysfs	(usbip_debug_flag & usbip_debug_vhci_sysfs)
-#define dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
-#define dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
-
-extern unsigned long usbip_debug_flag;
-extern struct device_attribute dev_attr_usbip_debug;
-
-#define dbg_with_flag(flag, fmt, args...)		\
-	do {						\
-		if(flag & usbip_debug_flag) 		\
-			udbg(fmt , ##args);		\
-	} while(0)
-
-#define dbg_sysfs(fmt, args...)	dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define dbg_xmit(fmt, args...)	dbg_with_flag(usbip_debug_xmit,  fmt , ##args)
-#define dbg_urb(fmt, args...)	dbg_with_flag(usbip_debug_urb,   fmt , ##args)
-#define dbg_eh(fmt, args...)	dbg_with_flag(usbip_debug_eh,   fmt , ##args)
-
-#define dbg_vhci_rh(fmt, args...) dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
-#define dbg_vhci_hc(fmt, args...) dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
-#define dbg_vhci_rx(fmt, args...) dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
-#define dbg_vhci_tx(fmt, args...) dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define dbg_vhci_sysfs(fmt, args...) dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
-
-#define dbg_stub_cmp(fmt, args...) dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define dbg_stub_rx(fmt, args...) dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define dbg_stub_tx(fmt, args...) dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
-
-
-/**
- * uerr - print error messages
- * @fmt:
- * @args:
- */
-#define uerr(fmt, args...)						\
-	do {								\
-		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	} while(0)
-
-/**
- * uinfo - print information messages
- * @fmt:
- * @args:
- */
-#define uinfo(fmt, args...)					\
-	do {							\
-		printk(KERN_INFO "usbip: " fmt , ## args);	\
-	} while(0)
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * USB/IP packet headers.
- * At now, we define 4 packet types:
- *
- *  - CMD_SUBMIT transfers a USB request. This is corresponding to usb_submit_urb().
- *  - RET_RETURN transfers a result of a USB request.
- *  - CMD_UNLINK transfers an unlink request of a pending USB request.
- *  - RET_UNLINK transfers an unlink request of a pending USB request.
- *
- * TODO:
- *
- *  - inter-operability between other OSs
- */
-
-/*
- * A basic header followed by other additional headers.
- */
-struct usbip_header_basic {
-#define USBIP_CMD_SUBMIT	0x0001
-#define USBIP_CMD_UNLINK	0x0002
-#define USBIP_RET_SUBMIT	0x0003
-#define USBIP_RET_UNLINK	0x0004
-	__u32 command;
-
-	__u32 busnum;
-	__u32 devnum;
-	__u32 seqnum; /* seaquencial number which identifies URBs */
-	__u32 pipe;
-} __attribute__ ((packed));
-
-/*
- * An additional header for a CMD_SUBMIT packet.
- */
-struct usbip_header_cmd_submit {
-	__u32 transfer_flags;
-	__s32 transfer_buffer_length;
-	__s32 bandwidth;
-	__s32 start_frame;
-	__s32 number_of_packets;
-	__s32 interval;
-	unsigned char setup[8]; /* CTRL only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a RET_SUBMIT packet.
- */
-struct usbip_header_ret_submit {
-	__s32 status;
-	__s32 actual_length; /* returned data length */
-	__s32 bandwidth;
-	__s32 start_frame; /* ISO and INT */
-	__s32 number_of_packets;  /* ISO only */
-	__s32 error_count; /* ISO only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a CMD_UNLINK packet.
- */
-struct usbip_header_cmd_unlink {
-	__u32 seqnum; /* URB's seqnum which will be unlinked */
-}__attribute__ ((packed));
-
-
-/*
- * An additional header for a RET_UNLINK packet.
- */
-struct usbip_header_ret_unlink {
-	__s32 status;
-}__attribute__ ((packed));
-
-
-/* the same as usb_iso_packet_descriptor but packed for pdu */
-struct usbip_iso_packet_descriptor {
-	__u32 offset;
-	__u32 length;            /* expected length */
-	__u32 actual_length;
-	__u32 status;
-}__attribute__ ((packed));
-
-
-/*
- * All usbip packets use a common header to keep code simple.
- */
-struct usbip_header {
-	struct usbip_header_basic base;
-
-	union {
-		struct usbip_header_cmd_submit	cmd_submit;
-		struct usbip_header_ret_submit	ret_submit;
-		struct usbip_header_cmd_unlink	cmd_unlink;
-		struct usbip_header_ret_unlink	ret_unlink;
-	} u;
-}__attribute__ ((packed));
-
-
-
-
-/*-------------------------------------------------------------------------*/
-
-
-int usbip_xmit(int , struct socket *, char *, int , int );
-int usbip_sendmsg(struct socket *, struct msghdr *, int );
-
-
-static inline int interface_to_busnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->bus->busnum;
-}
-
-static inline int interface_to_devnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->devnum;
-}
-
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
-	return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-struct socket *sockfd_to_socket(unsigned int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-
-
-void usbip_dump_urb (struct urb *purb);
-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,
-};
-
-enum usbip_status {
-	/* sdev is available. */
-	SDEV_ST_AVAILABLE = 0x01,
-	/* sdev is now used. */
-	SDEV_ST_USED,
-	/* sdev is unusable because of a fatal error. */
-	SDEV_ST_ERROR,
-
-	/* vdev does not connect a remote device. */
-	VDEV_ST_NULL,
-	/* vdev is used, but the USB address is not assigned yet */
-	VDEV_ST_NOTASSIGNED,
-	VDEV_ST_USED,
-	VDEV_ST_ERROR
-};
-
-/* a common structure for stub_device and vhci_device */
-struct usbip_device{
-	enum usbip_side side;
-
-	enum usbip_status status;
-
-	/* lock for status */
-	spinlock_t lock;
-
-	struct socket *tcp_socket;
-
-	struct usbip_task tcp_rx;
-	struct usbip_task tcp_tx;
-
-	/* event handler */
-#define USBIP_EH_SHUTDOWN	(1 << 0)
-#define USBIP_EH_BYE		(1 << 1)
-#define USBIP_EH_RESET		(1 << 2)
-#define USBIP_EH_UNUSABLE	(1 << 3)
-
-#define SDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
-#define	SDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_SUBMIT		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE )
-
-#define	VDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
-#define	VDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
-
-	unsigned long event;
-	struct usbip_task eh;
-	wait_queue_head_t eh_waitq;
-
-	struct eh_ops {
-		void (*shutdown)(struct usbip_device *);
-		void (*reset)(struct usbip_device *);
-		void (*unusable)(struct usbip_device *);
-	} eh_ops;
-};
-
-
-void usbip_task_init(struct usbip_task *ut, char *, void (*loop_ops)(struct usbip_task *));
-
-void 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);
-void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
-
-
-/* usbip_event.c */
-void usbip_start_eh(struct usbip_device *ud);
-void usbip_stop_eh(struct usbip_device *ud);
-void usbip_event_add(struct usbip_device *ud, unsigned long event);
-int usbip_event_happend(struct usbip_device *ud);
-
-
-#endif
diff -Naur usbip-0.1.4/drivers/2.6.16/usbip_event.c trunk/drivers/2.6.16/usbip_event.c
--- usbip-0.1.4/drivers/2.6.16/usbip_event.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/usbip_event.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,153 +0,0 @@
-/*
- * $Id: usbip_event.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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 void event_handler_loop(struct usbip_task *eh);
-
-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((int(*)(void *)) usbip_thread, (void *) eh, 0);
-
-	wait_for_completion(&eh->thread_done);
-}
-
-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");
-}
-
-
-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);
-}
-
-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;
-}
-
-
-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 */
-		uerr("unknown event\n");
-		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");
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.16/vhci.h trunk/drivers/2.6.16/vhci.h
--- usbip-0.1.4/drivers/2.6.16/vhci.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/vhci.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,143 +0,0 @@
-/*
- * $Id: vhci.h 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/platform_device.h>
-#include HCD_HEADER
-
-
-struct vhci_device {
-	struct usb_device *udev;
-
-	/* busnum and devnum of a remote device */
-	__u32 busnum;
-	__u32 devnum;
-
-	/* speed of a remote device */
-	enum usb_device_speed speed;
-
-	/*  vhci root-hub port to which this device is attached  */
-	__u32 rhport;
-
-	struct usbip_device ud;
-
-
-	/* lock for the below link lists */
-	spinlock_t priv_lock;
-
-	/* vhci_priv is linked to one of them. */
-	struct list_head priv_tx;
-	struct list_head priv_rx;
-
-	/* vhci_unlink is linked to one of them */
-	struct list_head unlink_tx;
-	struct list_head unlink_rx;
-
-	/* vhci_tx thread sleeps for this queue */
-	wait_queue_head_t waitq_tx;
-};
-
-
-/* urb->hcpriv, use container_of() */
-struct vhci_priv {
-	unsigned long seqnum;
-	struct list_head list;
-
-	struct vhci_device *vdev;
-	struct urb *urb;
-};
-
-
-struct vhci_unlink {
-	/* seqnum of this request */
-	unsigned long seqnum;
-
-	struct list_head list;
-
-	/* seqnum of the unlink target */
-	unsigned long unlink_seqnum;
-};
-
-/*
- * The number of ports is less than 16 ?
- * USB_MAXCHILDREN is statically defined to 16 in usb.h.  Its maximum value
- * would be 31 because the event_bits[1] of struct usb_hub is defined as
- * unsigned long in hub.h
- */
-#define VHCI_NPORTS 8
-
-/* for usb_bus.hcpriv */
-struct vhci_hcd {
-	spinlock_t	lock;
-
-	u32	port_status[VHCI_NPORTS];
-
-	unsigned	resuming:1;
-	unsigned long	re_timeout;
-
-	atomic_t seqnum;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 * But, the index of this array begins from 0.
-	 */
-	struct vhci_device vdev[VHCI_NPORTS];
-
-	/* vhci_device which has not been assiged its address yet */
-	int pending_port;
-};
-
-
-extern struct vhci_hcd *the_controller;
-extern struct attribute_group dev_attr_group;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declaration */
-
-/* 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);
-
-#define hardware		(&the_controller->pdev.dev)
-
-static inline struct vhci_device *port_to_vdev(__u32 port)
-{
-	return &the_controller->vdev[port];
-}
-
-static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd)
-{
-	return (struct vhci_hcd *) (hcd->hcd_priv);
-}
-
-static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci)
-{
-	return container_of((void *) vhci, struct usb_hcd, hcd_priv);
-}
-
-static inline struct device *vhci_dev(struct vhci_hcd *vhci)
-{
-	return vhci_to_hcd(vhci)->self.controller;
-}
diff -Naur usbip-0.1.4/drivers/2.6.16/vhci_hcd.c trunk/drivers/2.6.16/vhci_hcd.c
--- usbip-0.1.4/drivers/2.6.16/vhci_hcd.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/vhci_hcd.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1174 +0,0 @@
-/*
- * $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-#define DRIVER_VERSION " $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $ "
-#define DRIVER_AUTHOR "HIROFUCHI Takahiro <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
-#define DRIVER_LICENCE "GPL"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENCE);
-
-
-
-/*
- * TODO
- * 	- update root hub emulation
- * 	- move the emulation code to userland ?
- * 		poring to other operating systems
- * 		minimize kernel code
- * 	- add suspend/resume code
- * 	- clean up everything
- */
-
-
-/* See usb gadget dummy hcd */
-
-
-static int vhci_hub_status (struct usb_hcd *hcd, char *buff);
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buff, u16 wLength);
-static int vhci_urb_enqueue (struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags);
-static int vhci_urb_dequeue( struct usb_hcd *hcd, struct urb *urb);
-static int vhci_start(struct usb_hcd *vhci_hcd);
-static void vhci_stop(struct usb_hcd *hcd);
-static int vhci_get_frame_number(struct usb_hcd *hcd);
-
-static const char driver_name[] = "vhci_hcd";
-static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
-
-
-
-
-struct vhci_hcd *the_controller = NULL;
-
-
-static const char *bit_desc[] = {
-	"CONNECTION",		/*0*/
-	"ENABLE",		/*1*/
-	"SUSPEND",		/*2*/
-	"OVER_CURRENT",		/*3*/
-	"RESET",		/*4*/
-	"R5",		/*5*/
-	"R6",		/*6*/
-	"R7",		/*7*/
-	"POWER",		/*8*/
-	"LOWSPEED",		/*9*/
-	"HIGHSPEED",		/*10*/
-	"PORT_TEST",		/*11*/
-	"INDICATOR",		/*12*/
-	"R13",		/*13*/
-	"R14",		/*14*/
-	"R15",		/*15*/
-	"C_CONNECTION",		/*16*/
-	"C_ENABLE",		/*17*/
-	"C_SUSPEND",		/*18*/
-	"C_OVER_CURRENT",	/*19*/
-	"C_RESET",		/*20*/
-	"R21",		/*21*/
-	"R22",		/*22*/
-	"R23",		/*23*/
-	"R24",		/*24*/
-	"R25",		/*25*/
-	"R26",		/*26*/
-	"R27",		/*27*/
-	"R28",		/*28*/
-	"R29",		/*29*/
-	"R30",		/*30*/
-	"R31",		/*31*/
-};
-
-
-static void dump_port_status(u32 status)
-{
-	int i = 0;
-
-	printk("status %08x:", status);
-	for (i = 0; i < 32; i++) {
-		if (status & (1 << i)) {
-			printk(" %s", bit_desc[i]);
-		}
-	}
-
-	printk("\n");
-}
-
-
-
-void rh_port_connect(int rhport, enum usb_device_speed speed)
-{
-	unsigned long	flags;
-
-	dbg_vhci_rh("rh_port_connect %d\n", rhport);
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
-		| (1 << USB_PORT_FEAT_C_CONNECTION);
-
-	switch (speed) {
-		case USB_SPEED_HIGH:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-			break;
-		case USB_SPEED_LOW:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-			break;
-		default:
-			break;
-	}
-
-	//spin_lock(&the_controller->vdev[rhport].ud.lock);
-	//the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
-	//spin_unlock(&the_controller->vdev[rhport].ud.lock);
-
-	the_controller->pending_port = rhport;
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-}
-
-void rh_port_disconnect(int rhport)
-{
-	unsigned long flags;
-
-	dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-	//stop_activity (dum, driver);
-	the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
-	the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION);
-
-
-	/* not yet complete the disconnection */
-	//spin_lock(&vdev->ud.lock);
-	//vdev->ud.status = VHC_ST_DISCONNECT;
-	//spin_unlock(&vdev->ud.lock);
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-#define PORT_C_MASK \
-	((USB_PORT_STAT_C_CONNECTION \
-	  | USB_PORT_STAT_C_ENABLE \
-	  | USB_PORT_STAT_C_SUSPEND \
-	  | USB_PORT_STAT_C_OVERCURRENT \
-	  | USB_PORT_STAT_C_RESET) << 16)
-
-/*
- * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without
- * suspend/resume support. But, it is modified to provide multiple ports.
- *
- * @buf: a bitmap to show which port status has been changed.
- *  bit  0: reserved or used for another purpose?
- *  bit  1: the status of port 0 has been changed.
- *  bit  2: the status of port 1 has been changed.
- *  ...
- *  bit  7: the status of port 6 has been changed.
- *  bit  8: the status of port 7 has been changed.
- *  ...
- *  bit 15: the status of port 14 has been changed.
- *
- * So, the maximum number of ports is 31 ( port 0 to port 30) ?
- *
- * The return value is the actual transfered length in byte. If nothing has
- * been changed, return 0. In the case that the number of ports is less than or
- * equal to 6 (VHCI_NPORTS==7), return 1.
- *
- */
-static int vhci_hub_status (struct usb_hcd *hcd, char *buf)
-{
-	struct vhci_hcd	*vhci;
-	unsigned long	flags;
-	int		retval = 0;
-
-	/* the enough buffer is allocated according to USB_MAXCHILDREN */
-	unsigned long	*event_bits = (unsigned long *) buf;
-	int		rhport;
-	int		changed = 0;
-
-
-	*event_bits = 0;
-
-	vhci = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&vhci->lock, flags);
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		dbg_vhci_rh("hw accessible flag in on?\n");
-		goto done;
-	}
-
-	/* check pseudo status register for each port */
-	for(rhport = 0; rhport < VHCI_NPORTS; rhport++) {
-		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
-			/* The status of a port has been changed, */
-			dbg_vhci_rh("port %d is changed\n", rhport);
-
-			*event_bits |= 1 << ( rhport + 1);
-			changed = 1;
-		}
-	}
-
-	if (changed)
-		retval = 1 + (VHCI_NPORTS / 8);
-	else
-		retval = 0;
-
-done:
-	spin_unlock_irqrestore (&vhci->lock, flags);
-	return retval;
-}
-
-/* See hub_configure in hub.c */
-static inline void hub_descriptor(struct usb_hub_descriptor *desc)
-{
-	memset(desc, 0, sizeof(*desc));
-	desc->bDescriptorType = 0x29;
-	desc->bDescLength = 9;
-	desc->wHubCharacteristics = (__force __u16)
-		(__constant_cpu_to_le16 (0x0001));
-	desc->bNbrPorts = VHCI_NPORTS;
-	desc->bitmap [0] = 0xff;
-	desc->bitmap [1] = 0xff;
-}
-
-
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
-{
-	struct vhci_hcd	*dum;
-	int             retval = 0;
-	unsigned long   flags;
-	int		rhport;
-
-	u32 prev_port_status[VHCI_NPORTS];
-
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
-		return -ETIMEDOUT;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 */
-	dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex);
-	if (wIndex > VHCI_NPORTS)
-		uerr("invalid port number %d\n", wIndex);
-	rhport = ((__u8 ) (wIndex & 0x00ff)) -1;
-
-	dum = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&dum->lock, flags);
-
-	/* store old status and compare now and old later */
-	if (dbg_flag_vhci_rh) {
-		int i = 0;
-		for (i = 0; i < VHCI_NPORTS; i++)
-			prev_port_status[i] = dum->port_status[i];
-	}
-
-	switch (typeReq) {
-		case ClearHubFeature:
-			dbg_vhci_rh(" ClearHubFeature\n");
-			break;
-		case ClearPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					if (dum->port_status[rhport] & (1 << USB_PORT_FEAT_SUSPEND)) {
-						/* 20msec signaling */
-						dum->resuming = 1;
-						dum->re_timeout = jiffies + msecs_to_jiffies(20);
-					}
-					break;
-				case USB_PORT_FEAT_POWER:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
-					dum->port_status[rhport] = 0;
-					//dum->address = 0;
-					//dum->hdev = 0;
-					dum->resuming = 0;
-					break;
-				case USB_PORT_FEAT_C_RESET:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_C_RESET\n");
-					switch (dum->vdev[rhport].speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							break;
-					}
-				default:
-					dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
-					dum->port_status[rhport] &= ~(1 << wValue);
-			}
-			break;
-		case GetHubDescriptor:
-			dbg_vhci_rh(" GetHubDescriptor\n");
-			hub_descriptor ((struct usb_hub_descriptor *) buf);
-			break;
-		case GetHubStatus:
-			dbg_vhci_rh(" GetHubStatus\n");
-			*(u32 *) buf = __constant_cpu_to_le32 (0);
-			break;
-		case GetPortStatus:
-			dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
-			if (wIndex > VHCI_NPORTS || wIndex < 1) {
-				uerr(" invalid port number %d\n", wIndex);
-				retval = -EPIPE;
-			}
-
-			/* we do no care of resume. */
-
-			/* whoever resets or resumes must GetPortStatus to
-			 * complete it!!
-			 *                                   */
-			if (dum->resuming && time_after (jiffies, dum->re_timeout)) {
-				uerr(" not yet\n");
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_SUSPEND);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_SUSPEND);
-				dum->resuming = 0;
-				dum->re_timeout = 0;
-				//if (dum->driver && dum->driver->resume) {
-				//	spin_unlock (&dum->lock);
-				//	dum->driver->resume (&dum->gadget);
-				//	spin_lock (&dum->lock);
-				//}
-			}
-
-			if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != 0
-					&& time_after (jiffies, dum->re_timeout)) {
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_RESET);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_RESET);
-				dum->re_timeout = 0;
-
-				if (dum->vdev[rhport].ud.status == VDEV_ST_NOTASSIGNED) {
-					dbg_vhci_rh(" enable rhport %d (status %u)\n", rhport, dum->vdev[rhport].ud.status);
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-				}
-#if 0
-				if (dum->driver) {
-
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-					/* give it the best speed we agree on */
-					dum->gadget.speed = dum->driver->speed;
-					dum->gadget.ep0->maxpacket = 64;
-					switch (dum->gadget.speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->gadget.ep0->maxpacket = 8;
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							dum->gadget.speed = USB_SPEED_FULL;
-							break;
-					}
-				}
-#endif
-
-			}
-			((u16 *) buf)[0] = cpu_to_le16 (dum->port_status[rhport]);
-			((u16 *) buf)[1] = cpu_to_le16 (dum->port_status[rhport] >> 16);
-
-			dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], ((u16 *)buf)[1] );
-			break;
-		case SetHubFeature:
-			dbg_vhci_rh(" SetHubFeature\n");
-			retval = -EPIPE;
-			break;
-		case SetPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_SUSPEND\n");
-					uerr(" not yet\n");
-#if 0
-					dum->port_status[rhport] |= (1 << USB_PORT_FEAT_SUSPEND);
-					if (dum->driver->suspend) {
-						spin_unlock (&dum->lock);
-						dum->driver->suspend (&dum->gadget);
-						spin_lock (&dum->lock);
-					}
-#endif
-					break;
-				case USB_PORT_FEAT_RESET:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
-					/* if it's already running, disconnect first */
-					if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
-						dum->port_status[rhport] &= ~(USB_PORT_STAT_ENABLE
-								| USB_PORT_STAT_LOW_SPEED
-								| USB_PORT_STAT_HIGH_SPEED);
-#if 0
-						if (dum->driver) {
-							dev_dbg (hardware, "disconnect\n");
-							stop_activity (dum, dum->driver);
-						}
-#endif
-
-						/* FIXME test that code path! */
-					}
-					/* 50msec reset signaling */
-					dum->re_timeout = jiffies + msecs_to_jiffies(50);
-
-					/* FALLTHROUGH */
-				default:
-					dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
-					dum->port_status[rhport] |= (1 << wValue);
-			}
-			break;
-
-		default:
-			uerr(" default: no such request\n");
-			//dev_dbg (hardware,
-			//		"hub control req%04x v%04x i%04x l%d\n",
-			//		typeReq, wValue, wIndex, wLength);
-
-			/* "protocol stall" on error */
-			retval = -EPIPE;
-	}
-
-	if (dbg_flag_vhci_rh) {
-		printk("port %d\n", rhport);
-		dump_port_status(prev_port_status[rhport]);
-		dump_port_status(dum->port_status[rhport]);
-	}
-	dbg_vhci_rh(" bye\n");
-
-	spin_unlock_irqrestore (&dum->lock, flags);
-
-	return retval;
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-static struct vhci_device *get_vdev(struct usb_device *udev)
-{
-	int i;
-
-	if (!udev)
-		return NULL;
-
-	for (i=0; i < VHCI_NPORTS; i++)
-		if (the_controller->vdev[i].udev == udev)
-			return port_to_vdev(i);
-
-	return NULL;
-}
-
-static void vhci_tx_urb(struct urb *urb)
-{
-	struct vhci_device *vdev = get_vdev(urb->dev);
-	struct vhci_priv *priv;
-	unsigned long flag;
-
-	if (!vdev)
-		BUG();
-
-	spin_lock_irqsave(&vdev->priv_lock, flag);
-
-	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
-	if (!priv) {
-		uerr("malloc vhci_priv\n");
-		spin_unlock_irqrestore(&vdev->priv_lock, flag);
-		usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
-	if (priv->seqnum == 0xffff)
-		uinfo("seqnum max\n");
-
-	priv->vdev = vdev;
-	priv->urb = urb;
-
-	urb->hcpriv = (void *) priv;
-
-
-	list_add_tail(&priv->list, &vdev->priv_tx);
-
-	wake_up(&vdev->waitq_tx);
-	spin_unlock_irqrestore(&vdev->priv_lock, flag);
-}
-
-static int vhci_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags);
-
-
-
-	/* patch to usb_sg_init() is in 2.5.60 */
-	BUG_ON (!urb->transfer_buffer && urb->transfer_buffer_length);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-
-	/* check HC is active or not */
-	if (!HC_IS_RUNNING(hcd->state)) {
-		uerr("HC is not running\n");
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return  -ENODEV;
-	}
-
-	if (urb->status != -EINPROGRESS) {
-		uerr("URB already unlinked!, status %d\n", urb->status);
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return urb->status;
-	}
-
-	/*
-	 * The enumelation process is as follows;
-	 *
-	 *  1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
-	 *     to get max packet length of default pipe
-	 *
-	 *  2. Set_Address request to DevAddr(0) EndPoint(0)
-	 *
-	 */
-
-	if (usb_pipedevice(urb->pipe) == 0) {
-		__u8 type = usb_pipetype(urb->pipe);
-		struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet;
-		struct vhci_device *vdev = port_to_vdev(the_controller->pending_port);
-
-		if (type != PIPE_CONTROL || !ctrlreq ) {
-			uerr("invalid request to devnum 0\n");
-			ret = EINVAL;
-			goto no_need_xmit;
-		}
-
-		switch (ctrlreq->bRequest) {
-
-			case USB_REQ_SET_ADDRESS:
-				vdev->udev = urb->dev;
-				dbg_vhci_hc("SetAddress Request (%d) to port %d\n",
-						ctrlreq->wValue, vdev->rhport);
-
-				spin_lock(&vdev->ud.lock);
-				vdev->ud.status = VDEV_ST_USED;
-				spin_unlock(&vdev->ud.lock);
-
-				spin_lock (&urb->lock);
-				if (urb->status == -EINPROGRESS) {
-					/* This request is successfully completed. */
-					/* If not -EINPROGRESS, possibly unlinked. */
-					urb->status = 0;
-				}
-				spin_unlock (&urb->lock);
-
-				goto no_need_xmit;
-
-			case USB_REQ_GET_DESCRIPTOR:
-				if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
-					dbg_vhci_hc("Not yet?: Get_Descriptor to device 0 (get max pipe size)\n");
-
-				vdev->udev = urb->dev;
-				goto out;
-
-			default:
-				/* NOT REACHED */
-				uerr("invalid request to devnum 0 bRequest %u, wValue %u\n",
-						ctrlreq->bRequest, ctrlreq->wValue);
-				ret =  -EINVAL;
-				goto no_need_xmit;
-		}
-
-	}
-
-out:
-
-
-	vhci_tx_urb(urb);
-
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-
-	return 0;
-
-
-no_need_xmit:
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-	return 0;
-}
-
-
-/*
- * vhci_rx gives back the urb after recieving the reply of the urb.  If an
- * unlink pdu is sent or not, vhci_rx recieves a normal return pdu and gives
- * back its urb. For the driver unlinking the urb, the content of the urb is
- * not important, but the calling to its completion handler is important; the
- * completion of unlinking is notified by the completion handler.
- *
- *
- * CLIENT SIDE
- *
- * - When vhci_hcd recieves RET_SUBMIT,
- *
- *	- case 1a). the urb of the pdu is not unlinking.
- *		- normal case
- *		=> just give back the urb
- *
- *	- case 1b). the urb of the pdu is unlinking.
- *		- usbip.ko will return a reply of the unlinking request.
- *		=> give back the urb now and go to case 2b).
- *
- * - When vhci_hcd recieves RET_UNLINK,
- *
- *   	- case 2a). a submit request is still pending in vhci_hcd.
- *   		- urb was really pending in usbip.ko and urb_unlink_urb() was
- *   		  completed there.
- *   		=> free a pending submit request
- *   		=> notify unlink completeness by giving back the urb
- *
- *   	- case 2b). a submit request is *not* pending in vhci_hcd.
- *   		- urb was already given back to the core driver.
- *   		=> do not give back the urb
- *
- *
- * SERVER SIDE
- *
- * - When usbip recieves CMD_UNLINK,
- *
- *	- case 3a). the urb of the unlink request is now in submission.
- *		=> do usb_unlink_urb().
- *		=> after the unlink is completed, send RET_UNLINK.
- *
- *	- case 3b). the urb of the unlink request is not in submission.
- *		- may be already completed or never be recieved
- *		=> send RET_UNLINK
- *
- */
-static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-{
-	unsigned long flags;
-	struct vhci_priv *priv;
-	struct vhci_device *vdev;
-
-	uinfo("vhci_hcd: dequeue a urb %p\n", urb);
-
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	priv = urb->hcpriv;
-	if (!priv) {
-		/* URB was never linked! or will be soon given back by vhci_rx. */
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return 0;
-	}
-
-	 /* send unlink request here? */
-	vdev = priv->vdev;
-
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		unsigned long flags2;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
-		list_del(&priv->list);
-		kfree(priv);
-		urb->hcpriv = NULL;
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-
-	} else {
-		/* tcp connection is alive */
-		unsigned long flags2;
-		struct vhci_unlink *unlink;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		/* setup CMD_UNLINK pdu */
-		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
-		if (!unlink) {
-			uerr("malloc vhci_unlink\n");
-			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-			spin_unlock_irqrestore(&the_controller->lock, flags);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-			return -ENOMEM;
-		}
-
-		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
-		if (unlink->seqnum == 0xffff)
-			uinfo("seqnum max\n");
-
-		unlink->unlink_seqnum = priv->seqnum;
-
-		uinfo("vhci_hcd: device %p seems to be still connected\n", vdev);
-
-		/* send cmd_unlink and try to cancel the pending URB in the peer */
-		list_add_tail(&unlink->list, &vdev->unlink_tx);
-		wake_up(&vdev->waitq_tx);
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-	}
-	
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-	/*
-	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will recieve RET_UNLINK and giveb back the URB.
-	 * Otherwise, we give back it here.
-	 */
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	dbg_vhci_hc("leave\n");
-	return 0;
-}
-
-
-static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock(&vdev->priv_lock);
-}
-
-/*
- * The important thing is that only one context begins cleanup.
- * This is why error handling and cleanup become simple.
- * We do not want to consider race condition as possible.
- */
-static void vhci_shutdown_connection(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	/* need this? see stub_dev.c */
-	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	usbip_stop_threads(&vdev->ud);
-	uinfo("stop threads\n");
-
-	/* active connection is closed */
-	if (vdev->ud.tcp_socket != NULL) {
-		sock_release(vdev->ud.tcp_socket);
-		vdev->ud.tcp_socket = NULL;
-	}
-	uinfo("release socket\n");
-
-	vhci_device_unlink_cleanup(vdev);
-
-	/*
-	 * rh_port_disconnect() is a trigger of ...
-	 *   usb_disable_device():
-	 * 	disable all the endpoints for a USB device.
-	 *   usb_disable_endpoint():
-	 * 	disable endpoints. pending urbs are unlinked(dequeued).
-	 *
-	 * NOTE: After calling rh_port_disconnect(), the USB device driver of a
-	 * deteched device should release used urbs in a cleanup function(i.e.
-	 * xxx_disconnect()). Therefore, vhci_hcd does not need to release
-	 * pushed urbs and their private data in this function.
-	 *
-	 * NOTE: vhci_dequeue() must be considered carefully. When shutdowning
-	 * a connection, vhci_shutdown_connection() expects vhci_dequeue()
-	 * gives back pushed urbs and frees their private data by request of
-	 * the cleanup function of a USB driver. When unlinking a urb with an
-	 * active connection, vhci_dequeue() does not give back the urb which
-	 * is actually given back by vhci_rx after recieving its return pdu.
-	 *
-	 */
-	rh_port_disconnect(vdev->rhport);
-
-	uinfo("disconnect device\n");
-}
-
-
-static void vhci_device_reset(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	spin_lock(&ud->lock);
-
-	vdev->busnum = 0;
-	vdev->devnum = 0;
-	vdev->speed  = 0;
-
-	ud->tcp_socket = NULL;
-
-	ud->status = VDEV_ST_NULL;
-
-	spin_unlock(&ud->lock);
-}
-
-static void vhci_device_unusable(struct usbip_device* ud)
-{
-	spin_lock(&ud->lock);
-
-	ud->status = VDEV_ST_ERROR;
-
-	spin_unlock(&ud->lock);
-}
-
-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.side   = USBIP_VHCI;
-	vdev->ud.status = VDEV_ST_NULL;
-	vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
-
-	INIT_LIST_HEAD(&vdev->priv_rx);
-	INIT_LIST_HEAD(&vdev->priv_tx);
-	INIT_LIST_HEAD(&vdev->unlink_tx);
-	INIT_LIST_HEAD(&vdev->unlink_rx);
-	vdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	init_waitqueue_head(&vdev->waitq_tx);
-
-	vdev->ud.eh_ops.shutdown = vhci_shutdown_connection;
-	vdev->ud.eh_ops.reset = vhci_device_reset;
-	vdev->ud.eh_ops.unusable= vhci_device_unusable;
-
-	usbip_start_eh(&vdev->ud);
-}
-
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_start(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport;
-
-	dbg_vhci_hc("enter vhci_start\n");
-
-
-	/* initialize private data of usb_hcd */
-
-	for(rhport=0; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-		vhci_device_init(vdev);
-		vdev->rhport = rhport;
-	}
-
-	atomic_set(&vhci->seqnum, 0);
-	spin_lock_init(&vhci->lock);
-
-
-
-	//hcd->power_budget = 0; /* no limit ? */
-	hcd->state  = HC_STATE_RUNNING;
-	//hcd->uses_new_polling = 1;
-
-
-	/* vhci_hcd is now ready to be controlled through sysfs */
-	sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	return 0;
-}
-
-static void vhci_stop(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport = 0;
-
-	dbg_vhci_hc("stop VHCI controller\n");
-
-
-	/* 1. remove the userland interface of vhci_hcd */
-	sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	/* 2. shutdown all the ports of vhci_hcd */
-	for(rhport = 0 ; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-
-		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
-		usbip_stop_eh(&vdev->ud);
-	}
-
-
-	uinfo("vhci_stop done\n");
-}
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_get_frame_number(struct usb_hcd *hcd)
-{
-	uerr("Not yet implemented\n");
-	return 0;
-}
-
-
-#ifdef  CONFIG_PM
-
-static int vhci_bus_suspend(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-static int vhci_bus_resume(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-#else
-
-#define vhci_bus_suspend      NULL
-#define vhci_bus_resume       NULL
-#endif
-
-
-
-static struct hc_driver vhci_hc_driver = {
-	.description	= driver_name,
-	.product_desc	= driver_desc,
-	.hcd_priv_size	= sizeof(struct vhci_hcd),
-
-	.flags		= HCD_USB2,
-
-	.start		= vhci_start,
-	.stop 		= vhci_stop,
-
-	.urb_enqueue	= vhci_urb_enqueue,
-	.urb_dequeue	= vhci_urb_dequeue,
-
-	.get_frame_number = vhci_get_frame_number,
-
-	.hub_status_data = vhci_hub_status,
-	.hub_control    = vhci_hub_control,
-	.bus_suspend	= vhci_bus_suspend,
-	.bus_resume	= vhci_bus_resume,
-};
-
-static int vhci_hcd_probe(struct platform_device *pdev)
-{
-	struct usb_hcd		*hcd;
-	int			ret;
-
-	uinfo("proving...\n");
-
-	dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
-
-
-	/* will be removed */
-	if (pdev->dev.dma_mask) {
-		info("vhci_hcd DMA not supported\n");
-		return -EINVAL;
-	}
-
-
-	/*
-	 * Allocate and initialize hcd.
-	 * Our private data is also allocated automatically.
-	 */
-	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id);
-	if (!hcd) {
-		uerr("create hcd failed\n");
-		return -ENOMEM;
-	}
-
-
-	/* this is private data for vhci_hcd */
-	the_controller = hcd_to_vhci(hcd);
-
-	/*
-	 * Finish generic HCD structure initialization and register.
-	 * Call the driver's reset() and start() routines.
-	 */
-	ret = usb_add_hcd(hcd, 0, 0);
-	if (ret != 0) {
-		uerr("usb_add_hcd failed %d\n", ret);
-		usb_put_hcd(hcd);
-		the_controller = NULL;
-		return ret;
-	}
-	
-
-	dbg_vhci_hc("bye\n");
-	return 0;
-}
-
-
-static int vhci_hcd_remove(struct platform_device *pdev)
-{
-	struct usb_hcd	*hcd;
-
-
-	hcd = platform_get_drvdata(pdev);
-	if(!hcd)
-		return 0;
-
-	/*
-	 * Disconnects the root hub,
-	 * then reverses the effects of usb_add_hcd(),
-	 * invoking the HCD's stop() methods.
-	 */
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-	the_controller = NULL;
-
-
-	return 0;
-}
-
-
-
-#ifdef CONFIG_PM
-
-/* what should happen for USB/IP under suspend/resume? */
-static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = state;
-
-	return 0;
-}
-
-static int vhci_hcd_resume(struct platform_device *pdev)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	return 0;
-}
-
-#else
-
-#define vhci_hcd_suspend	NULL
-#define vhci_hcd_resume		NULL
-
-#endif
-
-
-static struct platform_driver vhci_driver = {
-	.probe	= vhci_hcd_probe,
-	.remove	= __devexit_p(vhci_hcd_remove),
-	.suspend = vhci_hcd_suspend,
-	.resume	= vhci_hcd_resume,
-	.driver	= {
-		.name = (char *) driver_name,
-		.owner = THIS_MODULE,
-	},
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
- * We need to add this virtual device as a platform device arbitrarily:
- * 	1. platform_device_register()
- */
-static void the_pdev_release(struct device *dev)
-{
-	return;
-}
-
-static struct platform_device the_pdev = {
-	/* should be the same name as driver_name */
-	.name = (char *) driver_name,
-	.id = -1,
-	.dev = {
-		//.driver = &vhci_driver,
-		.release = the_pdev_release,
-	},
-};
-
-static int __init vhci_init(void)
-{
-	int ret;
-
-	dbg_vhci_hc("enter\n");
-	if (usb_disabled())
-		return -ENODEV;
-
-	info("driver %s, %s\n", driver_name, DRIVER_VERSION);
-
-	ret = platform_driver_register(&vhci_driver);
-	if (ret < 0)
-		goto err_driver_register;
-
-	ret = platform_device_register(&the_pdev);
-	if (ret < 0)
-		goto err_platform_device_register;
-
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-
-
-
-	/* error occurred */
-
-err_platform_device_register:
-	platform_driver_unregister(&vhci_driver);
-
-err_driver_register:
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-}
-module_init(vhci_init);
-
-
-static void __exit vhci_cleanup(void)
-{
-	dbg_vhci_hc("enter\n");
-
-	platform_device_unregister(&the_pdev);
-	platform_driver_unregister(&vhci_driver);
-
-	dbg_vhci_hc("bye\n");
-}
-module_exit(vhci_cleanup);
diff -Naur usbip-0.1.4/drivers/2.6.16/vhci_rx.c trunk/drivers/2.6.16/vhci_rx.c
--- usbip-0.1.4/drivers/2.6.16/vhci_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/vhci_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,239 +0,0 @@
-/*
- * $Id: vhci_rx.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
-{
-	struct vhci_priv *priv, *tmp;
-	struct urb *urb = NULL;
-
-
-	spin_lock(&vdev->priv_lock);
-
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
-		if (priv->seqnum == seqnum) {
-			urb = priv->urb;
-			dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", urb, priv, seqnum);
-
-
-			if (urb->status != -EINPROGRESS) {
-				 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
-					 uinfo("urb %p was unlinked %ssynchronuously.\n",
-							 urb, urb->status == -ENOENT ? "" : "a");
-				 } else {
-					 uinfo("urb %p may be in a error, status %d\n",
-							 urb, urb->status);
-				 }
-			}
-
-
-			list_del(&priv->list);
-			kfree(priv);
-			urb->hcpriv = NULL;
-
-
-			break;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-
-	return urb;
-}
-
-static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &vdev->ud;
-	struct urb *urb;
-
-
-	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
-
-
-	if (!urb) {
-		uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
-		uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-
-	/* unpack the pdu to a urb */
-	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
-
-
-	/* recv transfer buffer */
-	if (usbip_recv_xbuff(ud, urb) < 0)
-		return;
-
-
-	/* recv iso_packet_descriptor */
-	if (usbip_recv_iso(ud, urb) < 0)
-		return;
-
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_urb(urb);
-
-
-	dbg_vhci_rx("now giveback urb %p\n", urb);
-
-
-
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-
-	dbg_vhci_rx("Leave\n");
-
-	return;
-}
-
-
-static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
-		struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		uinfo("unlink->seqnum %lu\n", unlink->seqnum);
-		if (unlink->seqnum == pdu->base.seqnum) {
-			dbg_vhci_rx("found pending unlink, %lu\n", unlink->seqnum);
-			list_del(&unlink->list);
-
-			spin_unlock(&vdev->priv_lock);
-			return unlink;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-	return NULL;
-}
-
-
-static void vhci_recv_ret_unlink(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink;
-	struct urb *urb;
-	
-	usbip_dump_header(pdu);
-
-	unlink = dequeue_pending_unlink(vdev, pdu);
-	if (!unlink) {
-		uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
-		return;
-	}
-
-	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
-	if (!urb) {
-		/*
-		 * I get the result of a unlink request. But, it seems that I
-		 * already recieved the result of its submit result and gave
-		 * back the URB.
-		 */
-		uinfo("the urb (seqnum %d) was already given backed\n", pdu->base.seqnum);
-	} else {
-		dbg_vhci_rx("now giveback urb %p\n", urb);
-
-		/* If unlink is succeed, status is -ECONNRESET */
-		urb->status = pdu->u.ret_unlink.status;
-		uinfo("%d\n", urb->status);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	kfree(unlink);
-
-	return;
-}
-
-/* recv a pdu */
-static void vhci_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-
-	dbg_vhci_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_header(&pdu);
-
-	switch(pdu.base.command) {
-		case USBIP_RET_SUBMIT:
-			vhci_recv_ret_submit(vdev, &pdu);
-			break;
-
-		case USBIP_RET_UNLINK:
-			vhci_recv_ret_unlink(vdev, &pdu);
-			break;
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu %u\n", pdu.base.command);
-			usbip_dump_header(&pdu);
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_vhci_rx("signal catched!\n");
-			break;
-		}
-
-
-		if (usbip_event_happend(ud)) break;
-
-		vhci_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.16/vhci_sysfs.c trunk/drivers/2.6.16/vhci_sysfs.c
--- usbip-0.1.4/drivers/2.6.16/vhci_sysfs.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/vhci_sysfs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,286 +0,0 @@
-/*
- * $Id: vhci_sysfs.c 195 2006-10-24 10:11:08Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* TODO: refine locking ?*/
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to show port status */
-
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-		char *out)
-{
-	char *s = out;
-	int i = 0;
-
-	if (!the_controller || !out)
-		BUG();
-
-	spin_lock(&the_controller->lock);
-
-	/*
-	 * output example:
-	 * prt sta bus dev socket           local_busid
-	 * 000 004 000 000         c5a7bb80 1-2.3
-	 * 001 004 000 000         d8cee980 2-3.4
-	 *
-	 * IP address can be retrieved from a socket pointer address by looking
-	 * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
-	 * port number and its peer IP address.
-	 */
-	out += sprintf(out, "prt sta spd bus dev socket           local_busid\n");
-
-	for (i=0; i < VHCI_NPORTS; i++) {
-		struct vhci_device *vdev = port_to_vdev(i);
-
-		spin_lock(&vdev->ud.lock);
-
-		out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
-
-		if (vdev->ud.status == VDEV_ST_USED) {
-			out += sprintf(out, "%03u %03u %03u ",
-					vdev->speed, vdev->busnum, vdev->devnum);
-			out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
-			out += sprintf(out, "%s", vdev->udev->dev.bus_id);
-
-		} else
-			out += sprintf(out, "000 000 000 0000000000000000 0-0");
-
-		out += sprintf(out, "\n");
-
-		spin_unlock(&vdev->ud.lock);
-	}
-
-	spin_unlock(&the_controller->lock);
-
-	return out - s ;
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to shutdown a virtual connection */
-
-static int vhci_port_disconnect(__u32 rhport)
-{
-	struct vhci_device *vdev;
-
-	dbg_vhci_sysfs("enter\n");
-
-	/* lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-	if (vdev->ud.status == VDEV_ST_NULL) {
-		uerr("not connected %d\n", vdev->ud.status);
-
-		/* unlock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		return -EINVAL;
-	}
-
-	/* unlock */
-	spin_unlock(&vdev->ud.lock);
-	spin_unlock(&the_controller->lock);
-
-	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
-
-	return 0;
-}
-
-static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count) {
-	int err;
-	__u32 rhport = 0;
-
-	sscanf(buf, "%u", &rhport);
-
-	/* check rhport */
-	if (rhport >= VHCI_NPORTS) {
-		uerr("invalid port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	err = vhci_port_disconnect(rhport);
-	if (err < 0) {
-		return -EINVAL;
-	}
-
-	dbg_vhci_sysfs("Leave\n");
-	return count;
-}
-
-static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to establish a virtual connection */
-
-static int valid_args(__u32 rhport, __u32 busnum, __u32 devnum,
-		enum usb_device_speed speed)
-{
-	/* check rhport */
-	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		uerr("port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	/* check busnum & devnum */
-	if ((busnum <= 0) || (busnum >= 128) || (devnum <= 0) || (devnum >= 128)) {
-		uerr("busnum %u devnum %u\n", busnum, devnum);
-		return -EINVAL;
-	}
-
-	/* check speed */
-	switch(speed) {
-		case USB_SPEED_LOW:
-		case USB_SPEED_FULL:
-		case USB_SPEED_HIGH:
-		case USB_SPEED_VARIABLE:
-			break;
-
-		default:
-			uerr("speed %d\n", speed);
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * To start a new USB/IP attachment, a userland program needs to setup a TCP
- * connection and then write its socket descriptor with remote device
- * information into this sysfs file.
- *
- * A remote device is virtually attached to the root-hub port of @rhport with
- * @speed. @busnum and @devnum are used to convert URBs between a client host
- * and a server host.
- *
- * write() returns 0 on success, else negative errno.
- */
-static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct vhci_device *vdev;
-	struct socket *socket;
-	int sockfd = 0;
-	__u32 rhport=0, busnum=0, devnum=0, speed=0;
-
-
-	/*
-	 * @rhport: port number of vhci_hcd
-	 * @sockfd: socket descriptor of an established TCP connection
-	 * @busnum: usb bus number in a remote host
-	 * @devnum: usb device number in a remote host
-	 * @speed: usb device speed in a remote host
-	 */
-	sscanf(buf, "%u %u %u %u %u", &rhport, &sockfd, &busnum, &devnum, &speed);
-
-	dbg_vhci_sysfs("rhport(%u) sockfd(%u) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-
-	/* check recieved parameters */
-	if (valid_args(rhport, busnum, devnum, speed) < 0)
-		return -EINVAL;
-
-	/* check sockfd */
-	socket = sockfd_to_socket(sockfd);
-	if (!socket)
-		return  -EINVAL;
-
-	setnodelay(socket);
-
-
-	/* now need lock until setting vdev status as used */
-
-	/* begin a lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-
-	if (vdev->ud.status != VDEV_ST_NULL) {
-		/* end of the lock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		uerr("port %d already used\n", rhport);
-		return -EINVAL;
-	}
-
-	uinfo("rhport(%u) sockfd(%d) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-	vdev->busnum        = busnum;
-	vdev->devnum        = devnum;
-	vdev->speed         = speed;
-	vdev->ud.tcp_socket = socket;
-	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
-
-	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;
-}
-
-static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_status.attr,
-	&dev_attr_detach.attr,
-	&dev_attr_attach.attr,
-	&dev_attr_usbip_debug.attr,
-	NULL,
-};
-
-struct attribute_group dev_attr_group = {
-	.attrs = dev_attrs,
-};
diff -Naur usbip-0.1.4/drivers/2.6.16/vhci_tx.c trunk/drivers/2.6.16/vhci_tx.c
--- usbip-0.1.4/drivers/2.6.16/vhci_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.16/vhci_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,264 +0,0 @@
-/*
- * $Id: vhci_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* @p: pipe whose dev number modified
- * @pdev: new devive number */
-static unsigned long tweak_pipe_devnum(__u32 p, __u8 pdev)
-{
-	__u32 oldp;
-	oldp = p;
-
-	if (pdev > 0x7f)
-		uerr("invalid devnum %u\n", pdev);
-
-	pdev &= 0x7f;    // 0XXX XXXX  confirm MSB be 0
-
-	p &= 0xffff80ff; /* clear p's devnum */
-
-	p |= (pdev << 8);
-
-	dbg_vhci_tx("return new pipe, devnum %u -> %u \n",
-		    usb_pipedevice(oldp), usb_pipedevice(p));
-	dbg_vhci_tx("           pipe %08x -> %08x\n", oldp, p);
-
-	return p;
-}
-
-static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
-{
-	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
-	struct vhci_device *vdev = priv->vdev;
-
-	dbg_vhci_tx("URB, local devnum(%u), busnum(%u) devnum(%u)\n",
-	            usb_pipedevice(urb->pipe), vdev->busnum, vdev->devnum);
-
-	pdup->base.command = USBIP_CMD_SUBMIT;
-	pdup->base.busnum  = vdev->busnum;
-	pdup->base.devnum  = vdev->devnum;
-	pdup->base.seqnum  = priv->seqnum;
-	pdup->base.pipe	   = tweak_pipe_devnum(urb->pipe, vdev->devnum);
-
-	usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
-
-	if (urb->setup_packet)
-		memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8);
-}
-
-static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_priv *priv, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) {
-		list_move_tail(&priv->list, &vdev->priv_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-
-static int vhci_send_cmd_submit(struct vhci_device *vdev)
-{
-	struct vhci_priv *priv = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(vdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_cmd_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->transfer_buffer_length;
-			txsize += urb->transfer_buffer_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_move_tail(&unlink->list, &vdev->unlink_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int vhci_send_cmd_unlink(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
-
-
-		/* 1. setup usbip_header */
-		pdu_header.base.command = USBIP_CMD_UNLINK;
-		pdu_header.base.busnum  = vdev->busnum;
-		pdu_header.base.devnum  = vdev->devnum;
-		pdu_header.base.seqnum  = unlink->seqnum;
-		pdu_header.base.pipe	= 0;
-		pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum;
-
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			uinfo("vhci_tx signal catched\n");
-			break;
-		}
-
-		if (vhci_send_cmd_submit(vdev) < 0)
-			break;
-
-		if (vhci_send_cmd_unlink(vdev) < 0)
-			break;
-
-		wait_event_interruptible(vdev->waitq_tx,
-				(!list_empty(&vdev->priv_tx) ||
-				 !list_empty(&vdev->unlink_tx)));
-
-		dbg_vhci_tx("pending urbs ?, now wake up\n");
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.17/Makefile trunk/drivers/2.6.17/Makefile
--- usbip-0.1.4/drivers/2.6.17/Makefile	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,63 +0,0 @@
-# Makefile for the USB/IP driver
-#
-# $Id: Makefile 97 2006-03-31 16:08:40Z taka-hir $
-#
-# Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
-#
-#
-# 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.
-#
-
- 
-# Please modify here or set environments.
-# KSOURCE should be pointed to the build directory of your kernel.
-# 
-DEBUG ?= n
-KSOURCE ?= /usr/src/linux
-
-
-%.x:%.c
-	gcc -o $@ $<
-
-KBUILD_VERBOSE:=1
-
-HCD_HEADER:=$(KSOURCE)/drivers/usb/core/hcd.h
-
-obj-m += usbip.o
-usbip-objs :=  usbip_common.o usbip_event.o stub_dev.o stub_main.o stub_rx.o stub_tx.o
-
-obj-m += vhci-hcd.o
-vhci-hcd-objs :=  usbip_common.o usbip_event.o vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
-
-
-EXTRA_CFLAGS += -DHCD_HEADER=\"$(HCD_HEADER)\"
-
-ifeq ($(DEBUG),y)
-	EXTRA_CFLAGS += -DCONFIG_USB_DEBUG
-endif
-
-
-default:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` modules
-
-.PHONY: cscope
-cscope:
-	cscope -b -k -R
-
-.PHONY: clean
-clean:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` clean
-	rm -f *.x *~
diff -Naur usbip-0.1.4/drivers/2.6.17/stub_dev.c trunk/drivers/2.6.17/stub_dev.c
--- usbip-0.1.4/drivers/2.6.17/stub_dev.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/stub_dev.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,438 +0,0 @@
-/*
- * $Id: stub_dev.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-
-static int stub_probe(struct usb_interface *interface,  const struct usb_device_id *id);
-static void stub_disconnect(struct usb_interface *interface);
-
-
-/*
- * Define device IDs here if you want to explicitly limit exportable devices.
- * In the most cases, wild card matching will be ok because driver binding can
- * be changed dynamically by a userland program.
- */
-static struct usb_device_id stub_table[] = {
-#if 0
-	/* just an example */
-	{ USB_DEVICE(0x05ac, 0x0301) },   /* Mac 1 button mouse */
-	{ USB_DEVICE(0x0430, 0x0009) },   /* Plat Home Keyboard */
-	{ USB_DEVICE(0x059b, 0x0001) },   /* Iomega USB Zip 100 */
-	{ USB_DEVICE(0x04b3, 0x4427) },   /* IBM USB CD-ROM */
-	{ USB_DEVICE(0x05a9, 0xa511) },   /* LifeView USB cam */
-	{ USB_DEVICE(0x55aa, 0x0201) },   /* Imation card reader */
-	{ USB_DEVICE(0x046d, 0x0870) },   /* Qcam Express(QV-30) */
-	{ USB_DEVICE(0x04bb, 0x0101) },   /* IO-DATA HD 120GB */
-	{ USB_DEVICE(0x04bb, 0x0904) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x04bb, 0x0201) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x08bb, 0x2702) },   /* ONKYO USB Speaker */
-	{ USB_DEVICE(0x046d, 0x08b2) },   /* Logicool Qcam 4000 Pro */
-#endif
-	/* magic for wild card */
-	{ .driver_info = 1 },
-	{ }                                     /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, stub_table);
-
-
-struct usb_driver stub_driver = {
-	.name		= "usbip",
-
-	.probe		= stub_probe,
-	.disconnect 	= stub_disconnect,
-
-	.id_table	= stub_table,
-};
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for a usbip-bound device */
-
-
-/*
- * usbip_status shows status of usbip as long as this driver is bound to the
- * target device.
- */
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct stub_device *sdev = dev_get_drvdata(dev);
-	int status;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	spin_lock(&sdev->ud.lock);
-	status = sdev->ud.status;
-	spin_unlock(&sdev->ud.lock);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", status);
-}
-static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
-
-
-/*
- * 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;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	sscanf(buf, "%d", &sockfd);
-
-	if (sockfd != -1) {
-		uinfo("stub up\n");
-
-		spin_lock(&sdev->ud.lock);
-
-		if (sdev->ud.status != SDEV_ST_AVAILABLE) {
-			uerr("not ready\n");
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		socket = sockfd_to_socket(sockfd);
-		if (!socket) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		setnodelay(socket);
-		setkeepalive(socket);
-		setreuse(socket);
-
-		sdev->ud.tcp_socket = socket;
-
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_start_threads(&sdev->ud);
-
-		spin_lock(&sdev->ud.lock);
-		sdev->ud.status = SDEV_ST_USED;
-		spin_unlock(&sdev->ud.lock);
-
-	} else {
-		uinfo("stub down\n");
-
-		spin_lock(&sdev->ud.lock);
-		if (sdev->ud.status != SDEV_ST_USED) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
-	}
-
-	return count;
-}
-static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
-
-static void stub_add_files(struct device *dev)
-{
-	device_create_file(dev, &dev_attr_usbip_status);
-	device_create_file(dev, &dev_attr_usbip_sockfd);
-	device_create_file(dev, &dev_attr_usbip_debug);
-}
-
-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);
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Event handler functions called by an event handler thread */
-
-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) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	/* 1. stop threads */
-	usbip_stop_threads(ud);
-
-	/* 2. close the socket */
-	/*
-	 * tcp_socket is freed after threads are killed.
-	 * So usbip_xmit do not touch NULL socket.
-	 */
-	if (ud->tcp_socket) {
-		sock_release(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);
-	struct usb_device *udev = interface_to_usbdev(sdev->interface);
-	int ret;
-
-	ret = usb_lock_device_for_reset(udev, sdev->interface);
-	if (ret < 0) {
-		uerr("lock for reset\n");
-
-		spin_lock(&ud->lock);
-		ud->status = SDEV_ST_ERROR;
-		spin_unlock(&ud->lock);
-
-		return;
-	}
-
-	/* try to reset the device */
-	ret = usb_reset_device(udev);
-
-	usb_unlock_device(udev);
-
-	spin_lock(&ud->lock);
-	if (ret) {
-		uerr("device reset\n");
-		ud->status = SDEV_ST_ERROR;
-
-	} else {
-		uinfo("device reset\n");
-		ud->status = SDEV_ST_AVAILABLE;
-
-	}
-	spin_unlock(&ud->lock);
-
-	return;
-}
-
-static void stub_device_unusable(struct usbip_device *ud)
-{
-	spin_lock(&ud->lock);
-	ud->status = SDEV_ST_ERROR;
-	spin_unlock(&ud->lock);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * stub_device_alloc - allocate a new stub_device struct
- * @interface: usb_interface of a new device
- *
- * Allocates and initializes a new stub_devce struct.
- */
-static struct stub_device * stub_device_alloc(struct usb_interface *interface)
-{
-	struct stub_device *sdev;
-
-	/* yes, it's a new device */
-	sdev = (struct stub_device *) kzalloc(sizeof(struct stub_device), GFP_KERNEL);
-	if (!sdev) {
-		uerr("no memory for stub_device\n");
-		return NULL;
-	}
-
-	sdev->interface = interface;
-
-	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;
-	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);
-	sdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	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);
-
-	udbg("register new interface\n");
-	return sdev;
-}
-
-static int stub_device_free(struct stub_device *sdev)
-{
-	if (!sdev)
-		return -EINVAL;
-
-	kfree(sdev);
-	udbg("kfree udev ok\n");
-
-	return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e. not *an*
- * active interface). Currently, a userland program must ensure that it
- * looks at the usbip's sysfs entries of only the first active interface.
- */
-static int stub_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	struct stub_device *sdev = NULL;
-	char *udev_busid = interface->dev.parent->bus_id;
-
-	udbg("Enter\n");
-
-	/* check we should claim or not by busid_table */
-	if (match_busid(udev_busid)) {
-		uinfo("this device %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) {
-		udbg("this device %s is a usb hub device. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		udbg("this device %s is attached on vhci_hcd. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	/* ok. this is my device. */
-
-	if ((sdev = stub_device_alloc(interface))) {
-		struct usb_device *udev = interface_to_usbdev(interface);
-
-		uinfo("USB/IP Stub: register a new interface (bus %u dev %u ifn %u)\n",
-				udev->bus->busnum, udev->devnum,
-				interface->cur_altsetting->desc.bInterfaceNumber);
-	} else
-		return -ENOMEM;
-
-	/* set private data to usb_interface */
-	usb_set_intfdata(interface, sdev);
-
-	stub_add_files(&interface->dev);
-
-	return 0;
-}
-
-
-/*
- * called in usb_disconnect() or usb_deregister()
- * but only if actconfig(active configuration) exists
- */
-static void stub_disconnect(struct usb_interface *interface)
-{
-	struct stub_device *sdev = usb_get_intfdata(interface);
-
-	udbg("Enter\n");
-
-	/* get stub_device */
-	if (!sdev)
-		BUG();
-
-	usb_set_intfdata(interface, NULL);
-
-
-	/*
-	 * NOTE:
-	 * rx/tx threads are invoked for each usb_device.
-	 */
-	stub_remove_files(&interface->dev);
-
-	/* 1. shutdown the current connection */
-	usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
-
-	/* 2. wait for the stop of the event handler */
-	usbip_stop_eh(&sdev->ud);
-
-	/* 3. free sdev */
-	stub_device_free(sdev);
-
-
-	udbg("bye\n");
-}
diff -Naur usbip-0.1.4/drivers/2.6.17/stub.h trunk/drivers/2.6.17/stub.h
--- usbip-0.1.4/drivers/2.6.17/stub.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/stub.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,96 +0,0 @@
-/*
- * $Id: stub.h 173 2006-07-21 09:48:40Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-
-struct stub_device {
-	struct usb_interface *interface;
-	struct list_head list;
-
-	struct usbip_device ud;
-
-	/*
-	 * stub_priv preserves private data of each urb.
-	 * It is allocated as stub_priv_cache and assigned to urb->context.
-	 *
-	 * stub_priv is always linked to any one of 3 lists;
-	 * 	priv_init: linked to this until the comletion of a urb.
-	 * 	priv_tx  : linked to this after the completion of a urb.
-	 * 	priv_free: linked to this after the sending of the result.
-	 *
-	 * Any of these list operations should be locked by priv_lock.
-	 */
-	spinlock_t priv_lock;
-	struct list_head priv_init;
-	struct list_head priv_tx;
-	struct list_head priv_free;
-
-	/* see comments for unlinking in stub_rx.c */
-	struct list_head unlink_tx;
-	struct list_head unlink_free;
-
-
-	wait_queue_head_t tx_waitq;
-};
-
-/* private data into urb->priv */
-struct stub_priv {
-	unsigned long seqnum;
-	struct list_head list;
-	struct stub_device *sdev;
-	struct urb *urb;
-
-	int unlinking;
-};
-
-struct stub_unlink {
-	unsigned long seqnum;
-	struct list_head list;
-	__u32 status;
-};
-
-
-extern kmem_cache_t *stub_priv_cache;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declarations */
-
-/* stub_tx.c */
-void stub_complete(struct urb*, struct pt_regs *);
-void stub_tx_loop(struct usbip_task *);
-
-/* stub_dev.c */
-extern struct usb_driver stub_driver;
-
-/* stub_rx.c */
-void stub_rx_loop(struct usbip_task *);
-void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
-
-/* stub_main.c */
-int match_busid(char *busid);
-void stub_device_cleanup_urbs(struct stub_device *sdev);
diff -Naur usbip-0.1.4/drivers/2.6.17/stub_main.c trunk/drivers/2.6.17/stub_main.c
--- usbip-0.1.4/drivers/2.6.17/stub_main.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/stub_main.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,300 +0,0 @@
-/*
- * $Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-/* Version Information */
-#define DRIVER_VERSION "$Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $"
-#define DRIVER_AUTHOR "Takahiro Hirofuchi <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Stub Driver for USB/IP"
-
-
-
-/* stub_priv is allocated from stub_priv_cache */
-kmem_cache_t *stub_priv_cache = NULL;
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for the usbip driver */
-
-
-/*
- * busid_tables defines matching busids that usbip can grab. A user can change
- * dynamically what device is locally used and what device is exported to a
- * remote host.
- */
-#define MAX_BUSID 16
-static char busid_table[MAX_BUSID][BUS_ID_SIZE];
-spinlock_t busid_table_lock = SPIN_LOCK_UNLOCKED;
-
-
-int match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-				/* already registerd */
-				spin_unlock(&busid_table_lock);
-				return 0;
-			}
-
-	spin_unlock(&busid_table_lock);
-
-	return 1;
-}
-
-static ssize_t show_match_busid(struct device_driver *drv, char *buf)
-{
-	int i;
-	char *out = buf;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			out += sprintf(out, "%s ", busid_table[i]);
-
-	spin_unlock(&busid_table_lock);
-
-	out += sprintf(out, "\n");
-
-	return out - buf;
-}
-
-static int add_match_busid(char *busid)
-{
-	int i;
-
-	if (!match_busid(busid))
-		return 0;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!busid_table[i][0]) {
-			strncpy(busid_table[i], busid, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static int del_match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-			/* found */
-			memset(busid_table[i], 0, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
-		size_t count)
-{
-	int len;
-	char busid[BUS_ID_SIZE];
-
-	if (count < 5)
-		return -EINVAL;
-
-	/* strnlen() does not include \0 */
-	len = strnlen(buf + 4, BUS_ID_SIZE);
-
-	/* busid needs to include \0 termination */
-	if (!(len < BUS_ID_SIZE))
-		return -EINVAL;
-
-	strncpy(busid, buf + 4, BUS_ID_SIZE);
-
-
-	if (!strncmp(buf, "add ", 4)) {
-		if (add_match_busid(busid) < 0)
-			return -ENOMEM;
-		else {
-			udbg("add busid %s\n", busid);
-			return count;
-		}
-	} else if (!strncmp(buf, "del ", 4)) {
-		if (del_match_busid(busid) < 0)
-			return -ENODEV;
-		else {
-			udbg("del busid %s\n", busid);
-			return count;
-		}
-	} else
-		return -EINVAL;
-}
-
-static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, store_match_busid);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Cleanup functions used to free private data */
-
-static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
-{
-	struct stub_priv *priv, *tmp;
-
-	list_for_each_entry_safe(priv, tmp, listhead, list) {
-		list_del(&priv->list);
-		return priv;
-	}
-
-	return NULL;
-}
-
-static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_init);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_free);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-	return NULL;
-}
-
-void stub_device_cleanup_urbs(struct stub_device *sdev)
-{
-	struct stub_priv *priv;
-
-	udbg("free sdev %p\n", sdev);
-
-	while ((priv = stub_priv_pop(sdev))) {
-		struct urb *urb = priv->urb;
-
-		udbg("   free urb %p\n", urb);
-		usb_kill_urb(urb);
-
-		kmem_cache_free(stub_priv_cache, priv);
-
-		if (urb->transfer_buffer != NULL)
-			kfree(urb->transfer_buffer);
-
-		if (urb->setup_packet != NULL)
-			kfree(urb->setup_packet);
-
-		usb_free_urb(urb);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init usb_stub_init(void)
-{
-	int ret;
-
-	stub_priv_cache = kmem_cache_create("stub_priv", sizeof(struct stub_priv),
-			0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!stub_priv_cache) {
-		uerr("create stub_priv_cache\n");
-		return -ENOMEM;
-	}
-
-	ret = usb_register(&stub_driver);
-	if (ret) {
-		uerr("usb_register failed %d\n", ret);
-		return ret;
-	}
-
-
-	info(DRIVER_DESC "" DRIVER_VERSION);
-
-	memset(busid_table, 0, sizeof(busid_table));
-
-	driver_create_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	return ret;
-}
-
-static void __exit usb_stub_exit(void)
-{
-	int ret;
-
-	udbg("enter\n");
-
-	driver_remove_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	/*
-	 * deregister() calls stub_disconnect() for all devices. Device
-	 * specific data is cleared in stub_disconnect().
-	 */
-	usb_deregister(&stub_driver);
-
-	ret = kmem_cache_destroy(stub_priv_cache);
-	if (ret != 0) {
-		uerr("memory leak of stub_priv, %d\n", ret);
-	}
-
-	udbg("bye\n");
-}
-
-
-
-
-module_init (usb_stub_init);
-module_exit (usb_stub_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff -Naur usbip-0.1.4/drivers/2.6.17/stub_rx.c trunk/drivers/2.6.17/stub_rx.c
--- usbip-0.1.4/drivers/2.6.17/stub_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/stub_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,442 +0,0 @@
-/*
- * $Id: stub_rx.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static int is_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	 return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
-		 (req->bRequestType == USB_RECIP_ENDPOINT) &&
-		 (req->wValue == USB_ENDPOINT_HALT);
-}
-
-static int is_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_INTERFACE) &&
-		   (req->bRequestType == USB_RECIP_INTERFACE);
-}
-
-static int is_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
-		   (req->bRequestType == USB_RECIP_DEVICE);
-}
-
-static int tweak_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	int target_endp;
-	int target_dir;
-	int target_pipe;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	/*
-	 * The stalled endpoint is specified in the wIndex value. The endpoint
-	 * of the urb is the target of this clear_halt request (i.e. control
-	 * endpoint).
-	 */
-	target_endp = le16_to_cpu(req->wIndex) & 0x000f;
-
-	/* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
-	target_dir = le16_to_cpu(req->wIndex) & 0x0080;
-
-	if (target_dir)
-		target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
-	else
-		target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
-
-	ret = usb_clear_halt(urb->dev, target_pipe);
-	if (ret < 0)
-		uinfo("clear_halt error: devnum %d endp %d, %d\n",
-				urb->dev->devnum, target_endp, ret);
-	else
-		uinfo("clear_halt done: devnum %d endp %d\n",
-				urb->dev->devnum, target_endp);
-
-	return ret;
-}
-
-static int tweak_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 alternate;
-	__u16 interface;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	alternate = le16_to_cpu(req->wValue);
-	interface = le16_to_cpu(req->wIndex);
-
-	dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
-
-	ret = usb_set_interface(urb->dev, interface, alternate);
-	if (ret < 0)
-		uinfo("set_interface error: inf %u alt %u, %d\n",
-				interface, alternate, ret);
-	else
-		uinfo("set_interface done: inf %u alt %u\n", interface, alternate);
-
-	return ret;
-}
-
-static int tweak_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 config;
-
-	info("set_configuration is not fully supported yet\n");
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	config = le16_to_cpu(req->wValue);
-
-	uinfo("set_configuration: devnum %d %d\n", urb->dev->devnum, config);
-
-#if 0
-	return usb_set_configuration(urb->dev, config);
-#endif
-	return 0;
-}
-
-/*
- * clear_halt, set_interface, and set_configuration require special tricks.
- * TODO: set_configuration. but I have never seen a multi-config device.
- */
-static void tweak_special_requests(struct urb *urb)
-{
-	if (!urb || !urb->setup_packet)
-		return;
-
-	if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
-		return;
-
-	if (is_clear_halt_cmd(urb))
-		/* treak clear_halt */
-		 tweak_clear_halt_cmd(urb);
-
-	else if (is_set_interface_cmd(urb))
-		/* tweak set_interface */
-		tweak_set_interface_cmd(urb);
-
-	else if (is_set_configuration_cmd(urb))
-		/* tweak set_configuration */
-		tweak_set_configuration_cmd(urb);
-
-	else
-		dbg_stub_rx("no need to tweak\n");
-}
-
-/*
- * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
- * By unlinking the urb asynchronously, stub_rx can continuously
- * process coming urbs.  Even if the urb is unlinked, its completion
- * handler will be called and stub_tx will send a return pdu.
- *
- * See also comments about unlinking strategy in vhci_hcd.c.
- */
-static int stub_recv_cmd_unlink(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct list_head *listhead = &sdev->priv_init;
-	struct list_head *ptr;
-	unsigned long flags;
-
-	struct stub_priv *priv;
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
-		priv = list_entry(ptr, struct stub_priv, list);
-		if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
-			int ret;
-
-			uinfo("unlink urb %p\n", priv->urb);
-
-			/*
-			 * This matched urb is not completed yet (i.e. be in
-			 * flight in usb hcd hardware/driver). Now we are
-			 * cancelling it. The unlinking flag means that we are
-			 * now not going to return the normal result pdu of a
-			 * submittion request, but going to return a result pdu
-			 * of the unlink request.
-			 */
-			priv->unlinking = 1;
-
-			/*
-			 * In the case that unlinking flag is on, prev->seqnum
-			 * is changed from the seqnum of the cancelling urb to
-			 * the seqnum of the unlink request. This will be used
-			 * to make the result pdu of the unlink request.
-			 */
-			priv->seqnum = pdu->base.seqnum;
-
-			spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-			/*
-			 * usb_unlink_urb() is now out of spinlocking to avoid
-			 * spinlock recursion since stub_complete() is
-			 * sometimes called in this context but not in the
-			 * interrupt context.  If stub_complete() is executed
-			 * before we call usb_unlink_urb(), usb_unlink_urb()
-			 * will return an error value. In this case, stub_tx
-			 * will return the result pdu of this unlink request
-			 * though submission is completed and actual unlinking
-			 * is not executed. OK?
-			 */
-			ret = usb_unlink_urb(priv->urb);
-			if (ret != -EINPROGRESS)
-				uerr("faild to unlink a urb %p, ret %d\n", priv->urb, ret);
-
-			return 0;
-		}
-	}
-
-	dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
-
-	/*
-	 * The urb of the unlink target is not found in priv_init queue. It was
-	 * already completed and its results is/was going to be sent by a
-	 * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
-	 * return the completeness of this unlink request to vhci_hcd.
-	 */
-	stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-
-	return 0;
-}
-
-static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &sdev->ud;
-
-	int bus = interface_to_busnum(sdev->interface);
-	int dev = interface_to_devnum(sdev->interface);
-
-	if (pdu->base.busnum == bus && pdu->base.devnum == dev) {
-		spin_lock(&ud->lock);
-		if (ud->status == SDEV_ST_USED) {
-			/* A request is valid. */
-			spin_unlock(&ud->lock);
-			return 1;
-		}
-		spin_unlock(&ud->lock);
-	}
-
-	return 0;
-}
-
-static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
-		struct usbip_header *pdu)
-{
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
-	if (!priv) {
-		uerr("alloc stub_priv\n");
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return NULL;
-	}
-
-	memset(priv, 0, sizeof(struct stub_priv));
-
-	priv->seqnum = pdu->base.seqnum;
-	priv->sdev = sdev;
-
-	/*
-	 * After a stub_priv is linked to a list_head,
-	 * our error handler can free allocated data.
-	 */
-	list_add_tail(&priv->list, &sdev->priv_init);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return priv;
-}
-
-static void stub_recv_cmd_submit(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	int ret;
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-
-
-	priv = stub_priv_alloc(sdev, pdu);
-	if (!priv)
-		return;
-
-	/* setup a urb */
-	if (usb_pipeisoc(pdu->base.pipe))
-		priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, GFP_KERNEL);
-	else
-		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
-
-	if (!priv->urb) {
-		uerr("malloc urb\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	/* set priv->urb->transfer_buffer */
-	if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
-		priv->urb->transfer_buffer =
-			kzalloc(pdu->u.cmd_submit.transfer_buffer_length, GFP_KERNEL);
-		if (!priv->urb->transfer_buffer) {
-			uerr("malloc x_buff\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-			return;
-		}
-	}
-
-	/* set priv->urb->setup_packet */
-	priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
-	if (!priv->urb->setup_packet) {
-		uerr("allocate setup_packet\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-	memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
-
-	/* set other members from the base header of pdu */
-	priv->urb->context                = (void *) priv;
-	priv->urb->dev                    = interface_to_usbdev(sdev->interface);
-	priv->urb->pipe                   = pdu->base.pipe;
-	priv->urb->complete               = stub_complete;
-
-	usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
-
-
-	if (usbip_recv_xbuff(ud, priv->urb) < 0)
-		return;
-
-	if (usbip_recv_iso(ud, priv->urb) < 0)
-		return;
-
-	tweak_special_requests(priv->urb);
-
-	/* urb is now ready to submit */
-	ret = usb_submit_urb(priv->urb, GFP_KERNEL);
-
-	if (ret == 0)
-		dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
-	else {
-		uerr("submit_urb error, %d\n", ret);
-
-		/*
-		 * Pessimistic.
-		 * This connection will be discared.
-		 */
-		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
-	}
-
-	dbg_stub_rx("Leave\n");
-	return;
-}
-
-/* recv a pdu */
-static void stub_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-
-	dbg_stub_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_stub_rx)
-		usbip_dump_header(&pdu);
-
-	if (!valid_request(sdev, &pdu)) {
-		uerr("recv invalid request\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	switch (pdu.base.command) {
-		case USBIP_CMD_UNLINK:
-			stub_recv_cmd_unlink(sdev, &pdu);
-			break;
-
-		case USBIP_CMD_SUBMIT:
-			stub_recv_cmd_submit(sdev, &pdu);
-			break;
-
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-			return;
-	}
-
-}
-
-void stub_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_rx("signal catched!\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		stub_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.17/stub_tx.c trunk/drivers/2.6.17/stub_tx.c
--- usbip-0.1.4/drivers/2.6.17/stub_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/stub_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,374 +0,0 @@
-/*
- * $Id: stub_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static void stub_free_priv_and_urb(struct stub_priv *priv)
-{
-	struct urb *urb = priv->urb;
-
-	if (urb->setup_packet)
-		kfree(urb->setup_packet);
-
-	if (urb->transfer_buffer)
-		kfree(urb->transfer_buffer);
-
-	list_del(&priv->list);
-	kmem_cache_free(stub_priv_cache, priv);
-
-	usb_free_urb(urb);
-}
-
-/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
-void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, __u32 status)
-{
-	struct stub_unlink *unlink;
-
-	unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
-	if (!unlink) {
-		uerr("alloc stub_unlink\n");
-		usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	unlink->seqnum = seqnum;
-	unlink->status = status;
-
-	list_add_tail(&unlink->list, &sdev->unlink_tx);
-}
-
-/**
- * stub_complete - completion handler of a usbip urb
- * @urb: pointer to the urb completed
- * @regs:
- *
- * When a urb has completed, the USB core driver calls this function mostly in
- * the interrupt context. To return the result of a urb, the completed urb is
- * linked to the pending list of returning.
- *
- */
-void stub_complete(struct urb *urb, struct pt_regs *regs)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-	struct stub_device *sdev = priv->sdev;
-	unsigned long flags;
-
-	dbg_stub_tx("complete! status %d\n", urb->status);
-
-
-	switch (urb->status) {
-		case 0:
-			/* OK */
-			break;
-		case -ENOENT:
-			uinfo("stopped by a call of usb_kill_urb()"
-					"because of cleaning up a virtual connection\n");
-			return;
-		case -ECONNRESET:
-			uinfo("unlinked by a call of usb_unlink_urb()\n");
-			break;
-		case -EPIPE:
-			uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
-			break;
-		case -ESHUTDOWN:
-			uinfo("device removed?\n");
-			break;
-		default:
-			uinfo("urb completion with non-zero status %d\n", urb->status);
-	}
-
-	/* link a urb to the queue of tx. */
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	if (priv->unlinking) {
-		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
-		stub_free_priv_and_urb(priv);
-	} else
-		list_move_tail(&priv->list, &sdev->priv_tx);
-
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	/* wake up tx_thread */
-	wake_up(&sdev->tx_waitq);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* fill PDU */
-
-static inline void setup_base_pdu(struct usbip_header_basic *base,
-		__u32 command, __u32 seqnum)
-{
-	base->command = command;
-	base->busnum  = 0;
-	base->devnum  = 0;
-	base->seqnum  = seqnum;
-	base->pipe    = 0;
-}
-
-static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-
-	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
-
-	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
-}
-
-static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
-		struct stub_unlink *unlink)
-{
-	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
-
-	rpdu->u.ret_unlink.status = unlink->status;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_SUBMIT */
-
-static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
-		list_move_tail(&priv->list, &sdev->priv_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int stub_send_ret_submit(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_ret_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->actual_length;
-			txsize += urb->actual_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
-		stub_free_priv_and_urb(priv);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_UNLINK */
-
-static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
-{
-	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_move_tail(&unlink->list, &sdev->unlink_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-static int stub_send_ret_unlink(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_unlink *unlink, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[1];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
-
-		/* 1. setup usbip_header */
-		setup_ret_unlink_pdu(&pdu_header, unlink);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void stub_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_tx("signal catched\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		/*
-		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
-		 * looks at only priv_init queue. If the completion of a URB is
-		 * earlier than the recieve of CMD_UNLINK, priv is moved to
-		 * priv_tx queue and stub_rx does not find the target priv. In
-		 * this case, vhci_rx recieves the result of the submit request
-		 * and then recieves the result of the unlink request. The
-		 * result of the submit is given back to the usbcore as the
-		 * completion of the unlink request. The request of the
-		 * unlink is ignored. This is ok because a driver who calls
-		 * usb_unlink_urb() understands the unlink was too late by
-		 * getting the status of the given-backed URB which has the
-		 * status of usb_submit_urb().
-		 */
-		if (stub_send_ret_submit(sdev) < 0)
-			break;
-
-		if (stub_send_ret_unlink(sdev) < 0)
-			break;
-
-		wait_event_interruptible(sdev->tx_waitq,
-				(!list_empty(&sdev->priv_tx) ||
-				 !list_empty(&sdev->unlink_tx)));
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.17/usbip_common.c trunk/drivers/2.6.17/usbip_common.c
--- usbip-0.1.4/drivers/2.6.17/usbip_common.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/usbip_common.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,935 +0,0 @@
-/*
- * $Id: usbip_common.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/file.h>
-#include <linux/tcp.h>
-#include <linux/in.h>
-#include "usbip_common.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* debug routines */
-
-#ifdef CONFIG_USB_DEBUG
-unsigned long usbip_debug_flag = 0xffffffff;
-#else
-unsigned long usbip_debug_flag = 0;
-#endif
-
-static ssize_t show_flag(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%lx\n", usbip_debug_flag);
-}
-
-static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	unsigned long flag;
-
-	sscanf(buf, "%lx", &flag);
-	usbip_debug_flag = flag;
-
-	return count;
-}
-DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
-
-static void usbip_dump_buffer(char *buff, int bufflen)
-{
-	int i;
-
-	if (bufflen > 128) {
-		for (i = 0; i< 128; i++) {
-			if (i%24 == 0)
-				printk("   ");
-			printk("%02x ", (unsigned char ) buff[i]);
-			if (i%4 == 3) printk("| ");
-			if (i%24 == 23) printk("\n");
-		}
-		printk("... (%d byte)\n", bufflen);
-		return;
-	}
-
-	for (i = 0; i< bufflen; i++) {
-		if (i%24 == 0)
-			printk("   ");
-		printk("%02x ", (unsigned char ) buff[i]);
-		if (i%4 == 3)
-			printk("| ");
-		if (i%24 == 23)
-			printk("\n");
-	}
-	printk("\n");
-
-}
-
-static void usbip_dump_pipe(unsigned int p)
-{
-	unsigned char type = usb_pipetype(p);
-	unsigned char ep = usb_pipeendpoint(p);
-	unsigned char dev = usb_pipedevice(p);
-	unsigned char dir = usb_pipein(p);
-
-	printk("dev(%d) ", dev);
-	printk("ep(%d) ",  ep);
-	printk("%s ", dir ? "IN" : "OUT");
-
-	switch(type) {
-		case PIPE_ISOCHRONOUS :
-			printk("%s ", "ISO");
-			break;
-		case PIPE_INTERRUPT :
-			printk("%s ", "INT");
-			break;
-		case PIPE_CONTROL :
-			printk("%s ", "CTL");
-			break;
-		case PIPE_BULK :
-			printk("%s ", "BLK");
-			break;
-		default :
-			printk("ERR");
-	}
-
-	printk("\n");
-
-}
-
-static void usbip_dump_usb_device(struct usb_device *dev)
-{
-	int i;
-
-	if (!dev) {
-		printk("      dump usb dev: null pointer!!\n");
-		return;
-	}
-
-	printk("       devnum(%d) devpath(%s)", dev->devnum, dev->devpath);
-
-	switch(dev->speed) {
-		case USB_SPEED_HIGH :
-			printk(" SPD_HIGH");
-			break;
-		case USB_SPEED_FULL :
-			printk(" SPD_FULL");
-			break;
-		case USB_SPEED_LOW :
-			printk(" SPD_LOW");
-			break;
-		case USB_SPEED_UNKNOWN :
-			printk(" SPD_UNKNOWN");
-			break;
-		default :
-			printk(" SPD_ERROR");
-	}
-
-	printk(" tt %p, ttport %d", dev->tt, dev->ttport);
-	printk("\n");
-
-	printk("                    ");
-	for (i = 0; i < 16; i++) {
-		printk(" %2u", i);
-	}
-
-	printk("\n");
-
-	printk("       toggle0(IN) :");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[0] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-	printk("       toggle1(OUT):");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[1] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-
-	printk("       epmaxp_in   :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_in[i])
-			printk(" %2u",  dev->ep_in[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n");
-
-	printk("       epmaxp_out  :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_out[i])
-			printk(" %2u",  dev->ep_out[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n       ");
-
-	printk("parent %p, bus %p", dev->parent, dev->bus);
-	printk("\n       ");
-
-	printk("descriptor %p, config %p, actconfig %p, rawdescriptors %p",
-			&dev->descriptor, dev->config, dev->actconfig, dev->rawdescriptors);
-	printk("\n       ");
-
-	printk("have_langid %d, string_langid %d", dev->have_langid, dev->string_langid);
-	printk("\n       ");
-
-	printk("maxchild %d, children %p", dev->maxchild, dev->children);
-
-	printk("\n");
-}
-
-static void usbip_dump_request_type(__u8 rt)
-{
-	switch(rt & USB_RECIP_MASK) {
-		case USB_RECIP_DEVICE:
-			printk("DEVICE");
-			break;
-		case USB_RECIP_INTERFACE:
-			printk("INTERF");
-			break;
-		case USB_RECIP_ENDPOINT:
-			printk("ENDPOI");
-			break;
-		case USB_RECIP_OTHER:
-			printk("OTHER ");
-			break;
-		default:
-			printk("------");
-	}
-}
-
-static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
-{
-	if (!cmd) {
-		printk("      %s : null pointer\n", __FUNCTION__);
-		return;
-	}
-
-	printk("       ");
-	printk("bRequestType(%02X) ", cmd->bRequestType);
-	printk("bRequest(%02X) " , cmd->bRequest);
-	printk("wValue(%04X) ", cmd->wValue);
-	printk("wIndex(%04X) ", cmd->wIndex);
-	printk("wLength(%04X) ", cmd->wLength);
-
-	printk("\n       ");
-
-	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk("STANDARD ");
-		switch(cmd->bRequest) {
-			case USB_REQ_GET_STATUS:
-				printk("GET_STATUS");
-				break;
-			case USB_REQ_CLEAR_FEATURE:
-				printk("CLEAR_FEAT");
-				break;
-			case USB_REQ_SET_FEATURE:
-				printk("SET_FEAT  ");
-				break;
-			case USB_REQ_SET_ADDRESS:
-				printk("SET_ADDRRS");
-				break;
-			case USB_REQ_GET_DESCRIPTOR:
-				printk("GET_DESCRI");
-				break;
-			case USB_REQ_SET_DESCRIPTOR:
-				printk("SET_DESCRI");
-				break;
-			case USB_REQ_GET_CONFIGURATION:
-				printk("GET_CONFIG");
-				break;
-			case USB_REQ_SET_CONFIGURATION:
-				printk("SET_CONFIG");
-				break;
-			case USB_REQ_GET_INTERFACE:
-				printk("GET_INTERF");
-				break;
-			case USB_REQ_SET_INTERFACE:
-				printk("SET_INTERF");
-				break;
-			case USB_REQ_SYNCH_FRAME:
-				printk("SYNC_FRAME");
-				break;
-			default:
-				printk("REQ(%02X) ", cmd->bRequest);
-		}
-
-		printk(" ");
-		usbip_dump_request_type(cmd->bRequestType);
-
-	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk("CLASS   ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk("VENDOR  ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk("RESERVED");
-
-	printk("\n");
-}
-
-void usbip_dump_urb (struct urb *purb)
-{
-	if (!purb) {
-		printk("   dump urb: null pointer!!\n");
-		return;
-	}
-
-	printk("   urb                   :%p\n", purb);
-	printk("   dev                   :%p\n", purb->dev);
-
-	usbip_dump_usb_device(purb->dev);
-
-	printk("   pipe                  :%08x ", purb->pipe);
-
-	usbip_dump_pipe(purb->pipe);
-
-	printk("   status                :%d\n", purb->status);
-	printk("   transfer_flags        :%08X\n", purb->transfer_flags);
-	printk("   transfer_buffer       :%p\n", purb->transfer_buffer);
-	printk("   transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("   actual_length         :%d\n", purb->actual_length);
-	printk("   bandwidth             :%d\n", purb->actual_length);
-	printk("   setup_packet          :%p\n", purb->setup_packet);
-
-	if (purb->setup_packet && usb_pipetype(purb->pipe) == PIPE_CONTROL)
-		usbip_dump_usb_ctrlrequest((struct usb_ctrlrequest *) purb->setup_packet);
-
-	printk("   start_frame           :%d\n", purb->start_frame);
-	printk("   number_of_packets     :%d\n", purb->number_of_packets);
-	printk("   interval              :%d\n", purb->interval);
-	printk("   error_count           :%d\n", purb->error_count);
-	printk("   context               :%p\n", purb->context);
-	printk("   complete              :%p\n", purb->complete);
-}
-
-void usbip_dump_header(struct usbip_header *pdu)
-{
-	udbg("BASE: cmd %u bus %u dev %u seq %u pipe %04x\n",
-			pdu->base.command,
-			pdu->base.busnum,
-			pdu->base.devnum,
-			pdu->base.seqnum,
-			pdu->base.pipe);
-
-	usbip_dump_pipe(pdu->base.pipe);
-
-	switch(pdu->base.command) {
-		case USBIP_CMD_SUBMIT:
-			udbg("CMD_SUBMIT: x_flags %u x_len %u bw %u sf %u #p %u iv %u\n",
-					pdu->u.cmd_submit.transfer_flags,
-					pdu->u.cmd_submit.transfer_buffer_length,
-					pdu->u.cmd_submit.bandwidth,
-					pdu->u.cmd_submit.start_frame,
-					pdu->u.cmd_submit.number_of_packets,
-					pdu->u.cmd_submit.interval);
-					break;
-		case USBIP_CMD_UNLINK:
-			udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
-			break;
-		case USBIP_RET_SUBMIT:
-			udbg("RET_SUBMIT: st %d al %u bw %u sf %d ec %d\n",
-					pdu->u.ret_submit.status,
-					pdu->u.ret_submit.actual_length,
-					pdu->u.ret_submit.bandwidth,
-					pdu->u.ret_submit.start_frame,
-					pdu->u.ret_submit.error_count);
-		case USBIP_RET_UNLINK:
-			udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
-			break;
-		default:
-			/* NOT REACHED */
-			udbg("UNKNOWN\n");
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* thread routines */
-
-int usbip_thread(void *param)
-{
-	struct usbip_task *ut = (struct usbip_task *) 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);
-}
-
-void usbip_start_threads(struct usbip_device *ud)
-{
-	/*
-	 * threads are invoked per one device (per one connection).
-	 */
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_rx, 0);
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_tx, 0);
-
-	/* confirm threads are starting */
-	wait_for_completion(&ud->tcp_rx.thread_done);
-	wait_for_completion(&ud->tcp_tx.thread_done);
-}
-
-void usbip_stop_threads(struct usbip_device *ud)
-{
-        /* kill threads related to this sdev, if v.c. exists */
-	if (ud->tcp_rx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
-		wait_for_completion(&ud->tcp_rx.thread_done);
-		udbg("rx_thread for ud %p has finished\n", ud);
-	}
-
-	if (ud->tcp_tx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
-		wait_for_completion(&ud->tcp_tx.thread_done);
-		udbg("tx_thread for ud %p has finished\n", ud);
-	}
-}
-
-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;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* socket routines */
-
- /*  Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags)
-{
-	int result;
-	struct msghdr msg;
-	struct kvec iov;
-	int total = 0;
-
-	/* for blocks of if (dbg_flag_xmit) */
-	char *bp = buf;
-	int osize= size;
-
-	dbg_xmit("enter\n");
-
-	if (!sock || !buf || !size) {
-		uerr("usbip_xmit: invalid arg, sock %p buff %p size %d\n",
-				sock, buf, size);
-		return -EINVAL;
-	}
-
-
-	if (dbg_flag_xmit) {
-		if (send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: sending... , sock %p, buf %p, size %d, msg_flags %d\n",
-					sock, buf, size, msg_flags);
-			usbip_dump_buffer(buf, size);
-		}
-	}
-
-
-	do {
-		sock->sk->sk_allocation = GFP_NOIO;
-		iov.iov_base    = buf;
-		iov.iov_len     = size;
-		msg.msg_name    = NULL;
-		msg.msg_namelen = 0;
-		msg.msg_control = NULL;
-		msg.msg_controllen = 0;
-		msg.msg_namelen    = 0;
-		msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
-
-		if (send)
-			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
-		else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL);
-
-		if (result <= 0) {
-			udbg("usbip_xmit: %s sock %p buf %p size %u ret %d total %d\n",
-					send ? "send" : "receive", sock, buf, size, result, total);
-			goto err;
-		}
-
-		size -= result;
-		buf += result;
-		total += result;
-
-	} while (size > 0);
-
-
-	if (dbg_flag_xmit) {
-		if (!send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: receiving....\n");
-			usbip_dump_buffer(bp, osize);
-			printk("usbip_xmit: received, osize %d ret %d size %d total %d\n",
-					osize, result, size, total);
-		}
-
-		if (send) {
-			printk("usbip_xmit: send, total %d\n", total);
-		}
-	}
-
-	return total;
-
-err:
-	return result;
-}
-
-int setquickack(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-void setreuse(struct socket *socket)
-{
-	socket->sk->sk_reuse = 1;
-}
-
-struct socket *sockfd_to_socket(unsigned int sockfd)
-{
-	struct socket *socket;
-	struct file *file;
-	struct inode *inode;
-
-	file = fget(sockfd);
-	if (!file) {
-		uerr("invalid sockfd\n");
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-
-	if (!inode || !S_ISSOCK(inode->i_mode))
-		return NULL;
-
-	socket = SOCKET_I(inode);
-
-	return socket;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/* pdu routines */
-
-/* there may be more cases to tweak the flags. */
-static unsigned int tweak_transfer_flags(unsigned int flags)
-{
-
-	if (flags & URB_NO_TRANSFER_DMA_MAP)
-		/*
-		 * vhci_hcd does not provide DMA-mapped I/O. The upper
-		 * driver does not need to set this flag. The remote
-		 * usbip.ko does not still perform DMA-mapped I/O for
-		 * DMA-caplable host controllers. So, clear this flag.
-		 */
-		flags &= ~URB_NO_TRANSFER_DMA_MAP;
-
-	if (flags & URB_NO_SETUP_DMA_MAP)
-		flags &= ~URB_NO_SETUP_DMA_MAP;
-
-	return flags;
-}
-
-static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
-
-	/*
-	 * Some members are not still implemented in usbip. I hope this issue
-	 * will be discussed when usbip is ported to other operating systems.
-	 */
-	if (pack) {
-		/* vhci_tx.c */
-		spdu->transfer_flags		= tweak_transfer_flags(urb->transfer_flags);
-
-		spdu->transfer_buffer_length	= urb->transfer_buffer_length;
-		spdu->bandwidth			= urb->bandwidth;
-		spdu->start_frame		= urb->start_frame;
-		spdu->number_of_packets		= urb->number_of_packets;
-		spdu->interval			= urb->interval;
-	} else  {
-		/* stub_rx.c */
-		urb->transfer_flags         = spdu->transfer_flags;
-
-		urb->transfer_buffer_length = spdu->transfer_buffer_length;
-		urb->bandwidth              = spdu->bandwidth;
-		urb->start_frame            = spdu->start_frame;
-		urb->number_of_packets      = spdu->number_of_packets;
-		urb->interval               = spdu->interval;
-	}
-}
-
-static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
-
-	if (pack) {
-		/* stub_tx.c */
-
-		rpdu->status		= urb->status;
-		rpdu->actual_length	= urb->actual_length;
-		rpdu->bandwidth		= urb->bandwidth;
-		rpdu->start_frame	= urb->start_frame;
-		rpdu->error_count	= urb->error_count;
-	} else {
-		/* vhci_rx.c */
-
-		urb->status		= rpdu->status;
-		urb->actual_length	= rpdu->actual_length;
-		urb->bandwidth		= rpdu->bandwidth;
-		urb->start_frame	= rpdu->start_frame;
-		urb->error_count	= rpdu->error_count;
-	}
-}
-
-
-void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack)
-{
-	switch(cmd) {
-		case USBIP_CMD_SUBMIT:
-			usbip_pack_cmd_submit(pdu, urb, pack);
-			break;
-		case USBIP_RET_SUBMIT:
-			usbip_pack_ret_submit(pdu, urb, pack);
-			break;
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-
-
-static void correct_endian_basic(struct usbip_header_basic *base, int send)
-{
-	if (send) {
-		base->command	= cpu_to_be32(base->command);
-		base->busnum	= cpu_to_be32(base->busnum);
-		base->devnum	= cpu_to_be32(base->devnum);
-		base->seqnum	= cpu_to_be32(base->seqnum);
-		base->pipe	= cpu_to_be32(base->pipe);
-	} else {
-		base->command	= be32_to_cpu(base->command);
-		base->busnum	= be32_to_cpu(base->busnum);
-		base->devnum	= be32_to_cpu(base->devnum);
-		base->seqnum	= be32_to_cpu(base->seqnum);
-		base->pipe	= be32_to_cpu(base->pipe);
-	}
-}
-
-static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, int send)
-{
-	if (send) {
-		pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
-
-		cpu_to_be32s(&pdu->transfer_buffer_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->number_of_packets);
-		cpu_to_be32s(&pdu->interval);
-	} else {
-		pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags);
-
-		be32_to_cpus(&pdu->transfer_buffer_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->number_of_packets);
-		be32_to_cpus(&pdu->interval);
-	}
-}
-
-static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, int send)
-{
-	if (send) {
-		cpu_to_be32s(&pdu->status);
-		cpu_to_be32s(&pdu->actual_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->error_count);
-	} else {
-		be32_to_cpus(&pdu->status);
-		be32_to_cpus(&pdu->actual_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->error_count);
-	}
-}
-
-static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, int send)
-{
-	if (send)
-		pdu->seqnum = cpu_to_be32(pdu->seqnum);
-	else
-		pdu->seqnum = be32_to_cpu(pdu->seqnum);
-}
-
-static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, int send)
-{
-	if (send)
-		cpu_to_be32s(&pdu->status);
-	else
-		be32_to_cpus(&pdu->status);
-}
-
-void usbip_header_correct_endian(struct usbip_header *pdu, int send)
-{
-	__u32 cmd = 0;
-
-	if (send)
-		cmd = pdu->base.command;
-
-	correct_endian_basic(&pdu->base, send);
-
-	if (!send)
-		cmd = pdu->base.command;
-
-	switch (cmd) {
-		case USBIP_CMD_SUBMIT:
-			correct_endian_cmd_submit(&pdu->u.cmd_submit, send);
-			break;
-		case USBIP_RET_SUBMIT:
-			correct_endian_ret_submit(&pdu->u.ret_submit, send);
-			break;
-
-		case USBIP_CMD_UNLINK:
-			correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send);
-			break;
-		case USBIP_RET_UNLINK:
-			correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
-			break;
-
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-	
-static void usbip_iso_pakcet_correct_endian(struct usbip_iso_packet_descriptor *iso, int send)
-{
-	/* does not need all members. but copy all simply. */
-	if (send) {
-		iso->offset	= cpu_to_be32(iso->offset);
-		iso->length	= cpu_to_be32(iso->length);
-		iso->status	= cpu_to_be32(iso->status);
-		iso->actual_length = cpu_to_be32(iso->actual_length);
-	} else {
-		iso->offset	= be32_to_cpu(iso->offset);
-		iso->length	= be32_to_cpu(iso->length);
-		iso->status	= be32_to_cpu(iso->status);
-		iso->actual_length = be32_to_cpu(iso->actual_length);
-	}
-}
-
-static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
-		struct usb_iso_packet_descriptor *uiso, int pack)
-{
-	if (pack) {
-		iso->offset		= uiso->offset;
-		iso->length		= uiso->length;
-		iso->status		= uiso->status;
-		iso->actual_length	= uiso->actual_length;
-	} else {
-		uiso->offset		= iso->offset;
-		uiso->length		= iso->length;
-		uiso->status		= iso->status;
-		uiso->actual_length	= iso->actual_length;
-	}
-}
-
-
-/* must free buffer */
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	ssize_t size = np * sizeof(*iso);
-	int i;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return NULL;
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
-		usbip_iso_pakcet_correct_endian(iso, 1);
-	}
-
-	*bufflen = size;
-
-	return buff;
-}
-
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	int size = np * sizeof(*iso);
-	int i;
-	int ret;
-
-	if (!usb_pipeisoc(urb->pipe))
-		return 0;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-
-	ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
-	if (ret != size) {
-		uerr("recv iso_frame_descriptor, %d\n", ret);
-		kfree(buff);
-
-		if (ud->side == USBIP_STUB)
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		else
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-
-		return -EPIPE;
-	}
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_iso_pakcet_correct_endian(iso, 0);
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
-	}
-
-
-	kfree(buff);
-
-	return ret;
-}
-
-
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
-{
-	int ret;
-	int size;
-
-	if (ud->side == USBIP_STUB) {
-		/* stub_rx.c */
-		/* the direction of urb must be OUT. */
-		if (usb_pipein(urb->pipe))
-			return 0;
-
-		size = urb->transfer_buffer_length;
-	} else {
-		/* vhci_rx.c */
-		/* the direction of urb must be IN. */
-		if (usb_pipeout(urb->pipe))
-			return 0;
-
-		size = urb->actual_length;
-	}
-
-	/* no need to recv xbuff */
-	if (!(size > 0))
-		return 0;
-
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) urb->transfer_buffer, size, 0);
-	if (ret != size) {
-		uerr("recv xbuf, %d\n", ret);
-		if (ud->side == USBIP_STUB) {
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		} else {
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-			return -EPIPE;
-		}
-	}
-
-	return ret;
-}
diff -Naur usbip-0.1.4/drivers/2.6.17/usbip_common.h trunk/drivers/2.6.17/usbip_common.h
--- usbip-0.1.4/drivers/2.6.17/usbip_common.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,364 +0,0 @@
-/*
- * $Id: usbip_common.h 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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.
- */
-
-#ifndef  __VHCI_COMMON_H
-#define  __VHCI_COMMON_H
-
-
-#include <linux/usb.h>
-#include <net/sock.h>
-#include <asm/byteorder.h>
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * define macros to print messages
- */
-
-/**
- * udbg - print debug messages if CONFIG_USB_DEBUG is defined
- * @fmt:
- * @args:
- */
-
-#ifdef CONFIG_USB_DEBUG
-
-#define udbg(fmt, args...)						\
-	do{								\
-		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	}while(0)
-
-#else  /* CONFIG_USB_DEBUG */
-
-#define udbg(fmt, args...)		do{ }while(0)
-
-#endif /* CONFIG_USB_DEBUG */
-
-
-enum {
-	usbip_debug_xmit	= (1 << 0),
-	usbip_debug_sysfs	= (1 << 1),
-	usbip_debug_urb		= (1 << 2),
-	usbip_debug_eh		= (1 << 3),
-
-	usbip_debug_stub_cmp	= (1 << 8),
-	usbip_debug_stub_dev	= (1 << 9),
-	usbip_debug_stub_rx	= (1 << 10),
-	usbip_debug_stub_tx	= (1 << 11),
-
-	usbip_debug_vhci_rh	= (1 << 8),
-	usbip_debug_vhci_hc	= (1 << 9),
-	usbip_debug_vhci_rx	= (1 << 10),
-	usbip_debug_vhci_tx	= (1 << 11),
-	usbip_debug_vhci_sysfs  = (1 << 12)
-};
-
-#define dbg_flag_xmit		(usbip_debug_flag & usbip_debug_xmit)
-#define dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
-#define dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
-#define dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
-#define dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
-#define dbg_flag_vhci_sysfs	(usbip_debug_flag & usbip_debug_vhci_sysfs)
-#define dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
-#define dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
-
-extern unsigned long usbip_debug_flag;
-extern struct device_attribute dev_attr_usbip_debug;
-
-#define dbg_with_flag(flag, fmt, args...)		\
-	do {						\
-		if(flag & usbip_debug_flag) 		\
-			udbg(fmt , ##args);		\
-	} while(0)
-
-#define dbg_sysfs(fmt, args...)	dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define dbg_xmit(fmt, args...)	dbg_with_flag(usbip_debug_xmit,  fmt , ##args)
-#define dbg_urb(fmt, args...)	dbg_with_flag(usbip_debug_urb,   fmt , ##args)
-#define dbg_eh(fmt, args...)	dbg_with_flag(usbip_debug_eh,   fmt , ##args)
-
-#define dbg_vhci_rh(fmt, args...) dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
-#define dbg_vhci_hc(fmt, args...) dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
-#define dbg_vhci_rx(fmt, args...) dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
-#define dbg_vhci_tx(fmt, args...) dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define dbg_vhci_sysfs(fmt, args...) dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
-
-#define dbg_stub_cmp(fmt, args...) dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define dbg_stub_rx(fmt, args...) dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define dbg_stub_tx(fmt, args...) dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
-
-
-/**
- * uerr - print error messages
- * @fmt:
- * @args:
- */
-#define uerr(fmt, args...)						\
-	do {								\
-		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	} while(0)
-
-/**
- * uinfo - print information messages
- * @fmt:
- * @args:
- */
-#define uinfo(fmt, args...)					\
-	do {							\
-		printk(KERN_INFO "usbip: " fmt , ## args);	\
-	} while(0)
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * USB/IP packet headers.
- * At now, we define 4 packet types:
- *
- *  - CMD_SUBMIT transfers a USB request. This is corresponding to usb_submit_urb().
- *  - RET_RETURN transfers a result of a USB request.
- *  - CMD_UNLINK transfers an unlink request of a pending USB request.
- *  - RET_UNLINK transfers an unlink request of a pending USB request.
- *
- * TODO:
- *
- *  - inter-operability between other OSs
- */
-
-/*
- * A basic header followed by other additional headers.
- */
-struct usbip_header_basic {
-#define USBIP_CMD_SUBMIT	0x0001
-#define USBIP_CMD_UNLINK	0x0002
-#define USBIP_RET_SUBMIT	0x0003
-#define USBIP_RET_UNLINK	0x0004
-	__u32 command;
-
-	__u32 busnum;
-	__u32 devnum;
-	__u32 seqnum; /* seaquencial number which identifies URBs */
-	__u32 pipe;
-} __attribute__ ((packed));
-
-/*
- * An additional header for a CMD_SUBMIT packet.
- */
-struct usbip_header_cmd_submit {
-	__u32 transfer_flags;
-	__s32 transfer_buffer_length;
-	__s32 bandwidth;
-	__s32 start_frame;
-	__s32 number_of_packets;
-	__s32 interval;
-	unsigned char setup[8]; /* CTRL only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a RET_SUBMIT packet.
- */
-struct usbip_header_ret_submit {
-	__s32 status;
-	__s32 actual_length; /* returned data length */
-	__s32 bandwidth;
-	__s32 start_frame; /* ISO and INT */
-	__s32 number_of_packets;  /* ISO only */
-	__s32 error_count; /* ISO only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a CMD_UNLINK packet.
- */
-struct usbip_header_cmd_unlink {
-	__u32 seqnum; /* URB's seqnum which will be unlinked */
-}__attribute__ ((packed));
-
-
-/*
- * An additional header for a RET_UNLINK packet.
- */
-struct usbip_header_ret_unlink {
-	__s32 status;
-}__attribute__ ((packed));
-
-
-/* the same as usb_iso_packet_descriptor but packed for pdu */
-struct usbip_iso_packet_descriptor {
-	__u32 offset;
-	__u32 length;            /* expected length */
-	__u32 actual_length;
-	__u32 status;
-}__attribute__ ((packed));
-
-
-/*
- * All usbip packets use a common header to keep code simple.
- */
-struct usbip_header {
-	struct usbip_header_basic base;
-
-	union {
-		struct usbip_header_cmd_submit	cmd_submit;
-		struct usbip_header_ret_submit	ret_submit;
-		struct usbip_header_cmd_unlink	cmd_unlink;
-		struct usbip_header_ret_unlink	ret_unlink;
-	} u;
-}__attribute__ ((packed));
-
-
-
-
-/*-------------------------------------------------------------------------*/
-
-
-int usbip_xmit(int , struct socket *, char *, int , int );
-int usbip_sendmsg(struct socket *, struct msghdr *, int );
-
-
-static inline int interface_to_busnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->bus->busnum;
-}
-
-static inline int interface_to_devnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->devnum;
-}
-
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
-	return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-struct socket *sockfd_to_socket(unsigned int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-
-
-void usbip_dump_urb (struct urb *purb);
-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,
-};
-
-enum usbip_status {
-	/* sdev is available. */
-	SDEV_ST_AVAILABLE = 0x01,
-	/* sdev is now used. */
-	SDEV_ST_USED,
-	/* sdev is unusable because of a fatal error. */
-	SDEV_ST_ERROR,
-
-	/* vdev does not connect a remote device. */
-	VDEV_ST_NULL,
-	/* vdev is used, but the USB address is not assigned yet */
-	VDEV_ST_NOTASSIGNED,
-	VDEV_ST_USED,
-	VDEV_ST_ERROR
-};
-
-/* a common structure for stub_device and vhci_device */
-struct usbip_device{
-	enum usbip_side side;
-
-	enum usbip_status status;
-
-	/* lock for status */
-	spinlock_t lock;
-
-	struct socket *tcp_socket;
-
-	struct usbip_task tcp_rx;
-	struct usbip_task tcp_tx;
-
-	/* event handler */
-#define USBIP_EH_SHUTDOWN	(1 << 0)
-#define USBIP_EH_BYE		(1 << 1)
-#define USBIP_EH_RESET		(1 << 2)
-#define USBIP_EH_UNUSABLE	(1 << 3)
-
-#define SDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
-#define	SDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_SUBMIT		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE )
-
-#define	VDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
-#define	VDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
-
-	unsigned long event;
-	struct usbip_task eh;
-	wait_queue_head_t eh_waitq;
-
-	struct eh_ops {
-		void (*shutdown)(struct usbip_device *);
-		void (*reset)(struct usbip_device *);
-		void (*unusable)(struct usbip_device *);
-	} eh_ops;
-};
-
-
-void usbip_task_init(struct usbip_task *ut, char *, void (*loop_ops)(struct usbip_task *));
-
-void 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);
-void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
-
-
-/* usbip_event.c */
-void usbip_start_eh(struct usbip_device *ud);
-void usbip_stop_eh(struct usbip_device *ud);
-void usbip_event_add(struct usbip_device *ud, unsigned long event);
-int usbip_event_happend(struct usbip_device *ud);
-
-
-#endif
diff -Naur usbip-0.1.4/drivers/2.6.17/usbip_event.c trunk/drivers/2.6.17/usbip_event.c
--- usbip-0.1.4/drivers/2.6.17/usbip_event.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/usbip_event.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,153 +0,0 @@
-/*
- * $Id: usbip_event.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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 void event_handler_loop(struct usbip_task *eh);
-
-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((int(*)(void *)) usbip_thread, (void *) eh, 0);
-
-	wait_for_completion(&eh->thread_done);
-}
-
-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");
-}
-
-
-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);
-}
-
-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;
-}
-
-
-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 */
-		uerr("unknown event\n");
-		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");
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.17/vhci.h trunk/drivers/2.6.17/vhci.h
--- usbip-0.1.4/drivers/2.6.17/vhci.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/vhci.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,143 +0,0 @@
-/*
- * $Id: vhci.h 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/platform_device.h>
-#include HCD_HEADER
-
-
-struct vhci_device {
-	struct usb_device *udev;
-
-	/* busnum and devnum of a remote device */
-	__u32 busnum;
-	__u32 devnum;
-
-	/* speed of a remote device */
-	enum usb_device_speed speed;
-
-	/*  vhci root-hub port to which this device is attached  */
-	__u32 rhport;
-
-	struct usbip_device ud;
-
-
-	/* lock for the below link lists */
-	spinlock_t priv_lock;
-
-	/* vhci_priv is linked to one of them. */
-	struct list_head priv_tx;
-	struct list_head priv_rx;
-
-	/* vhci_unlink is linked to one of them */
-	struct list_head unlink_tx;
-	struct list_head unlink_rx;
-
-	/* vhci_tx thread sleeps for this queue */
-	wait_queue_head_t waitq_tx;
-};
-
-
-/* urb->hcpriv, use container_of() */
-struct vhci_priv {
-	unsigned long seqnum;
-	struct list_head list;
-
-	struct vhci_device *vdev;
-	struct urb *urb;
-};
-
-
-struct vhci_unlink {
-	/* seqnum of this request */
-	unsigned long seqnum;
-
-	struct list_head list;
-
-	/* seqnum of the unlink target */
-	unsigned long unlink_seqnum;
-};
-
-/*
- * The number of ports is less than 16 ?
- * USB_MAXCHILDREN is statically defined to 16 in usb.h.  Its maximum value
- * would be 31 because the event_bits[1] of struct usb_hub is defined as
- * unsigned long in hub.h
- */
-#define VHCI_NPORTS 8
-
-/* for usb_bus.hcpriv */
-struct vhci_hcd {
-	spinlock_t	lock;
-
-	u32	port_status[VHCI_NPORTS];
-
-	unsigned	resuming:1;
-	unsigned long	re_timeout;
-
-	atomic_t seqnum;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 * But, the index of this array begins from 0.
-	 */
-	struct vhci_device vdev[VHCI_NPORTS];
-
-	/* vhci_device which has not been assiged its address yet */
-	int pending_port;
-};
-
-
-extern struct vhci_hcd *the_controller;
-extern struct attribute_group dev_attr_group;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declaration */
-
-/* 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);
-
-#define hardware		(&the_controller->pdev.dev)
-
-static inline struct vhci_device *port_to_vdev(__u32 port)
-{
-	return &the_controller->vdev[port];
-}
-
-static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd)
-{
-	return (struct vhci_hcd *) (hcd->hcd_priv);
-}
-
-static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci)
-{
-	return container_of((void *) vhci, struct usb_hcd, hcd_priv);
-}
-
-static inline struct device *vhci_dev(struct vhci_hcd *vhci)
-{
-	return vhci_to_hcd(vhci)->self.controller;
-}
diff -Naur usbip-0.1.4/drivers/2.6.17/vhci_hcd.c trunk/drivers/2.6.17/vhci_hcd.c
--- usbip-0.1.4/drivers/2.6.17/vhci_hcd.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/vhci_hcd.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1174 +0,0 @@
-/*
- * $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-#define DRIVER_VERSION " $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $ "
-#define DRIVER_AUTHOR "HIROFUCHI Takahiro <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
-#define DRIVER_LICENCE "GPL"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENCE);
-
-
-
-/*
- * TODO
- * 	- update root hub emulation
- * 	- move the emulation code to userland ?
- * 		poring to other operating systems
- * 		minimize kernel code
- * 	- add suspend/resume code
- * 	- clean up everything
- */
-
-
-/* See usb gadget dummy hcd */
-
-
-static int vhci_hub_status (struct usb_hcd *hcd, char *buff);
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buff, u16 wLength);
-static int vhci_urb_enqueue (struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags);
-static int vhci_urb_dequeue( struct usb_hcd *hcd, struct urb *urb);
-static int vhci_start(struct usb_hcd *vhci_hcd);
-static void vhci_stop(struct usb_hcd *hcd);
-static int vhci_get_frame_number(struct usb_hcd *hcd);
-
-static const char driver_name[] = "vhci_hcd";
-static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
-
-
-
-
-struct vhci_hcd *the_controller = NULL;
-
-
-static const char *bit_desc[] = {
-	"CONNECTION",		/*0*/
-	"ENABLE",		/*1*/
-	"SUSPEND",		/*2*/
-	"OVER_CURRENT",		/*3*/
-	"RESET",		/*4*/
-	"R5",		/*5*/
-	"R6",		/*6*/
-	"R7",		/*7*/
-	"POWER",		/*8*/
-	"LOWSPEED",		/*9*/
-	"HIGHSPEED",		/*10*/
-	"PORT_TEST",		/*11*/
-	"INDICATOR",		/*12*/
-	"R13",		/*13*/
-	"R14",		/*14*/
-	"R15",		/*15*/
-	"C_CONNECTION",		/*16*/
-	"C_ENABLE",		/*17*/
-	"C_SUSPEND",		/*18*/
-	"C_OVER_CURRENT",	/*19*/
-	"C_RESET",		/*20*/
-	"R21",		/*21*/
-	"R22",		/*22*/
-	"R23",		/*23*/
-	"R24",		/*24*/
-	"R25",		/*25*/
-	"R26",		/*26*/
-	"R27",		/*27*/
-	"R28",		/*28*/
-	"R29",		/*29*/
-	"R30",		/*30*/
-	"R31",		/*31*/
-};
-
-
-static void dump_port_status(u32 status)
-{
-	int i = 0;
-
-	printk("status %08x:", status);
-	for (i = 0; i < 32; i++) {
-		if (status & (1 << i)) {
-			printk(" %s", bit_desc[i]);
-		}
-	}
-
-	printk("\n");
-}
-
-
-
-void rh_port_connect(int rhport, enum usb_device_speed speed)
-{
-	unsigned long	flags;
-
-	dbg_vhci_rh("rh_port_connect %d\n", rhport);
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
-		| (1 << USB_PORT_FEAT_C_CONNECTION);
-
-	switch (speed) {
-		case USB_SPEED_HIGH:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-			break;
-		case USB_SPEED_LOW:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-			break;
-		default:
-			break;
-	}
-
-	//spin_lock(&the_controller->vdev[rhport].ud.lock);
-	//the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
-	//spin_unlock(&the_controller->vdev[rhport].ud.lock);
-
-	the_controller->pending_port = rhport;
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-}
-
-void rh_port_disconnect(int rhport)
-{
-	unsigned long flags;
-
-	dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-	//stop_activity (dum, driver);
-	the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
-	the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION);
-
-
-	/* not yet complete the disconnection */
-	//spin_lock(&vdev->ud.lock);
-	//vdev->ud.status = VHC_ST_DISCONNECT;
-	//spin_unlock(&vdev->ud.lock);
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-#define PORT_C_MASK \
-	((USB_PORT_STAT_C_CONNECTION \
-	  | USB_PORT_STAT_C_ENABLE \
-	  | USB_PORT_STAT_C_SUSPEND \
-	  | USB_PORT_STAT_C_OVERCURRENT \
-	  | USB_PORT_STAT_C_RESET) << 16)
-
-/*
- * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without
- * suspend/resume support. But, it is modified to provide multiple ports.
- *
- * @buf: a bitmap to show which port status has been changed.
- *  bit  0: reserved or used for another purpose?
- *  bit  1: the status of port 0 has been changed.
- *  bit  2: the status of port 1 has been changed.
- *  ...
- *  bit  7: the status of port 6 has been changed.
- *  bit  8: the status of port 7 has been changed.
- *  ...
- *  bit 15: the status of port 14 has been changed.
- *
- * So, the maximum number of ports is 31 ( port 0 to port 30) ?
- *
- * The return value is the actual transfered length in byte. If nothing has
- * been changed, return 0. In the case that the number of ports is less than or
- * equal to 6 (VHCI_NPORTS==7), return 1.
- *
- */
-static int vhci_hub_status (struct usb_hcd *hcd, char *buf)
-{
-	struct vhci_hcd	*vhci;
-	unsigned long	flags;
-	int		retval = 0;
-
-	/* the enough buffer is allocated according to USB_MAXCHILDREN */
-	unsigned long	*event_bits = (unsigned long *) buf;
-	int		rhport;
-	int		changed = 0;
-
-
-	*event_bits = 0;
-
-	vhci = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&vhci->lock, flags);
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		dbg_vhci_rh("hw accessible flag in on?\n");
-		goto done;
-	}
-
-	/* check pseudo status register for each port */
-	for(rhport = 0; rhport < VHCI_NPORTS; rhport++) {
-		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
-			/* The status of a port has been changed, */
-			dbg_vhci_rh("port %d is changed\n", rhport);
-
-			*event_bits |= 1 << ( rhport + 1);
-			changed = 1;
-		}
-	}
-
-	if (changed)
-		retval = 1 + (VHCI_NPORTS / 8);
-	else
-		retval = 0;
-
-done:
-	spin_unlock_irqrestore (&vhci->lock, flags);
-	return retval;
-}
-
-/* See hub_configure in hub.c */
-static inline void hub_descriptor(struct usb_hub_descriptor *desc)
-{
-	memset(desc, 0, sizeof(*desc));
-	desc->bDescriptorType = 0x29;
-	desc->bDescLength = 9;
-	desc->wHubCharacteristics = (__force __u16)
-		(__constant_cpu_to_le16 (0x0001));
-	desc->bNbrPorts = VHCI_NPORTS;
-	desc->bitmap [0] = 0xff;
-	desc->bitmap [1] = 0xff;
-}
-
-
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
-{
-	struct vhci_hcd	*dum;
-	int             retval = 0;
-	unsigned long   flags;
-	int		rhport;
-
-	u32 prev_port_status[VHCI_NPORTS];
-
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
-		return -ETIMEDOUT;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 */
-	dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex);
-	if (wIndex > VHCI_NPORTS)
-		uerr("invalid port number %d\n", wIndex);
-	rhport = ((__u8 ) (wIndex & 0x00ff)) -1;
-
-	dum = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&dum->lock, flags);
-
-	/* store old status and compare now and old later */
-	if (dbg_flag_vhci_rh) {
-		int i = 0;
-		for (i = 0; i < VHCI_NPORTS; i++)
-			prev_port_status[i] = dum->port_status[i];
-	}
-
-	switch (typeReq) {
-		case ClearHubFeature:
-			dbg_vhci_rh(" ClearHubFeature\n");
-			break;
-		case ClearPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					if (dum->port_status[rhport] & (1 << USB_PORT_FEAT_SUSPEND)) {
-						/* 20msec signaling */
-						dum->resuming = 1;
-						dum->re_timeout = jiffies + msecs_to_jiffies(20);
-					}
-					break;
-				case USB_PORT_FEAT_POWER:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
-					dum->port_status[rhport] = 0;
-					//dum->address = 0;
-					//dum->hdev = 0;
-					dum->resuming = 0;
-					break;
-				case USB_PORT_FEAT_C_RESET:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_C_RESET\n");
-					switch (dum->vdev[rhport].speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							break;
-					}
-				default:
-					dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
-					dum->port_status[rhport] &= ~(1 << wValue);
-			}
-			break;
-		case GetHubDescriptor:
-			dbg_vhci_rh(" GetHubDescriptor\n");
-			hub_descriptor ((struct usb_hub_descriptor *) buf);
-			break;
-		case GetHubStatus:
-			dbg_vhci_rh(" GetHubStatus\n");
-			*(u32 *) buf = __constant_cpu_to_le32 (0);
-			break;
-		case GetPortStatus:
-			dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
-			if (wIndex > VHCI_NPORTS || wIndex < 1) {
-				uerr(" invalid port number %d\n", wIndex);
-				retval = -EPIPE;
-			}
-
-			/* we do no care of resume. */
-
-			/* whoever resets or resumes must GetPortStatus to
-			 * complete it!!
-			 *                                   */
-			if (dum->resuming && time_after (jiffies, dum->re_timeout)) {
-				uerr(" not yet\n");
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_SUSPEND);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_SUSPEND);
-				dum->resuming = 0;
-				dum->re_timeout = 0;
-				//if (dum->driver && dum->driver->resume) {
-				//	spin_unlock (&dum->lock);
-				//	dum->driver->resume (&dum->gadget);
-				//	spin_lock (&dum->lock);
-				//}
-			}
-
-			if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != 0
-					&& time_after (jiffies, dum->re_timeout)) {
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_RESET);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_RESET);
-				dum->re_timeout = 0;
-
-				if (dum->vdev[rhport].ud.status == VDEV_ST_NOTASSIGNED) {
-					dbg_vhci_rh(" enable rhport %d (status %u)\n", rhport, dum->vdev[rhport].ud.status);
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-				}
-#if 0
-				if (dum->driver) {
-
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-					/* give it the best speed we agree on */
-					dum->gadget.speed = dum->driver->speed;
-					dum->gadget.ep0->maxpacket = 64;
-					switch (dum->gadget.speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->gadget.ep0->maxpacket = 8;
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							dum->gadget.speed = USB_SPEED_FULL;
-							break;
-					}
-				}
-#endif
-
-			}
-			((u16 *) buf)[0] = cpu_to_le16 (dum->port_status[rhport]);
-			((u16 *) buf)[1] = cpu_to_le16 (dum->port_status[rhport] >> 16);
-
-			dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], ((u16 *)buf)[1] );
-			break;
-		case SetHubFeature:
-			dbg_vhci_rh(" SetHubFeature\n");
-			retval = -EPIPE;
-			break;
-		case SetPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_SUSPEND\n");
-					uerr(" not yet\n");
-#if 0
-					dum->port_status[rhport] |= (1 << USB_PORT_FEAT_SUSPEND);
-					if (dum->driver->suspend) {
-						spin_unlock (&dum->lock);
-						dum->driver->suspend (&dum->gadget);
-						spin_lock (&dum->lock);
-					}
-#endif
-					break;
-				case USB_PORT_FEAT_RESET:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
-					/* if it's already running, disconnect first */
-					if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
-						dum->port_status[rhport] &= ~(USB_PORT_STAT_ENABLE
-								| USB_PORT_STAT_LOW_SPEED
-								| USB_PORT_STAT_HIGH_SPEED);
-#if 0
-						if (dum->driver) {
-							dev_dbg (hardware, "disconnect\n");
-							stop_activity (dum, dum->driver);
-						}
-#endif
-
-						/* FIXME test that code path! */
-					}
-					/* 50msec reset signaling */
-					dum->re_timeout = jiffies + msecs_to_jiffies(50);
-
-					/* FALLTHROUGH */
-				default:
-					dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
-					dum->port_status[rhport] |= (1 << wValue);
-			}
-			break;
-
-		default:
-			uerr(" default: no such request\n");
-			//dev_dbg (hardware,
-			//		"hub control req%04x v%04x i%04x l%d\n",
-			//		typeReq, wValue, wIndex, wLength);
-
-			/* "protocol stall" on error */
-			retval = -EPIPE;
-	}
-
-	if (dbg_flag_vhci_rh) {
-		printk("port %d\n", rhport);
-		dump_port_status(prev_port_status[rhport]);
-		dump_port_status(dum->port_status[rhport]);
-	}
-	dbg_vhci_rh(" bye\n");
-
-	spin_unlock_irqrestore (&dum->lock, flags);
-
-	return retval;
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-static struct vhci_device *get_vdev(struct usb_device *udev)
-{
-	int i;
-
-	if (!udev)
-		return NULL;
-
-	for (i=0; i < VHCI_NPORTS; i++)
-		if (the_controller->vdev[i].udev == udev)
-			return port_to_vdev(i);
-
-	return NULL;
-}
-
-static void vhci_tx_urb(struct urb *urb)
-{
-	struct vhci_device *vdev = get_vdev(urb->dev);
-	struct vhci_priv *priv;
-	unsigned long flag;
-
-	if (!vdev)
-		BUG();
-
-	spin_lock_irqsave(&vdev->priv_lock, flag);
-
-	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
-	if (!priv) {
-		uerr("malloc vhci_priv\n");
-		spin_unlock_irqrestore(&vdev->priv_lock, flag);
-		usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
-	if (priv->seqnum == 0xffff)
-		uinfo("seqnum max\n");
-
-	priv->vdev = vdev;
-	priv->urb = urb;
-
-	urb->hcpriv = (void *) priv;
-
-
-	list_add_tail(&priv->list, &vdev->priv_tx);
-
-	wake_up(&vdev->waitq_tx);
-	spin_unlock_irqrestore(&vdev->priv_lock, flag);
-}
-
-static int vhci_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags);
-
-
-
-	/* patch to usb_sg_init() is in 2.5.60 */
-	BUG_ON (!urb->transfer_buffer && urb->transfer_buffer_length);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-
-	/* check HC is active or not */
-	if (!HC_IS_RUNNING(hcd->state)) {
-		uerr("HC is not running\n");
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return  -ENODEV;
-	}
-
-	if (urb->status != -EINPROGRESS) {
-		uerr("URB already unlinked!, status %d\n", urb->status);
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return urb->status;
-	}
-
-	/*
-	 * The enumelation process is as follows;
-	 *
-	 *  1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
-	 *     to get max packet length of default pipe
-	 *
-	 *  2. Set_Address request to DevAddr(0) EndPoint(0)
-	 *
-	 */
-
-	if (usb_pipedevice(urb->pipe) == 0) {
-		__u8 type = usb_pipetype(urb->pipe);
-		struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet;
-		struct vhci_device *vdev = port_to_vdev(the_controller->pending_port);
-
-		if (type != PIPE_CONTROL || !ctrlreq ) {
-			uerr("invalid request to devnum 0\n");
-			ret = EINVAL;
-			goto no_need_xmit;
-		}
-
-		switch (ctrlreq->bRequest) {
-
-			case USB_REQ_SET_ADDRESS:
-				vdev->udev = urb->dev;
-				dbg_vhci_hc("SetAddress Request (%d) to port %d\n",
-						ctrlreq->wValue, vdev->rhport);
-
-				spin_lock(&vdev->ud.lock);
-				vdev->ud.status = VDEV_ST_USED;
-				spin_unlock(&vdev->ud.lock);
-
-				spin_lock (&urb->lock);
-				if (urb->status == -EINPROGRESS) {
-					/* This request is successfully completed. */
-					/* If not -EINPROGRESS, possibly unlinked. */
-					urb->status = 0;
-				}
-				spin_unlock (&urb->lock);
-
-				goto no_need_xmit;
-
-			case USB_REQ_GET_DESCRIPTOR:
-				if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
-					dbg_vhci_hc("Not yet?: Get_Descriptor to device 0 (get max pipe size)\n");
-
-				vdev->udev = urb->dev;
-				goto out;
-
-			default:
-				/* NOT REACHED */
-				uerr("invalid request to devnum 0 bRequest %u, wValue %u\n",
-						ctrlreq->bRequest, ctrlreq->wValue);
-				ret =  -EINVAL;
-				goto no_need_xmit;
-		}
-
-	}
-
-out:
-
-
-	vhci_tx_urb(urb);
-
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-
-	return 0;
-
-
-no_need_xmit:
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-	return 0;
-}
-
-
-/*
- * vhci_rx gives back the urb after recieving the reply of the urb.  If an
- * unlink pdu is sent or not, vhci_rx recieves a normal return pdu and gives
- * back its urb. For the driver unlinking the urb, the content of the urb is
- * not important, but the calling to its completion handler is important; the
- * completion of unlinking is notified by the completion handler.
- *
- *
- * CLIENT SIDE
- *
- * - When vhci_hcd recieves RET_SUBMIT,
- *
- *	- case 1a). the urb of the pdu is not unlinking.
- *		- normal case
- *		=> just give back the urb
- *
- *	- case 1b). the urb of the pdu is unlinking.
- *		- usbip.ko will return a reply of the unlinking request.
- *		=> give back the urb now and go to case 2b).
- *
- * - When vhci_hcd recieves RET_UNLINK,
- *
- *   	- case 2a). a submit request is still pending in vhci_hcd.
- *   		- urb was really pending in usbip.ko and urb_unlink_urb() was
- *   		  completed there.
- *   		=> free a pending submit request
- *   		=> notify unlink completeness by giving back the urb
- *
- *   	- case 2b). a submit request is *not* pending in vhci_hcd.
- *   		- urb was already given back to the core driver.
- *   		=> do not give back the urb
- *
- *
- * SERVER SIDE
- *
- * - When usbip recieves CMD_UNLINK,
- *
- *	- case 3a). the urb of the unlink request is now in submission.
- *		=> do usb_unlink_urb().
- *		=> after the unlink is completed, send RET_UNLINK.
- *
- *	- case 3b). the urb of the unlink request is not in submission.
- *		- may be already completed or never be recieved
- *		=> send RET_UNLINK
- *
- */
-static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-{
-	unsigned long flags;
-	struct vhci_priv *priv;
-	struct vhci_device *vdev;
-
-	uinfo("vhci_hcd: dequeue a urb %p\n", urb);
-
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	priv = urb->hcpriv;
-	if (!priv) {
-		/* URB was never linked! or will be soon given back by vhci_rx. */
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return 0;
-	}
-
-	 /* send unlink request here? */
-	vdev = priv->vdev;
-
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		unsigned long flags2;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
-		list_del(&priv->list);
-		kfree(priv);
-		urb->hcpriv = NULL;
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-
-	} else {
-		/* tcp connection is alive */
-		unsigned long flags2;
-		struct vhci_unlink *unlink;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		/* setup CMD_UNLINK pdu */
-		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
-		if (!unlink) {
-			uerr("malloc vhci_unlink\n");
-			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-			spin_unlock_irqrestore(&the_controller->lock, flags);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-			return -ENOMEM;
-		}
-
-		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
-		if (unlink->seqnum == 0xffff)
-			uinfo("seqnum max\n");
-
-		unlink->unlink_seqnum = priv->seqnum;
-
-		uinfo("vhci_hcd: device %p seems to be still connected\n", vdev);
-
-		/* send cmd_unlink and try to cancel the pending URB in the peer */
-		list_add_tail(&unlink->list, &vdev->unlink_tx);
-		wake_up(&vdev->waitq_tx);
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-	}
-	
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-	/*
-	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will recieve RET_UNLINK and giveb back the URB.
-	 * Otherwise, we give back it here.
-	 */
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	dbg_vhci_hc("leave\n");
-	return 0;
-}
-
-
-static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock(&vdev->priv_lock);
-}
-
-/*
- * The important thing is that only one context begins cleanup.
- * This is why error handling and cleanup become simple.
- * We do not want to consider race condition as possible.
- */
-static void vhci_shutdown_connection(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	/* need this? see stub_dev.c */
-	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	usbip_stop_threads(&vdev->ud);
-	uinfo("stop threads\n");
-
-	/* active connection is closed */
-	if (vdev->ud.tcp_socket != NULL) {
-		sock_release(vdev->ud.tcp_socket);
-		vdev->ud.tcp_socket = NULL;
-	}
-	uinfo("release socket\n");
-
-	vhci_device_unlink_cleanup(vdev);
-
-	/*
-	 * rh_port_disconnect() is a trigger of ...
-	 *   usb_disable_device():
-	 * 	disable all the endpoints for a USB device.
-	 *   usb_disable_endpoint():
-	 * 	disable endpoints. pending urbs are unlinked(dequeued).
-	 *
-	 * NOTE: After calling rh_port_disconnect(), the USB device driver of a
-	 * deteched device should release used urbs in a cleanup function(i.e.
-	 * xxx_disconnect()). Therefore, vhci_hcd does not need to release
-	 * pushed urbs and their private data in this function.
-	 *
-	 * NOTE: vhci_dequeue() must be considered carefully. When shutdowning
-	 * a connection, vhci_shutdown_connection() expects vhci_dequeue()
-	 * gives back pushed urbs and frees their private data by request of
-	 * the cleanup function of a USB driver. When unlinking a urb with an
-	 * active connection, vhci_dequeue() does not give back the urb which
-	 * is actually given back by vhci_rx after recieving its return pdu.
-	 *
-	 */
-	rh_port_disconnect(vdev->rhport);
-
-	uinfo("disconnect device\n");
-}
-
-
-static void vhci_device_reset(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	spin_lock(&ud->lock);
-
-	vdev->busnum = 0;
-	vdev->devnum = 0;
-	vdev->speed  = 0;
-
-	ud->tcp_socket = NULL;
-
-	ud->status = VDEV_ST_NULL;
-
-	spin_unlock(&ud->lock);
-}
-
-static void vhci_device_unusable(struct usbip_device* ud)
-{
-	spin_lock(&ud->lock);
-
-	ud->status = VDEV_ST_ERROR;
-
-	spin_unlock(&ud->lock);
-}
-
-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.side   = USBIP_VHCI;
-	vdev->ud.status = VDEV_ST_NULL;
-	vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
-
-	INIT_LIST_HEAD(&vdev->priv_rx);
-	INIT_LIST_HEAD(&vdev->priv_tx);
-	INIT_LIST_HEAD(&vdev->unlink_tx);
-	INIT_LIST_HEAD(&vdev->unlink_rx);
-	vdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	init_waitqueue_head(&vdev->waitq_tx);
-
-	vdev->ud.eh_ops.shutdown = vhci_shutdown_connection;
-	vdev->ud.eh_ops.reset = vhci_device_reset;
-	vdev->ud.eh_ops.unusable= vhci_device_unusable;
-
-	usbip_start_eh(&vdev->ud);
-}
-
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_start(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport;
-
-	dbg_vhci_hc("enter vhci_start\n");
-
-
-	/* initialize private data of usb_hcd */
-
-	for(rhport=0; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-		vhci_device_init(vdev);
-		vdev->rhport = rhport;
-	}
-
-	atomic_set(&vhci->seqnum, 0);
-	spin_lock_init(&vhci->lock);
-
-
-
-	//hcd->power_budget = 0; /* no limit ? */
-	hcd->state  = HC_STATE_RUNNING;
-	//hcd->uses_new_polling = 1;
-
-
-	/* vhci_hcd is now ready to be controlled through sysfs */
-	sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	return 0;
-}
-
-static void vhci_stop(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport = 0;
-
-	dbg_vhci_hc("stop VHCI controller\n");
-
-
-	/* 1. remove the userland interface of vhci_hcd */
-	sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	/* 2. shutdown all the ports of vhci_hcd */
-	for(rhport = 0 ; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-
-		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
-		usbip_stop_eh(&vdev->ud);
-	}
-
-
-	uinfo("vhci_stop done\n");
-}
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_get_frame_number(struct usb_hcd *hcd)
-{
-	uerr("Not yet implemented\n");
-	return 0;
-}
-
-
-#ifdef  CONFIG_PM
-
-static int vhci_bus_suspend(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-static int vhci_bus_resume(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-#else
-
-#define vhci_bus_suspend      NULL
-#define vhci_bus_resume       NULL
-#endif
-
-
-
-static struct hc_driver vhci_hc_driver = {
-	.description	= driver_name,
-	.product_desc	= driver_desc,
-	.hcd_priv_size	= sizeof(struct vhci_hcd),
-
-	.flags		= HCD_USB2,
-
-	.start		= vhci_start,
-	.stop 		= vhci_stop,
-
-	.urb_enqueue	= vhci_urb_enqueue,
-	.urb_dequeue	= vhci_urb_dequeue,
-
-	.get_frame_number = vhci_get_frame_number,
-
-	.hub_status_data = vhci_hub_status,
-	.hub_control    = vhci_hub_control,
-	.bus_suspend	= vhci_bus_suspend,
-	.bus_resume	= vhci_bus_resume,
-};
-
-static int vhci_hcd_probe(struct platform_device *pdev)
-{
-	struct usb_hcd		*hcd;
-	int			ret;
-
-	uinfo("proving...\n");
-
-	dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
-
-
-	/* will be removed */
-	if (pdev->dev.dma_mask) {
-		info("vhci_hcd DMA not supported\n");
-		return -EINVAL;
-	}
-
-
-	/*
-	 * Allocate and initialize hcd.
-	 * Our private data is also allocated automatically.
-	 */
-	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id);
-	if (!hcd) {
-		uerr("create hcd failed\n");
-		return -ENOMEM;
-	}
-
-
-	/* this is private data for vhci_hcd */
-	the_controller = hcd_to_vhci(hcd);
-
-	/*
-	 * Finish generic HCD structure initialization and register.
-	 * Call the driver's reset() and start() routines.
-	 */
-	ret = usb_add_hcd(hcd, 0, 0);
-	if (ret != 0) {
-		uerr("usb_add_hcd failed %d\n", ret);
-		usb_put_hcd(hcd);
-		the_controller = NULL;
-		return ret;
-	}
-	
-
-	dbg_vhci_hc("bye\n");
-	return 0;
-}
-
-
-static int vhci_hcd_remove(struct platform_device *pdev)
-{
-	struct usb_hcd	*hcd;
-
-
-	hcd = platform_get_drvdata(pdev);
-	if(!hcd)
-		return 0;
-
-	/*
-	 * Disconnects the root hub,
-	 * then reverses the effects of usb_add_hcd(),
-	 * invoking the HCD's stop() methods.
-	 */
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-	the_controller = NULL;
-
-
-	return 0;
-}
-
-
-
-#ifdef CONFIG_PM
-
-/* what should happen for USB/IP under suspend/resume? */
-static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = state;
-
-	return 0;
-}
-
-static int vhci_hcd_resume(struct platform_device *pdev)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	return 0;
-}
-
-#else
-
-#define vhci_hcd_suspend	NULL
-#define vhci_hcd_resume		NULL
-
-#endif
-
-
-static struct platform_driver vhci_driver = {
-	.probe	= vhci_hcd_probe,
-	.remove	= __devexit_p(vhci_hcd_remove),
-	.suspend = vhci_hcd_suspend,
-	.resume	= vhci_hcd_resume,
-	.driver	= {
-		.name = (char *) driver_name,
-		.owner = THIS_MODULE,
-	},
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
- * We need to add this virtual device as a platform device arbitrarily:
- * 	1. platform_device_register()
- */
-static void the_pdev_release(struct device *dev)
-{
-	return;
-}
-
-static struct platform_device the_pdev = {
-	/* should be the same name as driver_name */
-	.name = (char *) driver_name,
-	.id = -1,
-	.dev = {
-		//.driver = &vhci_driver,
-		.release = the_pdev_release,
-	},
-};
-
-static int __init vhci_init(void)
-{
-	int ret;
-
-	dbg_vhci_hc("enter\n");
-	if (usb_disabled())
-		return -ENODEV;
-
-	info("driver %s, %s\n", driver_name, DRIVER_VERSION);
-
-	ret = platform_driver_register(&vhci_driver);
-	if (ret < 0)
-		goto err_driver_register;
-
-	ret = platform_device_register(&the_pdev);
-	if (ret < 0)
-		goto err_platform_device_register;
-
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-
-
-
-	/* error occurred */
-
-err_platform_device_register:
-	platform_driver_unregister(&vhci_driver);
-
-err_driver_register:
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-}
-module_init(vhci_init);
-
-
-static void __exit vhci_cleanup(void)
-{
-	dbg_vhci_hc("enter\n");
-
-	platform_device_unregister(&the_pdev);
-	platform_driver_unregister(&vhci_driver);
-
-	dbg_vhci_hc("bye\n");
-}
-module_exit(vhci_cleanup);
diff -Naur usbip-0.1.4/drivers/2.6.17/vhci_rx.c trunk/drivers/2.6.17/vhci_rx.c
--- usbip-0.1.4/drivers/2.6.17/vhci_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/vhci_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,239 +0,0 @@
-/*
- * $Id: vhci_rx.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
-{
-	struct vhci_priv *priv, *tmp;
-	struct urb *urb = NULL;
-
-
-	spin_lock(&vdev->priv_lock);
-
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
-		if (priv->seqnum == seqnum) {
-			urb = priv->urb;
-			dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", urb, priv, seqnum);
-
-
-			if (urb->status != -EINPROGRESS) {
-				 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
-					 uinfo("urb %p was unlinked %ssynchronuously.\n",
-							 urb, urb->status == -ENOENT ? "" : "a");
-				 } else {
-					 uinfo("urb %p may be in a error, status %d\n",
-							 urb, urb->status);
-				 }
-			}
-
-
-			list_del(&priv->list);
-			kfree(priv);
-			urb->hcpriv = NULL;
-
-
-			break;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-
-	return urb;
-}
-
-static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &vdev->ud;
-	struct urb *urb;
-
-
-	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
-
-
-	if (!urb) {
-		uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
-		uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-
-	/* unpack the pdu to a urb */
-	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
-
-
-	/* recv transfer buffer */
-	if (usbip_recv_xbuff(ud, urb) < 0)
-		return;
-
-
-	/* recv iso_packet_descriptor */
-	if (usbip_recv_iso(ud, urb) < 0)
-		return;
-
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_urb(urb);
-
-
-	dbg_vhci_rx("now giveback urb %p\n", urb);
-
-
-
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-
-	dbg_vhci_rx("Leave\n");
-
-	return;
-}
-
-
-static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
-		struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		uinfo("unlink->seqnum %lu\n", unlink->seqnum);
-		if (unlink->seqnum == pdu->base.seqnum) {
-			dbg_vhci_rx("found pending unlink, %lu\n", unlink->seqnum);
-			list_del(&unlink->list);
-
-			spin_unlock(&vdev->priv_lock);
-			return unlink;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-	return NULL;
-}
-
-
-static void vhci_recv_ret_unlink(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink;
-	struct urb *urb;
-	
-	usbip_dump_header(pdu);
-
-	unlink = dequeue_pending_unlink(vdev, pdu);
-	if (!unlink) {
-		uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
-		return;
-	}
-
-	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
-	if (!urb) {
-		/*
-		 * I get the result of a unlink request. But, it seems that I
-		 * already recieved the result of its submit result and gave
-		 * back the URB.
-		 */
-		uinfo("the urb (seqnum %d) was already given backed\n", pdu->base.seqnum);
-	} else {
-		dbg_vhci_rx("now giveback urb %p\n", urb);
-
-		/* If unlink is succeed, status is -ECONNRESET */
-		urb->status = pdu->u.ret_unlink.status;
-		uinfo("%d\n", urb->status);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	kfree(unlink);
-
-	return;
-}
-
-/* recv a pdu */
-static void vhci_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-
-	dbg_vhci_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_header(&pdu);
-
-	switch(pdu.base.command) {
-		case USBIP_RET_SUBMIT:
-			vhci_recv_ret_submit(vdev, &pdu);
-			break;
-
-		case USBIP_RET_UNLINK:
-			vhci_recv_ret_unlink(vdev, &pdu);
-			break;
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu %u\n", pdu.base.command);
-			usbip_dump_header(&pdu);
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_vhci_rx("signal catched!\n");
-			break;
-		}
-
-
-		if (usbip_event_happend(ud)) break;
-
-		vhci_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.17/vhci_sysfs.c trunk/drivers/2.6.17/vhci_sysfs.c
--- usbip-0.1.4/drivers/2.6.17/vhci_sysfs.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/vhci_sysfs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,286 +0,0 @@
-/*
- * $Id: vhci_sysfs.c 195 2006-10-24 10:11:08Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* TODO: refine locking ?*/
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to show port status */
-
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-		char *out)
-{
-	char *s = out;
-	int i = 0;
-
-	if (!the_controller || !out)
-		BUG();
-
-	spin_lock(&the_controller->lock);
-
-	/*
-	 * output example:
-	 * prt sta bus dev socket           local_busid
-	 * 000 004 000 000         c5a7bb80 1-2.3
-	 * 001 004 000 000         d8cee980 2-3.4
-	 *
-	 * IP address can be retrieved from a socket pointer address by looking
-	 * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
-	 * port number and its peer IP address.
-	 */
-	out += sprintf(out, "prt sta spd bus dev socket           local_busid\n");
-
-	for (i=0; i < VHCI_NPORTS; i++) {
-		struct vhci_device *vdev = port_to_vdev(i);
-
-		spin_lock(&vdev->ud.lock);
-
-		out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
-
-		if (vdev->ud.status == VDEV_ST_USED) {
-			out += sprintf(out, "%03u %03u %03u ",
-					vdev->speed, vdev->busnum, vdev->devnum);
-			out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
-			out += sprintf(out, "%s", vdev->udev->dev.bus_id);
-
-		} else
-			out += sprintf(out, "000 000 000 0000000000000000 0-0");
-
-		out += sprintf(out, "\n");
-
-		spin_unlock(&vdev->ud.lock);
-	}
-
-	spin_unlock(&the_controller->lock);
-
-	return out - s ;
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to shutdown a virtual connection */
-
-static int vhci_port_disconnect(__u32 rhport)
-{
-	struct vhci_device *vdev;
-
-	dbg_vhci_sysfs("enter\n");
-
-	/* lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-	if (vdev->ud.status == VDEV_ST_NULL) {
-		uerr("not connected %d\n", vdev->ud.status);
-
-		/* unlock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		return -EINVAL;
-	}
-
-	/* unlock */
-	spin_unlock(&vdev->ud.lock);
-	spin_unlock(&the_controller->lock);
-
-	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
-
-	return 0;
-}
-
-static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count) {
-	int err;
-	__u32 rhport = 0;
-
-	sscanf(buf, "%u", &rhport);
-
-	/* check rhport */
-	if (rhport >= VHCI_NPORTS) {
-		uerr("invalid port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	err = vhci_port_disconnect(rhport);
-	if (err < 0) {
-		return -EINVAL;
-	}
-
-	dbg_vhci_sysfs("Leave\n");
-	return count;
-}
-
-static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to establish a virtual connection */
-
-static int valid_args(__u32 rhport, __u32 busnum, __u32 devnum,
-		enum usb_device_speed speed)
-{
-	/* check rhport */
-	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		uerr("port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	/* check busnum & devnum */
-	if ((busnum <= 0) || (busnum >= 128) || (devnum <= 0) || (devnum >= 128)) {
-		uerr("busnum %u devnum %u\n", busnum, devnum);
-		return -EINVAL;
-	}
-
-	/* check speed */
-	switch(speed) {
-		case USB_SPEED_LOW:
-		case USB_SPEED_FULL:
-		case USB_SPEED_HIGH:
-		case USB_SPEED_VARIABLE:
-			break;
-
-		default:
-			uerr("speed %d\n", speed);
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * To start a new USB/IP attachment, a userland program needs to setup a TCP
- * connection and then write its socket descriptor with remote device
- * information into this sysfs file.
- *
- * A remote device is virtually attached to the root-hub port of @rhport with
- * @speed. @busnum and @devnum are used to convert URBs between a client host
- * and a server host.
- *
- * write() returns 0 on success, else negative errno.
- */
-static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct vhci_device *vdev;
-	struct socket *socket;
-	int sockfd = 0;
-	__u32 rhport=0, busnum=0, devnum=0, speed=0;
-
-
-	/*
-	 * @rhport: port number of vhci_hcd
-	 * @sockfd: socket descriptor of an established TCP connection
-	 * @busnum: usb bus number in a remote host
-	 * @devnum: usb device number in a remote host
-	 * @speed: usb device speed in a remote host
-	 */
-	sscanf(buf, "%u %u %u %u %u", &rhport, &sockfd, &busnum, &devnum, &speed);
-
-	dbg_vhci_sysfs("rhport(%u) sockfd(%u) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-
-	/* check recieved parameters */
-	if (valid_args(rhport, busnum, devnum, speed) < 0)
-		return -EINVAL;
-
-	/* check sockfd */
-	socket = sockfd_to_socket(sockfd);
-	if (!socket)
-		return  -EINVAL;
-
-	setnodelay(socket);
-
-
-	/* now need lock until setting vdev status as used */
-
-	/* begin a lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-
-	if (vdev->ud.status != VDEV_ST_NULL) {
-		/* end of the lock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		uerr("port %d already used\n", rhport);
-		return -EINVAL;
-	}
-
-	uinfo("rhport(%u) sockfd(%d) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-	vdev->busnum        = busnum;
-	vdev->devnum        = devnum;
-	vdev->speed         = speed;
-	vdev->ud.tcp_socket = socket;
-	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
-
-	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;
-}
-
-static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_status.attr,
-	&dev_attr_detach.attr,
-	&dev_attr_attach.attr,
-	&dev_attr_usbip_debug.attr,
-	NULL,
-};
-
-struct attribute_group dev_attr_group = {
-	.attrs = dev_attrs,
-};
diff -Naur usbip-0.1.4/drivers/2.6.17/vhci_tx.c trunk/drivers/2.6.17/vhci_tx.c
--- usbip-0.1.4/drivers/2.6.17/vhci_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.17/vhci_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,264 +0,0 @@
-/*
- * $Id: vhci_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* @p: pipe whose dev number modified
- * @pdev: new devive number */
-static unsigned long tweak_pipe_devnum(__u32 p, __u8 pdev)
-{
-	__u32 oldp;
-	oldp = p;
-
-	if (pdev > 0x7f)
-		uerr("invalid devnum %u\n", pdev);
-
-	pdev &= 0x7f;    // 0XXX XXXX  confirm MSB be 0
-
-	p &= 0xffff80ff; /* clear p's devnum */
-
-	p |= (pdev << 8);
-
-	dbg_vhci_tx("return new pipe, devnum %u -> %u \n",
-		    usb_pipedevice(oldp), usb_pipedevice(p));
-	dbg_vhci_tx("           pipe %08x -> %08x\n", oldp, p);
-
-	return p;
-}
-
-static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
-{
-	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
-	struct vhci_device *vdev = priv->vdev;
-
-	dbg_vhci_tx("URB, local devnum(%u), busnum(%u) devnum(%u)\n",
-	            usb_pipedevice(urb->pipe), vdev->busnum, vdev->devnum);
-
-	pdup->base.command = USBIP_CMD_SUBMIT;
-	pdup->base.busnum  = vdev->busnum;
-	pdup->base.devnum  = vdev->devnum;
-	pdup->base.seqnum  = priv->seqnum;
-	pdup->base.pipe	   = tweak_pipe_devnum(urb->pipe, vdev->devnum);
-
-	usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
-
-	if (urb->setup_packet)
-		memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8);
-}
-
-static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_priv *priv, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) {
-		list_move_tail(&priv->list, &vdev->priv_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-
-static int vhci_send_cmd_submit(struct vhci_device *vdev)
-{
-	struct vhci_priv *priv = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(vdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_cmd_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->transfer_buffer_length;
-			txsize += urb->transfer_buffer_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_move_tail(&unlink->list, &vdev->unlink_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int vhci_send_cmd_unlink(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
-
-
-		/* 1. setup usbip_header */
-		pdu_header.base.command = USBIP_CMD_UNLINK;
-		pdu_header.base.busnum  = vdev->busnum;
-		pdu_header.base.devnum  = vdev->devnum;
-		pdu_header.base.seqnum  = unlink->seqnum;
-		pdu_header.base.pipe	= 0;
-		pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum;
-
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			uinfo("vhci_tx signal catched\n");
-			break;
-		}
-
-		if (vhci_send_cmd_submit(vdev) < 0)
-			break;
-
-		if (vhci_send_cmd_unlink(vdev) < 0)
-			break;
-
-		wait_event_interruptible(vdev->waitq_tx,
-				(!list_empty(&vdev->priv_tx) ||
-				 !list_empty(&vdev->unlink_tx)));
-
-		dbg_vhci_tx("pending urbs ?, now wake up\n");
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.18/Makefile trunk/drivers/2.6.18/Makefile
--- usbip-0.1.4/drivers/2.6.18/Makefile	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,63 +0,0 @@
-# Makefile for the USB/IP driver
-#
-# $Id: Makefile 97 2006-03-31 16:08:40Z taka-hir $
-#
-# Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
-#
-#
-# 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.
-#
-
- 
-# Please modify here or set environments.
-# KSOURCE should be pointed to the build directory of your kernel.
-# 
-DEBUG ?= n
-KSOURCE ?= /usr/src/linux
-
-
-%.x:%.c
-	gcc -o $@ $<
-
-KBUILD_VERBOSE:=1
-
-HCD_HEADER:=$(KSOURCE)/drivers/usb/core/hcd.h
-
-obj-m += usbip.o
-usbip-objs :=  usbip_common.o usbip_event.o stub_dev.o stub_main.o stub_rx.o stub_tx.o
-
-obj-m += vhci-hcd.o
-vhci-hcd-objs :=  usbip_common.o usbip_event.o vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
-
-
-EXTRA_CFLAGS += -DHCD_HEADER=\"$(HCD_HEADER)\"
-
-ifeq ($(DEBUG),y)
-	EXTRA_CFLAGS += -DCONFIG_USB_DEBUG
-endif
-
-
-default:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` modules
-
-.PHONY: cscope
-cscope:
-	cscope -b -k -R
-
-.PHONY: clean
-clean:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` clean
-	rm -f *.x *~
diff -Naur usbip-0.1.4/drivers/2.6.18/stub_dev.c trunk/drivers/2.6.18/stub_dev.c
--- usbip-0.1.4/drivers/2.6.18/stub_dev.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/stub_dev.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,438 +0,0 @@
-/*
- * $Id: stub_dev.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-
-static int stub_probe(struct usb_interface *interface,  const struct usb_device_id *id);
-static void stub_disconnect(struct usb_interface *interface);
-
-
-/*
- * Define device IDs here if you want to explicitly limit exportable devices.
- * In the most cases, wild card matching will be ok because driver binding can
- * be changed dynamically by a userland program.
- */
-static struct usb_device_id stub_table[] = {
-#if 0
-	/* just an example */
-	{ USB_DEVICE(0x05ac, 0x0301) },   /* Mac 1 button mouse */
-	{ USB_DEVICE(0x0430, 0x0009) },   /* Plat Home Keyboard */
-	{ USB_DEVICE(0x059b, 0x0001) },   /* Iomega USB Zip 100 */
-	{ USB_DEVICE(0x04b3, 0x4427) },   /* IBM USB CD-ROM */
-	{ USB_DEVICE(0x05a9, 0xa511) },   /* LifeView USB cam */
-	{ USB_DEVICE(0x55aa, 0x0201) },   /* Imation card reader */
-	{ USB_DEVICE(0x046d, 0x0870) },   /* Qcam Express(QV-30) */
-	{ USB_DEVICE(0x04bb, 0x0101) },   /* IO-DATA HD 120GB */
-	{ USB_DEVICE(0x04bb, 0x0904) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x04bb, 0x0201) },   /* IO-DATA USB-ET/TX */
-	{ USB_DEVICE(0x08bb, 0x2702) },   /* ONKYO USB Speaker */
-	{ USB_DEVICE(0x046d, 0x08b2) },   /* Logicool Qcam 4000 Pro */
-#endif
-	/* magic for wild card */
-	{ .driver_info = 1 },
-	{ }                                     /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, stub_table);
-
-
-struct usb_driver stub_driver = {
-	.name		= "usbip",
-
-	.probe		= stub_probe,
-	.disconnect 	= stub_disconnect,
-
-	.id_table	= stub_table,
-};
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for a usbip-bound device */
-
-
-/*
- * usbip_status shows status of usbip as long as this driver is bound to the
- * target device.
- */
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct stub_device *sdev = dev_get_drvdata(dev);
-	int status;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	spin_lock(&sdev->ud.lock);
-	status = sdev->ud.status;
-	spin_unlock(&sdev->ud.lock);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", status);
-}
-static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
-
-
-/*
- * 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;
-
-	if (!sdev) {
-		uerr("sdev is null\n");
-		return -ENODEV;
-	}
-
-	sscanf(buf, "%d", &sockfd);
-
-	if (sockfd != -1) {
-		uinfo("stub up\n");
-
-		spin_lock(&sdev->ud.lock);
-
-		if (sdev->ud.status != SDEV_ST_AVAILABLE) {
-			uerr("not ready\n");
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		socket = sockfd_to_socket(sockfd);
-		if (!socket) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-
-		setnodelay(socket);
-		setkeepalive(socket);
-		setreuse(socket);
-
-		sdev->ud.tcp_socket = socket;
-
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_start_threads(&sdev->ud);
-
-		spin_lock(&sdev->ud.lock);
-		sdev->ud.status = SDEV_ST_USED;
-		spin_unlock(&sdev->ud.lock);
-
-	} else {
-		uinfo("stub down\n");
-
-		spin_lock(&sdev->ud.lock);
-		if (sdev->ud.status != SDEV_ST_USED) {
-			spin_unlock(&sdev->ud.lock);
-			return -EINVAL;
-		}
-		spin_unlock(&sdev->ud.lock);
-
-		usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
-	}
-
-	return count;
-}
-static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
-
-static void stub_add_files(struct device *dev)
-{
-	device_create_file(dev, &dev_attr_usbip_status);
-	device_create_file(dev, &dev_attr_usbip_sockfd);
-	device_create_file(dev, &dev_attr_usbip_debug);
-}
-
-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);
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Event handler functions called by an event handler thread */
-
-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) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	/* 1. stop threads */
-	usbip_stop_threads(ud);
-
-	/* 2. close the socket */
-	/*
-	 * tcp_socket is freed after threads are killed.
-	 * So usbip_xmit do not touch NULL socket.
-	 */
-	if (ud->tcp_socket) {
-		sock_release(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);
-	struct usb_device *udev = interface_to_usbdev(sdev->interface);
-	int ret;
-
-	ret = usb_lock_device_for_reset(udev, sdev->interface);
-	if (ret < 0) {
-		uerr("lock for reset\n");
-
-		spin_lock(&ud->lock);
-		ud->status = SDEV_ST_ERROR;
-		spin_unlock(&ud->lock);
-
-		return;
-	}
-
-	/* try to reset the device */
-	ret = usb_reset_device(udev);
-
-	usb_unlock_device(udev);
-
-	spin_lock(&ud->lock);
-	if (ret) {
-		uerr("device reset\n");
-		ud->status = SDEV_ST_ERROR;
-
-	} else {
-		uinfo("device reset\n");
-		ud->status = SDEV_ST_AVAILABLE;
-
-	}
-	spin_unlock(&ud->lock);
-
-	return;
-}
-
-static void stub_device_unusable(struct usbip_device *ud)
-{
-	spin_lock(&ud->lock);
-	ud->status = SDEV_ST_ERROR;
-	spin_unlock(&ud->lock);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * stub_device_alloc - allocate a new stub_device struct
- * @interface: usb_interface of a new device
- *
- * Allocates and initializes a new stub_devce struct.
- */
-static struct stub_device * stub_device_alloc(struct usb_interface *interface)
-{
-	struct stub_device *sdev;
-
-	/* yes, it's a new device */
-	sdev = (struct stub_device *) kzalloc(sizeof(struct stub_device), GFP_KERNEL);
-	if (!sdev) {
-		uerr("no memory for stub_device\n");
-		return NULL;
-	}
-
-	sdev->interface = interface;
-
-	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;
-	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);
-	sdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	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);
-
-	udbg("register new interface\n");
-	return sdev;
-}
-
-static int stub_device_free(struct stub_device *sdev)
-{
-	if (!sdev)
-		return -EINVAL;
-
-	kfree(sdev);
-	udbg("kfree udev ok\n");
-
-	return 0;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e. not *an*
- * active interface). Currently, a userland program must ensure that it
- * looks at the usbip's sysfs entries of only the first active interface.
- */
-static int stub_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	struct stub_device *sdev = NULL;
-	char *udev_busid = interface->dev.parent->bus_id;
-
-	udbg("Enter\n");
-
-	/* check we should claim or not by busid_table */
-	if (match_busid(udev_busid)) {
-		uinfo("this device %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) {
-		udbg("this device %s is a usb hub device. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		udbg("this device %s is attached on vhci_hcd. skip!\n", udev_busid);
-		return -ENODEV;
-	}
-
-	/* ok. this is my device. */
-
-	if ((sdev = stub_device_alloc(interface))) {
-		struct usb_device *udev = interface_to_usbdev(interface);
-
-		uinfo("USB/IP Stub: register a new interface (bus %u dev %u ifn %u)\n",
-				udev->bus->busnum, udev->devnum,
-				interface->cur_altsetting->desc.bInterfaceNumber);
-	} else
-		return -ENOMEM;
-
-	/* set private data to usb_interface */
-	usb_set_intfdata(interface, sdev);
-
-	stub_add_files(&interface->dev);
-
-	return 0;
-}
-
-
-/*
- * called in usb_disconnect() or usb_deregister()
- * but only if actconfig(active configuration) exists
- */
-static void stub_disconnect(struct usb_interface *interface)
-{
-	struct stub_device *sdev = usb_get_intfdata(interface);
-
-	udbg("Enter\n");
-
-	/* get stub_device */
-	if (!sdev)
-		BUG();
-
-	usb_set_intfdata(interface, NULL);
-
-
-	/*
-	 * NOTE:
-	 * rx/tx threads are invoked for each usb_device.
-	 */
-	stub_remove_files(&interface->dev);
-
-	/* 1. shutdown the current connection */
-	usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
-
-	/* 2. wait for the stop of the event handler */
-	usbip_stop_eh(&sdev->ud);
-
-	/* 3. free sdev */
-	stub_device_free(sdev);
-
-
-	udbg("bye\n");
-}
diff -Naur usbip-0.1.4/drivers/2.6.18/stub.h trunk/drivers/2.6.18/stub.h
--- usbip-0.1.4/drivers/2.6.18/stub.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/stub.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,96 +0,0 @@
-/*
- * $Id: stub.h 173 2006-07-21 09:48:40Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-
-struct stub_device {
-	struct usb_interface *interface;
-	struct list_head list;
-
-	struct usbip_device ud;
-
-	/*
-	 * stub_priv preserves private data of each urb.
-	 * It is allocated as stub_priv_cache and assigned to urb->context.
-	 *
-	 * stub_priv is always linked to any one of 3 lists;
-	 * 	priv_init: linked to this until the comletion of a urb.
-	 * 	priv_tx  : linked to this after the completion of a urb.
-	 * 	priv_free: linked to this after the sending of the result.
-	 *
-	 * Any of these list operations should be locked by priv_lock.
-	 */
-	spinlock_t priv_lock;
-	struct list_head priv_init;
-	struct list_head priv_tx;
-	struct list_head priv_free;
-
-	/* see comments for unlinking in stub_rx.c */
-	struct list_head unlink_tx;
-	struct list_head unlink_free;
-
-
-	wait_queue_head_t tx_waitq;
-};
-
-/* private data into urb->priv */
-struct stub_priv {
-	unsigned long seqnum;
-	struct list_head list;
-	struct stub_device *sdev;
-	struct urb *urb;
-
-	int unlinking;
-};
-
-struct stub_unlink {
-	unsigned long seqnum;
-	struct list_head list;
-	__u32 status;
-};
-
-
-extern kmem_cache_t *stub_priv_cache;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declarations */
-
-/* stub_tx.c */
-void stub_complete(struct urb*, struct pt_regs *);
-void stub_tx_loop(struct usbip_task *);
-
-/* stub_dev.c */
-extern struct usb_driver stub_driver;
-
-/* stub_rx.c */
-void stub_rx_loop(struct usbip_task *);
-void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
-
-/* stub_main.c */
-int match_busid(char *busid);
-void stub_device_cleanup_urbs(struct stub_device *sdev);
diff -Naur usbip-0.1.4/drivers/2.6.18/stub_main.c trunk/drivers/2.6.18/stub_main.c
--- usbip-0.1.4/drivers/2.6.18/stub_main.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/stub_main.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,300 +0,0 @@
-/*
- * $Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-/* Version Information */
-#define DRIVER_VERSION "$Id: stub_main.c 192 2006-10-24 08:51:47Z taka-hir $"
-#define DRIVER_AUTHOR "Takahiro Hirofuchi <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Stub Driver for USB/IP"
-
-
-
-/* stub_priv is allocated from stub_priv_cache */
-kmem_cache_t *stub_priv_cache = NULL;
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for the usbip driver */
-
-
-/*
- * busid_tables defines matching busids that usbip can grab. A user can change
- * dynamically what device is locally used and what device is exported to a
- * remote host.
- */
-#define MAX_BUSID 16
-static char busid_table[MAX_BUSID][BUS_ID_SIZE];
-spinlock_t busid_table_lock = SPIN_LOCK_UNLOCKED;
-
-
-int match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-				/* already registerd */
-				spin_unlock(&busid_table_lock);
-				return 0;
-			}
-
-	spin_unlock(&busid_table_lock);
-
-	return 1;
-}
-
-static ssize_t show_match_busid(struct device_driver *drv, char *buf)
-{
-	int i;
-	char *out = buf;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (busid_table[i][0])
-			out += sprintf(out, "%s ", busid_table[i]);
-
-	spin_unlock(&busid_table_lock);
-
-	out += sprintf(out, "\n");
-
-	return out - buf;
-}
-
-static int add_match_busid(char *busid)
-{
-	int i;
-
-	if (!match_busid(busid))
-		return 0;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!busid_table[i][0]) {
-			strncpy(busid_table[i], busid, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static int del_match_busid(char *busid)
-{
-	int i;
-
-	spin_lock(&busid_table_lock);
-
-	for (i = 0; i < MAX_BUSID; i++)
-		if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
-			/* found */
-			memset(busid_table[i], 0, BUS_ID_SIZE);
-			spin_unlock(&busid_table_lock);
-			return 0;
-		}
-
-	spin_unlock(&busid_table_lock);
-
-	return -1;
-}
-
-static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
-		size_t count)
-{
-	int len;
-	char busid[BUS_ID_SIZE];
-
-	if (count < 5)
-		return -EINVAL;
-
-	/* strnlen() does not include \0 */
-	len = strnlen(buf + 4, BUS_ID_SIZE);
-
-	/* busid needs to include \0 termination */
-	if (!(len < BUS_ID_SIZE))
-		return -EINVAL;
-
-	strncpy(busid, buf + 4, BUS_ID_SIZE);
-
-
-	if (!strncmp(buf, "add ", 4)) {
-		if (add_match_busid(busid) < 0)
-			return -ENOMEM;
-		else {
-			udbg("add busid %s\n", busid);
-			return count;
-		}
-	} else if (!strncmp(buf, "del ", 4)) {
-		if (del_match_busid(busid) < 0)
-			return -ENODEV;
-		else {
-			udbg("del busid %s\n", busid);
-			return count;
-		}
-	} else
-		return -EINVAL;
-}
-
-static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, store_match_busid);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Cleanup functions used to free private data */
-
-static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
-{
-	struct stub_priv *priv, *tmp;
-
-	list_for_each_entry_safe(priv, tmp, listhead, list) {
-		list_del(&priv->list);
-		return priv;
-	}
-
-	return NULL;
-}
-
-static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_init);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	priv = stub_priv_pop_from_listhead(&sdev->priv_free);
-	if (priv) {
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-	return NULL;
-}
-
-void stub_device_cleanup_urbs(struct stub_device *sdev)
-{
-	struct stub_priv *priv;
-
-	udbg("free sdev %p\n", sdev);
-
-	while ((priv = stub_priv_pop(sdev))) {
-		struct urb *urb = priv->urb;
-
-		udbg("   free urb %p\n", urb);
-		usb_kill_urb(urb);
-
-		kmem_cache_free(stub_priv_cache, priv);
-
-		if (urb->transfer_buffer != NULL)
-			kfree(urb->transfer_buffer);
-
-		if (urb->setup_packet != NULL)
-			kfree(urb->setup_packet);
-
-		usb_free_urb(urb);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init usb_stub_init(void)
-{
-	int ret;
-
-	stub_priv_cache = kmem_cache_create("stub_priv", sizeof(struct stub_priv),
-			0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!stub_priv_cache) {
-		uerr("create stub_priv_cache\n");
-		return -ENOMEM;
-	}
-
-	ret = usb_register(&stub_driver);
-	if (ret) {
-		uerr("usb_register failed %d\n", ret);
-		return ret;
-	}
-
-
-	info(DRIVER_DESC "" DRIVER_VERSION);
-
-	memset(busid_table, 0, sizeof(busid_table));
-
-	driver_create_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	return ret;
-}
-
-static void __exit usb_stub_exit(void)
-{
-	int ret;
-
-	udbg("enter\n");
-
-	driver_remove_file(&stub_driver.driver, &driver_attr_match_busid);
-
-	/*
-	 * deregister() calls stub_disconnect() for all devices. Device
-	 * specific data is cleared in stub_disconnect().
-	 */
-	usb_deregister(&stub_driver);
-
-	ret = kmem_cache_destroy(stub_priv_cache);
-	if (ret != 0) {
-		uerr("memory leak of stub_priv, %d\n", ret);
-	}
-
-	udbg("bye\n");
-}
-
-
-
-
-module_init (usb_stub_init);
-module_exit (usb_stub_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff -Naur usbip-0.1.4/drivers/2.6.18/stub_rx.c trunk/drivers/2.6.18/stub_rx.c
--- usbip-0.1.4/drivers/2.6.18/stub_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/stub_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,442 +0,0 @@
-/*
- * $Id: stub_rx.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static int is_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	 return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
-		 (req->bRequestType == USB_RECIP_ENDPOINT) &&
-		 (req->wValue == USB_ENDPOINT_HALT);
-}
-
-static int is_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_INTERFACE) &&
-		   (req->bRequestType == USB_RECIP_INTERFACE);
-}
-
-static int is_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
-		   (req->bRequestType == USB_RECIP_DEVICE);
-}
-
-static int tweak_clear_halt_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	int target_endp;
-	int target_dir;
-	int target_pipe;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-
-	/*
-	 * The stalled endpoint is specified in the wIndex value. The endpoint
-	 * of the urb is the target of this clear_halt request (i.e. control
-	 * endpoint).
-	 */
-	target_endp = le16_to_cpu(req->wIndex) & 0x000f;
-
-	/* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
-	target_dir = le16_to_cpu(req->wIndex) & 0x0080;
-
-	if (target_dir)
-		target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
-	else
-		target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
-
-	ret = usb_clear_halt(urb->dev, target_pipe);
-	if (ret < 0)
-		uinfo("clear_halt error: devnum %d endp %d, %d\n",
-				urb->dev->devnum, target_endp, ret);
-	else
-		uinfo("clear_halt done: devnum %d endp %d\n",
-				urb->dev->devnum, target_endp);
-
-	return ret;
-}
-
-static int tweak_set_interface_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 alternate;
-	__u16 interface;
-	int ret;
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	alternate = le16_to_cpu(req->wValue);
-	interface = le16_to_cpu(req->wIndex);
-
-	dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
-
-	ret = usb_set_interface(urb->dev, interface, alternate);
-	if (ret < 0)
-		uinfo("set_interface error: inf %u alt %u, %d\n",
-				interface, alternate, ret);
-	else
-		uinfo("set_interface done: inf %u alt %u\n", interface, alternate);
-
-	return ret;
-}
-
-static int tweak_set_configuration_cmd(struct urb *urb)
-{
-	struct usb_ctrlrequest *req;
-	__u16 config;
-
-	info("set_configuration is not fully supported yet\n");
-
-	req = (struct usb_ctrlrequest *) urb->setup_packet;
-	config = le16_to_cpu(req->wValue);
-
-	uinfo("set_configuration: devnum %d %d\n", urb->dev->devnum, config);
-
-#if 0
-	return usb_set_configuration(urb->dev, config);
-#endif
-	return 0;
-}
-
-/*
- * clear_halt, set_interface, and set_configuration require special tricks.
- * TODO: set_configuration. but I have never seen a multi-config device.
- */
-static void tweak_special_requests(struct urb *urb)
-{
-	if (!urb || !urb->setup_packet)
-		return;
-
-	if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
-		return;
-
-	if (is_clear_halt_cmd(urb))
-		/* treak clear_halt */
-		 tweak_clear_halt_cmd(urb);
-
-	else if (is_set_interface_cmd(urb))
-		/* tweak set_interface */
-		tweak_set_interface_cmd(urb);
-
-	else if (is_set_configuration_cmd(urb))
-		/* tweak set_configuration */
-		tweak_set_configuration_cmd(urb);
-
-	else
-		dbg_stub_rx("no need to tweak\n");
-}
-
-/*
- * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
- * By unlinking the urb asynchronously, stub_rx can continuously
- * process coming urbs.  Even if the urb is unlinked, its completion
- * handler will be called and stub_tx will send a return pdu.
- *
- * See also comments about unlinking strategy in vhci_hcd.c.
- */
-static int stub_recv_cmd_unlink(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct list_head *listhead = &sdev->priv_init;
-	struct list_head *ptr;
-	unsigned long flags;
-
-	struct stub_priv *priv;
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
-		priv = list_entry(ptr, struct stub_priv, list);
-		if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
-			int ret;
-
-			uinfo("unlink urb %p\n", priv->urb);
-
-			/*
-			 * This matched urb is not completed yet (i.e. be in
-			 * flight in usb hcd hardware/driver). Now we are
-			 * cancelling it. The unlinking flag means that we are
-			 * now not going to return the normal result pdu of a
-			 * submittion request, but going to return a result pdu
-			 * of the unlink request.
-			 */
-			priv->unlinking = 1;
-
-			/*
-			 * In the case that unlinking flag is on, prev->seqnum
-			 * is changed from the seqnum of the cancelling urb to
-			 * the seqnum of the unlink request. This will be used
-			 * to make the result pdu of the unlink request.
-			 */
-			priv->seqnum = pdu->base.seqnum;
-
-			spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-			/*
-			 * usb_unlink_urb() is now out of spinlocking to avoid
-			 * spinlock recursion since stub_complete() is
-			 * sometimes called in this context but not in the
-			 * interrupt context.  If stub_complete() is executed
-			 * before we call usb_unlink_urb(), usb_unlink_urb()
-			 * will return an error value. In this case, stub_tx
-			 * will return the result pdu of this unlink request
-			 * though submission is completed and actual unlinking
-			 * is not executed. OK?
-			 */
-			ret = usb_unlink_urb(priv->urb);
-			if (ret != -EINPROGRESS)
-				uerr("faild to unlink a urb %p, ret %d\n", priv->urb, ret);
-
-			return 0;
-		}
-	}
-
-	dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
-
-	/*
-	 * The urb of the unlink target is not found in priv_init queue. It was
-	 * already completed and its results is/was going to be sent by a
-	 * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
-	 * return the completeness of this unlink request to vhci_hcd.
-	 */
-	stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-
-	return 0;
-}
-
-static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &sdev->ud;
-
-	int bus = interface_to_busnum(sdev->interface);
-	int dev = interface_to_devnum(sdev->interface);
-
-	if (pdu->base.busnum == bus && pdu->base.devnum == dev) {
-		spin_lock(&ud->lock);
-		if (ud->status == SDEV_ST_USED) {
-			/* A request is valid. */
-			spin_unlock(&ud->lock);
-			return 1;
-		}
-		spin_unlock(&ud->lock);
-	}
-
-	return 0;
-}
-
-static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
-		struct usbip_header *pdu)
-{
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
-	if (!priv) {
-		uerr("alloc stub_priv\n");
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return NULL;
-	}
-
-	memset(priv, 0, sizeof(struct stub_priv));
-
-	priv->seqnum = pdu->base.seqnum;
-	priv->sdev = sdev;
-
-	/*
-	 * After a stub_priv is linked to a list_head,
-	 * our error handler can free allocated data.
-	 */
-	list_add_tail(&priv->list, &sdev->priv_init);
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return priv;
-}
-
-static void stub_recv_cmd_submit(struct stub_device *sdev, struct usbip_header *pdu)
-{
-	int ret;
-	struct stub_priv *priv;
-	struct usbip_device *ud = &sdev->ud;
-
-
-	priv = stub_priv_alloc(sdev, pdu);
-	if (!priv)
-		return;
-
-	/* setup a urb */
-	if (usb_pipeisoc(pdu->base.pipe))
-		priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, GFP_KERNEL);
-	else
-		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
-
-	if (!priv->urb) {
-		uerr("malloc urb\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	/* set priv->urb->transfer_buffer */
-	if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
-		priv->urb->transfer_buffer =
-			kzalloc(pdu->u.cmd_submit.transfer_buffer_length, GFP_KERNEL);
-		if (!priv->urb->transfer_buffer) {
-			uerr("malloc x_buff\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-			return;
-		}
-	}
-
-	/* set priv->urb->setup_packet */
-	priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
-	if (!priv->urb->setup_packet) {
-		uerr("allocate setup_packet\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-	memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
-
-	/* set other members from the base header of pdu */
-	priv->urb->context                = (void *) priv;
-	priv->urb->dev                    = interface_to_usbdev(sdev->interface);
-	priv->urb->pipe                   = pdu->base.pipe;
-	priv->urb->complete               = stub_complete;
-
-	usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
-
-
-	if (usbip_recv_xbuff(ud, priv->urb) < 0)
-		return;
-
-	if (usbip_recv_iso(ud, priv->urb) < 0)
-		return;
-
-	tweak_special_requests(priv->urb);
-
-	/* urb is now ready to submit */
-	ret = usb_submit_urb(priv->urb, GFP_KERNEL);
-
-	if (ret == 0)
-		dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
-	else {
-		uerr("submit_urb error, %d\n", ret);
-
-		/*
-		 * Pessimistic.
-		 * This connection will be discared.
-		 */
-		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
-	}
-
-	dbg_stub_rx("Leave\n");
-	return;
-}
-
-/* recv a pdu */
-static void stub_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-
-	dbg_stub_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_stub_rx)
-		usbip_dump_header(&pdu);
-
-	if (!valid_request(sdev, &pdu)) {
-		uerr("recv invalid request\n");
-		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	switch (pdu.base.command) {
-		case USBIP_CMD_UNLINK:
-			stub_recv_cmd_unlink(sdev, &pdu);
-			break;
-
-		case USBIP_CMD_SUBMIT:
-			stub_recv_cmd_submit(sdev, &pdu);
-			break;
-
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu\n");
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-			return;
-	}
-
-}
-
-void stub_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_rx("signal catched!\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		stub_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.18/stub_tx.c trunk/drivers/2.6.18/stub_tx.c
--- usbip-0.1.4/drivers/2.6.18/stub_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/stub_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,374 +0,0 @@
-/*
- * $Id: stub_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "stub.h"
-
-
-static void stub_free_priv_and_urb(struct stub_priv *priv)
-{
-	struct urb *urb = priv->urb;
-
-	if (urb->setup_packet)
-		kfree(urb->setup_packet);
-
-	if (urb->transfer_buffer)
-		kfree(urb->transfer_buffer);
-
-	list_del(&priv->list);
-	kmem_cache_free(stub_priv_cache, priv);
-
-	usb_free_urb(urb);
-}
-
-/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
-void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, __u32 status)
-{
-	struct stub_unlink *unlink;
-
-	unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
-	if (!unlink) {
-		uerr("alloc stub_unlink\n");
-		usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	unlink->seqnum = seqnum;
-	unlink->status = status;
-
-	list_add_tail(&unlink->list, &sdev->unlink_tx);
-}
-
-/**
- * stub_complete - completion handler of a usbip urb
- * @urb: pointer to the urb completed
- * @regs:
- *
- * When a urb has completed, the USB core driver calls this function mostly in
- * the interrupt context. To return the result of a urb, the completed urb is
- * linked to the pending list of returning.
- *
- */
-void stub_complete(struct urb *urb, struct pt_regs *regs)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-	struct stub_device *sdev = priv->sdev;
-	unsigned long flags;
-
-	dbg_stub_tx("complete! status %d\n", urb->status);
-
-
-	switch (urb->status) {
-		case 0:
-			/* OK */
-			break;
-		case -ENOENT:
-			uinfo("stopped by a call of usb_kill_urb()"
-					"because of cleaning up a virtual connection\n");
-			return;
-		case -ECONNRESET:
-			uinfo("unlinked by a call of usb_unlink_urb()\n");
-			break;
-		case -EPIPE:
-			uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
-			break;
-		case -ESHUTDOWN:
-			uinfo("device removed?\n");
-			break;
-		default:
-			uinfo("urb completion with non-zero status %d\n", urb->status);
-	}
-
-	/* link a urb to the queue of tx. */
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	if (priv->unlinking) {
-		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
-		stub_free_priv_and_urb(priv);
-	} else
-		list_move_tail(&priv->list, &sdev->priv_tx);
-
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	/* wake up tx_thread */
-	wake_up(&sdev->tx_waitq);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* fill PDU */
-
-static inline void setup_base_pdu(struct usbip_header_basic *base,
-		__u32 command, __u32 seqnum)
-{
-	base->command = command;
-	base->busnum  = 0;
-	base->devnum  = 0;
-	base->seqnum  = seqnum;
-	base->pipe    = 0;
-}
-
-static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
-{
-	struct stub_priv *priv = (struct stub_priv *) urb->context;
-
-	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
-
-	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
-}
-
-static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
-		struct stub_unlink *unlink)
-{
-	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
-
-	rpdu->u.ret_unlink.status = unlink->status;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_SUBMIT */
-
-static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
-		list_move_tail(&priv->list, &sdev->priv_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int stub_send_ret_submit(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_priv *priv, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_ret_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->actual_length;
-			txsize += urb->actual_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
-		stub_free_priv_and_urb(priv);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* send RET_UNLINK */
-
-static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
-{
-	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_move_tail(&unlink->list, &sdev->unlink_free);
-		spin_unlock_irqrestore(&sdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-static int stub_send_ret_unlink(struct stub_device *sdev)
-{
-	unsigned long flags;
-	struct stub_unlink *unlink, *tmp;
-
-	struct msghdr msg;
-	struct kvec iov[1];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
-
-		/* 1. setup usbip_header */
-		setup_ret_unlink_pdu(&pdu_header, unlink);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_stub_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-
-	spin_lock_irqsave(&sdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock_irqrestore(&sdev->priv_lock, flags);
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void stub_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_stub_tx("signal catched\n");
-			break;
-		}
-
-		if (usbip_event_happend(ud))
-			break;
-
-		/*
-		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
-		 * looks at only priv_init queue. If the completion of a URB is
-		 * earlier than the recieve of CMD_UNLINK, priv is moved to
-		 * priv_tx queue and stub_rx does not find the target priv. In
-		 * this case, vhci_rx recieves the result of the submit request
-		 * and then recieves the result of the unlink request. The
-		 * result of the submit is given back to the usbcore as the
-		 * completion of the unlink request. The request of the
-		 * unlink is ignored. This is ok because a driver who calls
-		 * usb_unlink_urb() understands the unlink was too late by
-		 * getting the status of the given-backed URB which has the
-		 * status of usb_submit_urb().
-		 */
-		if (stub_send_ret_submit(sdev) < 0)
-			break;
-
-		if (stub_send_ret_unlink(sdev) < 0)
-			break;
-
-		wait_event_interruptible(sdev->tx_waitq,
-				(!list_empty(&sdev->priv_tx) ||
-				 !list_empty(&sdev->unlink_tx)));
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.18/usbip_common.c trunk/drivers/2.6.18/usbip_common.c
--- usbip-0.1.4/drivers/2.6.18/usbip_common.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/usbip_common.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,935 +0,0 @@
-/*
- * $Id: usbip_common.c 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/kernel.h>
-#include <linux/file.h>
-#include <linux/tcp.h>
-#include <linux/in.h>
-#include "usbip_common.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* debug routines */
-
-#ifdef CONFIG_USB_DEBUG
-unsigned long usbip_debug_flag = 0xffffffff;
-#else
-unsigned long usbip_debug_flag = 0;
-#endif
-
-static ssize_t show_flag(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%lx\n", usbip_debug_flag);
-}
-
-static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	unsigned long flag;
-
-	sscanf(buf, "%lx", &flag);
-	usbip_debug_flag = flag;
-
-	return count;
-}
-DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
-
-static void usbip_dump_buffer(char *buff, int bufflen)
-{
-	int i;
-
-	if (bufflen > 128) {
-		for (i = 0; i< 128; i++) {
-			if (i%24 == 0)
-				printk("   ");
-			printk("%02x ", (unsigned char ) buff[i]);
-			if (i%4 == 3) printk("| ");
-			if (i%24 == 23) printk("\n");
-		}
-		printk("... (%d byte)\n", bufflen);
-		return;
-	}
-
-	for (i = 0; i< bufflen; i++) {
-		if (i%24 == 0)
-			printk("   ");
-		printk("%02x ", (unsigned char ) buff[i]);
-		if (i%4 == 3)
-			printk("| ");
-		if (i%24 == 23)
-			printk("\n");
-	}
-	printk("\n");
-
-}
-
-static void usbip_dump_pipe(unsigned int p)
-{
-	unsigned char type = usb_pipetype(p);
-	unsigned char ep = usb_pipeendpoint(p);
-	unsigned char dev = usb_pipedevice(p);
-	unsigned char dir = usb_pipein(p);
-
-	printk("dev(%d) ", dev);
-	printk("ep(%d) ",  ep);
-	printk("%s ", dir ? "IN" : "OUT");
-
-	switch(type) {
-		case PIPE_ISOCHRONOUS :
-			printk("%s ", "ISO");
-			break;
-		case PIPE_INTERRUPT :
-			printk("%s ", "INT");
-			break;
-		case PIPE_CONTROL :
-			printk("%s ", "CTL");
-			break;
-		case PIPE_BULK :
-			printk("%s ", "BLK");
-			break;
-		default :
-			printk("ERR");
-	}
-
-	printk("\n");
-
-}
-
-static void usbip_dump_usb_device(struct usb_device *dev)
-{
-	int i;
-
-	if (!dev) {
-		printk("      dump usb dev: null pointer!!\n");
-		return;
-	}
-
-	printk("       devnum(%d) devpath(%s)", dev->devnum, dev->devpath);
-
-	switch(dev->speed) {
-		case USB_SPEED_HIGH :
-			printk(" SPD_HIGH");
-			break;
-		case USB_SPEED_FULL :
-			printk(" SPD_FULL");
-			break;
-		case USB_SPEED_LOW :
-			printk(" SPD_LOW");
-			break;
-		case USB_SPEED_UNKNOWN :
-			printk(" SPD_UNKNOWN");
-			break;
-		default :
-			printk(" SPD_ERROR");
-	}
-
-	printk(" tt %p, ttport %d", dev->tt, dev->ttport);
-	printk("\n");
-
-	printk("                    ");
-	for (i = 0; i < 16; i++) {
-		printk(" %2u", i);
-	}
-
-	printk("\n");
-
-	printk("       toggle0(IN) :");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[0] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-	printk("       toggle1(OUT):");
-	for (i = 0; i< 16; i++) {
-		printk(" %2u", ( dev->toggle[1] & (1 << i) ) ? 1 : 0);
-	}
-
-	printk("\n");
-
-
-	printk("       epmaxp_in   :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_in[i])
-			printk(" %2u",  dev->ep_in[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n");
-
-	printk("       epmaxp_out  :");
-	for (i = 0; i < 16; i++) {
-		if (dev->ep_out[i])
-			printk(" %2u",  dev->ep_out[i]->desc.wMaxPacketSize);
-	}
-
-	printk("\n       ");
-
-	printk("parent %p, bus %p", dev->parent, dev->bus);
-	printk("\n       ");
-
-	printk("descriptor %p, config %p, actconfig %p, rawdescriptors %p",
-			&dev->descriptor, dev->config, dev->actconfig, dev->rawdescriptors);
-	printk("\n       ");
-
-	printk("have_langid %d, string_langid %d", dev->have_langid, dev->string_langid);
-	printk("\n       ");
-
-	printk("maxchild %d, children %p", dev->maxchild, dev->children);
-
-	printk("\n");
-}
-
-static void usbip_dump_request_type(__u8 rt)
-{
-	switch(rt & USB_RECIP_MASK) {
-		case USB_RECIP_DEVICE:
-			printk("DEVICE");
-			break;
-		case USB_RECIP_INTERFACE:
-			printk("INTERF");
-			break;
-		case USB_RECIP_ENDPOINT:
-			printk("ENDPOI");
-			break;
-		case USB_RECIP_OTHER:
-			printk("OTHER ");
-			break;
-		default:
-			printk("------");
-	}
-}
-
-static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
-{
-	if (!cmd) {
-		printk("      %s : null pointer\n", __FUNCTION__);
-		return;
-	}
-
-	printk("       ");
-	printk("bRequestType(%02X) ", cmd->bRequestType);
-	printk("bRequest(%02X) " , cmd->bRequest);
-	printk("wValue(%04X) ", cmd->wValue);
-	printk("wIndex(%04X) ", cmd->wIndex);
-	printk("wLength(%04X) ", cmd->wLength);
-
-	printk("\n       ");
-
-	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk("STANDARD ");
-		switch(cmd->bRequest) {
-			case USB_REQ_GET_STATUS:
-				printk("GET_STATUS");
-				break;
-			case USB_REQ_CLEAR_FEATURE:
-				printk("CLEAR_FEAT");
-				break;
-			case USB_REQ_SET_FEATURE:
-				printk("SET_FEAT  ");
-				break;
-			case USB_REQ_SET_ADDRESS:
-				printk("SET_ADDRRS");
-				break;
-			case USB_REQ_GET_DESCRIPTOR:
-				printk("GET_DESCRI");
-				break;
-			case USB_REQ_SET_DESCRIPTOR:
-				printk("SET_DESCRI");
-				break;
-			case USB_REQ_GET_CONFIGURATION:
-				printk("GET_CONFIG");
-				break;
-			case USB_REQ_SET_CONFIGURATION:
-				printk("SET_CONFIG");
-				break;
-			case USB_REQ_GET_INTERFACE:
-				printk("GET_INTERF");
-				break;
-			case USB_REQ_SET_INTERFACE:
-				printk("SET_INTERF");
-				break;
-			case USB_REQ_SYNCH_FRAME:
-				printk("SYNC_FRAME");
-				break;
-			default:
-				printk("REQ(%02X) ", cmd->bRequest);
-		}
-
-		printk(" ");
-		usbip_dump_request_type(cmd->bRequestType);
-
-	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk("CLASS   ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk("VENDOR  ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk("RESERVED");
-
-	printk("\n");
-}
-
-void usbip_dump_urb (struct urb *purb)
-{
-	if (!purb) {
-		printk("   dump urb: null pointer!!\n");
-		return;
-	}
-
-	printk("   urb                   :%p\n", purb);
-	printk("   dev                   :%p\n", purb->dev);
-
-	usbip_dump_usb_device(purb->dev);
-
-	printk("   pipe                  :%08x ", purb->pipe);
-
-	usbip_dump_pipe(purb->pipe);
-
-	printk("   status                :%d\n", purb->status);
-	printk("   transfer_flags        :%08X\n", purb->transfer_flags);
-	printk("   transfer_buffer       :%p\n", purb->transfer_buffer);
-	printk("   transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("   actual_length         :%d\n", purb->actual_length);
-	printk("   bandwidth             :%d\n", purb->actual_length);
-	printk("   setup_packet          :%p\n", purb->setup_packet);
-
-	if (purb->setup_packet && usb_pipetype(purb->pipe) == PIPE_CONTROL)
-		usbip_dump_usb_ctrlrequest((struct usb_ctrlrequest *) purb->setup_packet);
-
-	printk("   start_frame           :%d\n", purb->start_frame);
-	printk("   number_of_packets     :%d\n", purb->number_of_packets);
-	printk("   interval              :%d\n", purb->interval);
-	printk("   error_count           :%d\n", purb->error_count);
-	printk("   context               :%p\n", purb->context);
-	printk("   complete              :%p\n", purb->complete);
-}
-
-void usbip_dump_header(struct usbip_header *pdu)
-{
-	udbg("BASE: cmd %u bus %u dev %u seq %u pipe %04x\n",
-			pdu->base.command,
-			pdu->base.busnum,
-			pdu->base.devnum,
-			pdu->base.seqnum,
-			pdu->base.pipe);
-
-	usbip_dump_pipe(pdu->base.pipe);
-
-	switch(pdu->base.command) {
-		case USBIP_CMD_SUBMIT:
-			udbg("CMD_SUBMIT: x_flags %u x_len %u bw %u sf %u #p %u iv %u\n",
-					pdu->u.cmd_submit.transfer_flags,
-					pdu->u.cmd_submit.transfer_buffer_length,
-					pdu->u.cmd_submit.bandwidth,
-					pdu->u.cmd_submit.start_frame,
-					pdu->u.cmd_submit.number_of_packets,
-					pdu->u.cmd_submit.interval);
-					break;
-		case USBIP_CMD_UNLINK:
-			udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
-			break;
-		case USBIP_RET_SUBMIT:
-			udbg("RET_SUBMIT: st %d al %u bw %u sf %d ec %d\n",
-					pdu->u.ret_submit.status,
-					pdu->u.ret_submit.actual_length,
-					pdu->u.ret_submit.bandwidth,
-					pdu->u.ret_submit.start_frame,
-					pdu->u.ret_submit.error_count);
-		case USBIP_RET_UNLINK:
-			udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
-			break;
-		default:
-			/* NOT REACHED */
-			udbg("UNKNOWN\n");
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* thread routines */
-
-int usbip_thread(void *param)
-{
-	struct usbip_task *ut = (struct usbip_task *) 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);
-}
-
-void usbip_start_threads(struct usbip_device *ud)
-{
-	/*
-	 * threads are invoked per one device (per one connection).
-	 */
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_rx, 0);
-	kernel_thread((int(*)(void *))usbip_thread, (void *)&ud->tcp_tx, 0);
-
-	/* confirm threads are starting */
-	wait_for_completion(&ud->tcp_rx.thread_done);
-	wait_for_completion(&ud->tcp_tx.thread_done);
-}
-
-void usbip_stop_threads(struct usbip_device *ud)
-{
-        /* kill threads related to this sdev, if v.c. exists */
-	if (ud->tcp_rx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
-		wait_for_completion(&ud->tcp_rx.thread_done);
-		udbg("rx_thread for ud %p has finished\n", ud);
-	}
-
-	if (ud->tcp_tx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
-		wait_for_completion(&ud->tcp_tx.thread_done);
-		udbg("tx_thread for ud %p has finished\n", ud);
-	}
-}
-
-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;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/* socket routines */
-
- /*  Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags)
-{
-	int result;
-	struct msghdr msg;
-	struct kvec iov;
-	int total = 0;
-
-	/* for blocks of if (dbg_flag_xmit) */
-	char *bp = buf;
-	int osize= size;
-
-	dbg_xmit("enter\n");
-
-	if (!sock || !buf || !size) {
-		uerr("usbip_xmit: invalid arg, sock %p buff %p size %d\n",
-				sock, buf, size);
-		return -EINVAL;
-	}
-
-
-	if (dbg_flag_xmit) {
-		if (send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: sending... , sock %p, buf %p, size %d, msg_flags %d\n",
-					sock, buf, size, msg_flags);
-			usbip_dump_buffer(buf, size);
-		}
-	}
-
-
-	do {
-		sock->sk->sk_allocation = GFP_NOIO;
-		iov.iov_base    = buf;
-		iov.iov_len     = size;
-		msg.msg_name    = NULL;
-		msg.msg_namelen = 0;
-		msg.msg_control = NULL;
-		msg.msg_controllen = 0;
-		msg.msg_namelen    = 0;
-		msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
-
-		if (send)
-			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
-		else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL);
-
-		if (result <= 0) {
-			udbg("usbip_xmit: %s sock %p buf %p size %u ret %d total %d\n",
-					send ? "send" : "receive", sock, buf, size, result, total);
-			goto err;
-		}
-
-		size -= result;
-		buf += result;
-		total += result;
-
-	} while (size > 0);
-
-
-	if (dbg_flag_xmit) {
-		if (!send) {
-			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
-			else
-				printk(KERN_DEBUG "interupt  :");
-
-			printk("usbip_xmit: receiving....\n");
-			usbip_dump_buffer(bp, osize);
-			printk("usbip_xmit: received, osize %d ret %d size %d total %d\n",
-					osize, result, size, total);
-		}
-
-		if (send) {
-			printk("usbip_xmit: send, total %d\n", total);
-		}
-	}
-
-	return total;
-
-err:
-	return result;
-}
-
-int setquickack(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-void setreuse(struct socket *socket)
-{
-	socket->sk->sk_reuse = 1;
-}
-
-struct socket *sockfd_to_socket(unsigned int sockfd)
-{
-	struct socket *socket;
-	struct file *file;
-	struct inode *inode;
-
-	file = fget(sockfd);
-	if (!file) {
-		uerr("invalid sockfd\n");
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-
-	if (!inode || !S_ISSOCK(inode->i_mode))
-		return NULL;
-
-	socket = SOCKET_I(inode);
-
-	return socket;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/* pdu routines */
-
-/* there may be more cases to tweak the flags. */
-static unsigned int tweak_transfer_flags(unsigned int flags)
-{
-
-	if (flags & URB_NO_TRANSFER_DMA_MAP)
-		/*
-		 * vhci_hcd does not provide DMA-mapped I/O. The upper
-		 * driver does not need to set this flag. The remote
-		 * usbip.ko does not still perform DMA-mapped I/O for
-		 * DMA-caplable host controllers. So, clear this flag.
-		 */
-		flags &= ~URB_NO_TRANSFER_DMA_MAP;
-
-	if (flags & URB_NO_SETUP_DMA_MAP)
-		flags &= ~URB_NO_SETUP_DMA_MAP;
-
-	return flags;
-}
-
-static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
-
-	/*
-	 * Some members are not still implemented in usbip. I hope this issue
-	 * will be discussed when usbip is ported to other operating systems.
-	 */
-	if (pack) {
-		/* vhci_tx.c */
-		spdu->transfer_flags		= tweak_transfer_flags(urb->transfer_flags);
-
-		spdu->transfer_buffer_length	= urb->transfer_buffer_length;
-		spdu->bandwidth			= urb->bandwidth;
-		spdu->start_frame		= urb->start_frame;
-		spdu->number_of_packets		= urb->number_of_packets;
-		spdu->interval			= urb->interval;
-	} else  {
-		/* stub_rx.c */
-		urb->transfer_flags         = spdu->transfer_flags;
-
-		urb->transfer_buffer_length = spdu->transfer_buffer_length;
-		urb->bandwidth              = spdu->bandwidth;
-		urb->start_frame            = spdu->start_frame;
-		urb->number_of_packets      = spdu->number_of_packets;
-		urb->interval               = spdu->interval;
-	}
-}
-
-static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, int pack)
-{
-	struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
-
-	if (pack) {
-		/* stub_tx.c */
-
-		rpdu->status		= urb->status;
-		rpdu->actual_length	= urb->actual_length;
-		rpdu->bandwidth		= urb->bandwidth;
-		rpdu->start_frame	= urb->start_frame;
-		rpdu->error_count	= urb->error_count;
-	} else {
-		/* vhci_rx.c */
-
-		urb->status		= rpdu->status;
-		urb->actual_length	= rpdu->actual_length;
-		urb->bandwidth		= rpdu->bandwidth;
-		urb->start_frame	= rpdu->start_frame;
-		urb->error_count	= rpdu->error_count;
-	}
-}
-
-
-void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack)
-{
-	switch(cmd) {
-		case USBIP_CMD_SUBMIT:
-			usbip_pack_cmd_submit(pdu, urb, pack);
-			break;
-		case USBIP_RET_SUBMIT:
-			usbip_pack_ret_submit(pdu, urb, pack);
-			break;
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-
-
-static void correct_endian_basic(struct usbip_header_basic *base, int send)
-{
-	if (send) {
-		base->command	= cpu_to_be32(base->command);
-		base->busnum	= cpu_to_be32(base->busnum);
-		base->devnum	= cpu_to_be32(base->devnum);
-		base->seqnum	= cpu_to_be32(base->seqnum);
-		base->pipe	= cpu_to_be32(base->pipe);
-	} else {
-		base->command	= be32_to_cpu(base->command);
-		base->busnum	= be32_to_cpu(base->busnum);
-		base->devnum	= be32_to_cpu(base->devnum);
-		base->seqnum	= be32_to_cpu(base->seqnum);
-		base->pipe	= be32_to_cpu(base->pipe);
-	}
-}
-
-static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, int send)
-{
-	if (send) {
-		pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
-
-		cpu_to_be32s(&pdu->transfer_buffer_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->number_of_packets);
-		cpu_to_be32s(&pdu->interval);
-	} else {
-		pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags);
-
-		be32_to_cpus(&pdu->transfer_buffer_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->number_of_packets);
-		be32_to_cpus(&pdu->interval);
-	}
-}
-
-static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, int send)
-{
-	if (send) {
-		cpu_to_be32s(&pdu->status);
-		cpu_to_be32s(&pdu->actual_length);
-		cpu_to_be32s(&pdu->bandwidth);
-		cpu_to_be32s(&pdu->start_frame);
-		cpu_to_be32s(&pdu->error_count);
-	} else {
-		be32_to_cpus(&pdu->status);
-		be32_to_cpus(&pdu->actual_length);
-		be32_to_cpus(&pdu->bandwidth);
-		be32_to_cpus(&pdu->start_frame);
-		be32_to_cpus(&pdu->error_count);
-	}
-}
-
-static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, int send)
-{
-	if (send)
-		pdu->seqnum = cpu_to_be32(pdu->seqnum);
-	else
-		pdu->seqnum = be32_to_cpu(pdu->seqnum);
-}
-
-static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, int send)
-{
-	if (send)
-		cpu_to_be32s(&pdu->status);
-	else
-		be32_to_cpus(&pdu->status);
-}
-
-void usbip_header_correct_endian(struct usbip_header *pdu, int send)
-{
-	__u32 cmd = 0;
-
-	if (send)
-		cmd = pdu->base.command;
-
-	correct_endian_basic(&pdu->base, send);
-
-	if (!send)
-		cmd = pdu->base.command;
-
-	switch (cmd) {
-		case USBIP_CMD_SUBMIT:
-			correct_endian_cmd_submit(&pdu->u.cmd_submit, send);
-			break;
-		case USBIP_RET_SUBMIT:
-			correct_endian_ret_submit(&pdu->u.ret_submit, send);
-			break;
-
-		case USBIP_CMD_UNLINK:
-			correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send);
-			break;
-		case USBIP_RET_UNLINK:
-			correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
-			break;
-
-		default:
-			/* NOTREACHED */
-			BUG();
-	}
-}
-	
-static void usbip_iso_pakcet_correct_endian(struct usbip_iso_packet_descriptor *iso, int send)
-{
-	/* does not need all members. but copy all simply. */
-	if (send) {
-		iso->offset	= cpu_to_be32(iso->offset);
-		iso->length	= cpu_to_be32(iso->length);
-		iso->status	= cpu_to_be32(iso->status);
-		iso->actual_length = cpu_to_be32(iso->actual_length);
-	} else {
-		iso->offset	= be32_to_cpu(iso->offset);
-		iso->length	= be32_to_cpu(iso->length);
-		iso->status	= be32_to_cpu(iso->status);
-		iso->actual_length = be32_to_cpu(iso->actual_length);
-	}
-}
-
-static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
-		struct usb_iso_packet_descriptor *uiso, int pack)
-{
-	if (pack) {
-		iso->offset		= uiso->offset;
-		iso->length		= uiso->length;
-		iso->status		= uiso->status;
-		iso->actual_length	= uiso->actual_length;
-	} else {
-		uiso->offset		= iso->offset;
-		uiso->length		= iso->length;
-		uiso->status		= iso->status;
-		uiso->actual_length	= iso->actual_length;
-	}
-}
-
-
-/* must free buffer */
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	ssize_t size = np * sizeof(*iso);
-	int i;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return NULL;
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
-		usbip_iso_pakcet_correct_endian(iso, 1);
-	}
-
-	*bufflen = size;
-
-	return buff;
-}
-
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
-{
-	void *buff;
-	struct usbip_iso_packet_descriptor *iso;
-	int np = urb->number_of_packets;
-	int size = np * sizeof(*iso);
-	int i;
-	int ret;
-
-	if (!usb_pipeisoc(urb->pipe))
-		return 0;
-
-	buff = kzalloc(size, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-
-	ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
-	if (ret != size) {
-		uerr("recv iso_frame_descriptor, %d\n", ret);
-		kfree(buff);
-
-		if (ud->side == USBIP_STUB)
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		else
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-
-		return -EPIPE;
-	}
-
-	for (i = 0; i < np; i++) {
-		iso = buff + (i * sizeof(*iso));
-
-		usbip_iso_pakcet_correct_endian(iso, 0);
-		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
-	}
-
-
-	kfree(buff);
-
-	return ret;
-}
-
-
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
-{
-	int ret;
-	int size;
-
-	if (ud->side == USBIP_STUB) {
-		/* stub_rx.c */
-		/* the direction of urb must be OUT. */
-		if (usb_pipein(urb->pipe))
-			return 0;
-
-		size = urb->transfer_buffer_length;
-	} else {
-		/* vhci_rx.c */
-		/* the direction of urb must be IN. */
-		if (usb_pipeout(urb->pipe))
-			return 0;
-
-		size = urb->actual_length;
-	}
-
-	/* no need to recv xbuff */
-	if (!(size > 0))
-		return 0;
-
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) urb->transfer_buffer, size, 0);
-	if (ret != size) {
-		uerr("recv xbuf, %d\n", ret);
-		if (ud->side == USBIP_STUB) {
-			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		} else {
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-			return -EPIPE;
-		}
-	}
-
-	return ret;
-}
diff -Naur usbip-0.1.4/drivers/2.6.18/usbip_common.h trunk/drivers/2.6.18/usbip_common.h
--- usbip-0.1.4/drivers/2.6.18/usbip_common.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,364 +0,0 @@
-/*
- * $Id: usbip_common.h 197 2006-10-24 10:20:25Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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.
- */
-
-#ifndef  __VHCI_COMMON_H
-#define  __VHCI_COMMON_H
-
-
-#include <linux/usb.h>
-#include <net/sock.h>
-#include <asm/byteorder.h>
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * define macros to print messages
- */
-
-/**
- * udbg - print debug messages if CONFIG_USB_DEBUG is defined
- * @fmt:
- * @args:
- */
-
-#ifdef CONFIG_USB_DEBUG
-
-#define udbg(fmt, args...)						\
-	do{								\
-		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	}while(0)
-
-#else  /* CONFIG_USB_DEBUG */
-
-#define udbg(fmt, args...)		do{ }while(0)
-
-#endif /* CONFIG_USB_DEBUG */
-
-
-enum {
-	usbip_debug_xmit	= (1 << 0),
-	usbip_debug_sysfs	= (1 << 1),
-	usbip_debug_urb		= (1 << 2),
-	usbip_debug_eh		= (1 << 3),
-
-	usbip_debug_stub_cmp	= (1 << 8),
-	usbip_debug_stub_dev	= (1 << 9),
-	usbip_debug_stub_rx	= (1 << 10),
-	usbip_debug_stub_tx	= (1 << 11),
-
-	usbip_debug_vhci_rh	= (1 << 8),
-	usbip_debug_vhci_hc	= (1 << 9),
-	usbip_debug_vhci_rx	= (1 << 10),
-	usbip_debug_vhci_tx	= (1 << 11),
-	usbip_debug_vhci_sysfs  = (1 << 12)
-};
-
-#define dbg_flag_xmit		(usbip_debug_flag & usbip_debug_xmit)
-#define dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
-#define dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
-#define dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
-#define dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
-#define dbg_flag_vhci_sysfs	(usbip_debug_flag & usbip_debug_vhci_sysfs)
-#define dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
-#define dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
-
-extern unsigned long usbip_debug_flag;
-extern struct device_attribute dev_attr_usbip_debug;
-
-#define dbg_with_flag(flag, fmt, args...)		\
-	do {						\
-		if(flag & usbip_debug_flag) 		\
-			udbg(fmt , ##args);		\
-	} while(0)
-
-#define dbg_sysfs(fmt, args...)	dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define dbg_xmit(fmt, args...)	dbg_with_flag(usbip_debug_xmit,  fmt , ##args)
-#define dbg_urb(fmt, args...)	dbg_with_flag(usbip_debug_urb,   fmt , ##args)
-#define dbg_eh(fmt, args...)	dbg_with_flag(usbip_debug_eh,   fmt , ##args)
-
-#define dbg_vhci_rh(fmt, args...) dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
-#define dbg_vhci_hc(fmt, args...) dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
-#define dbg_vhci_rx(fmt, args...) dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
-#define dbg_vhci_tx(fmt, args...) dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define dbg_vhci_sysfs(fmt, args...) dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
-
-#define dbg_stub_cmp(fmt, args...) dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define dbg_stub_rx(fmt, args...) dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define dbg_stub_tx(fmt, args...) dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
-
-
-/**
- * uerr - print error messages
- * @fmt:
- * @args:
- */
-#define uerr(fmt, args...)						\
-	do {								\
-		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	} while(0)
-
-/**
- * uinfo - print information messages
- * @fmt:
- * @args:
- */
-#define uinfo(fmt, args...)					\
-	do {							\
-		printk(KERN_INFO "usbip: " fmt , ## args);	\
-	} while(0)
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * USB/IP packet headers.
- * At now, we define 4 packet types:
- *
- *  - CMD_SUBMIT transfers a USB request. This is corresponding to usb_submit_urb().
- *  - RET_RETURN transfers a result of a USB request.
- *  - CMD_UNLINK transfers an unlink request of a pending USB request.
- *  - RET_UNLINK transfers an unlink request of a pending USB request.
- *
- * TODO:
- *
- *  - inter-operability between other OSs
- */
-
-/*
- * A basic header followed by other additional headers.
- */
-struct usbip_header_basic {
-#define USBIP_CMD_SUBMIT	0x0001
-#define USBIP_CMD_UNLINK	0x0002
-#define USBIP_RET_SUBMIT	0x0003
-#define USBIP_RET_UNLINK	0x0004
-	__u32 command;
-
-	__u32 busnum;
-	__u32 devnum;
-	__u32 seqnum; /* seaquencial number which identifies URBs */
-	__u32 pipe;
-} __attribute__ ((packed));
-
-/*
- * An additional header for a CMD_SUBMIT packet.
- */
-struct usbip_header_cmd_submit {
-	__u32 transfer_flags;
-	__s32 transfer_buffer_length;
-	__s32 bandwidth;
-	__s32 start_frame;
-	__s32 number_of_packets;
-	__s32 interval;
-	unsigned char setup[8]; /* CTRL only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a RET_SUBMIT packet.
- */
-struct usbip_header_ret_submit {
-	__s32 status;
-	__s32 actual_length; /* returned data length */
-	__s32 bandwidth;
-	__s32 start_frame; /* ISO and INT */
-	__s32 number_of_packets;  /* ISO only */
-	__s32 error_count; /* ISO only */
-}__attribute__ ((packed));
-
-/*
- * An additional header for a CMD_UNLINK packet.
- */
-struct usbip_header_cmd_unlink {
-	__u32 seqnum; /* URB's seqnum which will be unlinked */
-}__attribute__ ((packed));
-
-
-/*
- * An additional header for a RET_UNLINK packet.
- */
-struct usbip_header_ret_unlink {
-	__s32 status;
-}__attribute__ ((packed));
-
-
-/* the same as usb_iso_packet_descriptor but packed for pdu */
-struct usbip_iso_packet_descriptor {
-	__u32 offset;
-	__u32 length;            /* expected length */
-	__u32 actual_length;
-	__u32 status;
-}__attribute__ ((packed));
-
-
-/*
- * All usbip packets use a common header to keep code simple.
- */
-struct usbip_header {
-	struct usbip_header_basic base;
-
-	union {
-		struct usbip_header_cmd_submit	cmd_submit;
-		struct usbip_header_ret_submit	ret_submit;
-		struct usbip_header_cmd_unlink	cmd_unlink;
-		struct usbip_header_ret_unlink	ret_unlink;
-	} u;
-}__attribute__ ((packed));
-
-
-
-
-/*-------------------------------------------------------------------------*/
-
-
-int usbip_xmit(int , struct socket *, char *, int , int );
-int usbip_sendmsg(struct socket *, struct msghdr *, int );
-
-
-static inline int interface_to_busnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->bus->busnum;
-}
-
-static inline int interface_to_devnum(struct usb_interface *interface)
-{
-	struct usb_device *udev = interface_to_usbdev(interface);
-	return udev->devnum;
-}
-
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
-	return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-struct socket *sockfd_to_socket(unsigned int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-
-
-void usbip_dump_urb (struct urb *purb);
-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,
-};
-
-enum usbip_status {
-	/* sdev is available. */
-	SDEV_ST_AVAILABLE = 0x01,
-	/* sdev is now used. */
-	SDEV_ST_USED,
-	/* sdev is unusable because of a fatal error. */
-	SDEV_ST_ERROR,
-
-	/* vdev does not connect a remote device. */
-	VDEV_ST_NULL,
-	/* vdev is used, but the USB address is not assigned yet */
-	VDEV_ST_NOTASSIGNED,
-	VDEV_ST_USED,
-	VDEV_ST_ERROR
-};
-
-/* a common structure for stub_device and vhci_device */
-struct usbip_device{
-	enum usbip_side side;
-
-	enum usbip_status status;
-
-	/* lock for status */
-	spinlock_t lock;
-
-	struct socket *tcp_socket;
-
-	struct usbip_task tcp_rx;
-	struct usbip_task tcp_tx;
-
-	/* event handler */
-#define USBIP_EH_SHUTDOWN	(1 << 0)
-#define USBIP_EH_BYE		(1 << 1)
-#define USBIP_EH_RESET		(1 << 2)
-#define USBIP_EH_UNUSABLE	(1 << 3)
-
-#define SDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
-#define	SDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_SUBMIT		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE )
-
-#define	VDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
-#define	VDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
-
-	unsigned long event;
-	struct usbip_task eh;
-	wait_queue_head_t eh_waitq;
-
-	struct eh_ops {
-		void (*shutdown)(struct usbip_device *);
-		void (*reset)(struct usbip_device *);
-		void (*unusable)(struct usbip_device *);
-	} eh_ops;
-};
-
-
-void usbip_task_init(struct usbip_task *ut, char *, void (*loop_ops)(struct usbip_task *));
-
-void 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);
-void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
-/* some members of urb must be substituted before. */
-int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
-
-
-/* usbip_event.c */
-void usbip_start_eh(struct usbip_device *ud);
-void usbip_stop_eh(struct usbip_device *ud);
-void usbip_event_add(struct usbip_device *ud, unsigned long event);
-int usbip_event_happend(struct usbip_device *ud);
-
-
-#endif
diff -Naur usbip-0.1.4/drivers/2.6.18/usbip_event.c trunk/drivers/2.6.18/usbip_event.c
--- usbip-0.1.4/drivers/2.6.18/usbip_event.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/usbip_event.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,153 +0,0 @@
-/*
- * $Id: usbip_event.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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 void event_handler_loop(struct usbip_task *eh);
-
-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((int(*)(void *)) usbip_thread, (void *) eh, 0);
-
-	wait_for_completion(&eh->thread_done);
-}
-
-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");
-}
-
-
-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);
-}
-
-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;
-}
-
-
-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 */
-		uerr("unknown event\n");
-		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");
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.18/vhci.h trunk/drivers/2.6.18/vhci.h
--- usbip-0.1.4/drivers/2.6.18/vhci.h	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/vhci.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,143 +0,0 @@
-/*
- * $Id: vhci.h 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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/platform_device.h>
-#include HCD_HEADER
-
-
-struct vhci_device {
-	struct usb_device *udev;
-
-	/* busnum and devnum of a remote device */
-	__u32 busnum;
-	__u32 devnum;
-
-	/* speed of a remote device */
-	enum usb_device_speed speed;
-
-	/*  vhci root-hub port to which this device is attached  */
-	__u32 rhport;
-
-	struct usbip_device ud;
-
-
-	/* lock for the below link lists */
-	spinlock_t priv_lock;
-
-	/* vhci_priv is linked to one of them. */
-	struct list_head priv_tx;
-	struct list_head priv_rx;
-
-	/* vhci_unlink is linked to one of them */
-	struct list_head unlink_tx;
-	struct list_head unlink_rx;
-
-	/* vhci_tx thread sleeps for this queue */
-	wait_queue_head_t waitq_tx;
-};
-
-
-/* urb->hcpriv, use container_of() */
-struct vhci_priv {
-	unsigned long seqnum;
-	struct list_head list;
-
-	struct vhci_device *vdev;
-	struct urb *urb;
-};
-
-
-struct vhci_unlink {
-	/* seqnum of this request */
-	unsigned long seqnum;
-
-	struct list_head list;
-
-	/* seqnum of the unlink target */
-	unsigned long unlink_seqnum;
-};
-
-/*
- * The number of ports is less than 16 ?
- * USB_MAXCHILDREN is statically defined to 16 in usb.h.  Its maximum value
- * would be 31 because the event_bits[1] of struct usb_hub is defined as
- * unsigned long in hub.h
- */
-#define VHCI_NPORTS 8
-
-/* for usb_bus.hcpriv */
-struct vhci_hcd {
-	spinlock_t	lock;
-
-	u32	port_status[VHCI_NPORTS];
-
-	unsigned	resuming:1;
-	unsigned long	re_timeout;
-
-	atomic_t seqnum;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 * But, the index of this array begins from 0.
-	 */
-	struct vhci_device vdev[VHCI_NPORTS];
-
-	/* vhci_device which has not been assiged its address yet */
-	int pending_port;
-};
-
-
-extern struct vhci_hcd *the_controller;
-extern struct attribute_group dev_attr_group;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declaration */
-
-/* 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);
-
-#define hardware		(&the_controller->pdev.dev)
-
-static inline struct vhci_device *port_to_vdev(__u32 port)
-{
-	return &the_controller->vdev[port];
-}
-
-static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd)
-{
-	return (struct vhci_hcd *) (hcd->hcd_priv);
-}
-
-static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci)
-{
-	return container_of((void *) vhci, struct usb_hcd, hcd_priv);
-}
-
-static inline struct device *vhci_dev(struct vhci_hcd *vhci)
-{
-	return vhci_to_hcd(vhci)->self.controller;
-}
diff -Naur usbip-0.1.4/drivers/2.6.18/vhci_hcd.c trunk/drivers/2.6.18/vhci_hcd.c
--- usbip-0.1.4/drivers/2.6.18/vhci_hcd.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/vhci_hcd.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1174 +0,0 @@
-/*
- * $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-#define DRIVER_VERSION " $Id: vhci_hcd.c 208 2006-11-12 15:22:24Z taka-hir $ "
-#define DRIVER_AUTHOR "HIROFUCHI Takahiro <taka-hir@is.naist.jp>"
-#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
-#define DRIVER_LICENCE "GPL"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENCE);
-
-
-
-/*
- * TODO
- * 	- update root hub emulation
- * 	- move the emulation code to userland ?
- * 		poring to other operating systems
- * 		minimize kernel code
- * 	- add suspend/resume code
- * 	- clean up everything
- */
-
-
-/* See usb gadget dummy hcd */
-
-
-static int vhci_hub_status (struct usb_hcd *hcd, char *buff);
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buff, u16 wLength);
-static int vhci_urb_enqueue (struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags);
-static int vhci_urb_dequeue( struct usb_hcd *hcd, struct urb *urb);
-static int vhci_start(struct usb_hcd *vhci_hcd);
-static void vhci_stop(struct usb_hcd *hcd);
-static int vhci_get_frame_number(struct usb_hcd *hcd);
-
-static const char driver_name[] = "vhci_hcd";
-static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
-
-
-
-
-struct vhci_hcd *the_controller = NULL;
-
-
-static const char *bit_desc[] = {
-	"CONNECTION",		/*0*/
-	"ENABLE",		/*1*/
-	"SUSPEND",		/*2*/
-	"OVER_CURRENT",		/*3*/
-	"RESET",		/*4*/
-	"R5",		/*5*/
-	"R6",		/*6*/
-	"R7",		/*7*/
-	"POWER",		/*8*/
-	"LOWSPEED",		/*9*/
-	"HIGHSPEED",		/*10*/
-	"PORT_TEST",		/*11*/
-	"INDICATOR",		/*12*/
-	"R13",		/*13*/
-	"R14",		/*14*/
-	"R15",		/*15*/
-	"C_CONNECTION",		/*16*/
-	"C_ENABLE",		/*17*/
-	"C_SUSPEND",		/*18*/
-	"C_OVER_CURRENT",	/*19*/
-	"C_RESET",		/*20*/
-	"R21",		/*21*/
-	"R22",		/*22*/
-	"R23",		/*23*/
-	"R24",		/*24*/
-	"R25",		/*25*/
-	"R26",		/*26*/
-	"R27",		/*27*/
-	"R28",		/*28*/
-	"R29",		/*29*/
-	"R30",		/*30*/
-	"R31",		/*31*/
-};
-
-
-static void dump_port_status(u32 status)
-{
-	int i = 0;
-
-	printk("status %08x:", status);
-	for (i = 0; i < 32; i++) {
-		if (status & (1 << i)) {
-			printk(" %s", bit_desc[i]);
-		}
-	}
-
-	printk("\n");
-}
-
-
-
-void rh_port_connect(int rhport, enum usb_device_speed speed)
-{
-	unsigned long	flags;
-
-	dbg_vhci_rh("rh_port_connect %d\n", rhport);
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
-		| (1 << USB_PORT_FEAT_C_CONNECTION);
-
-	switch (speed) {
-		case USB_SPEED_HIGH:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-			break;
-		case USB_SPEED_LOW:
-			the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-			break;
-		default:
-			break;
-	}
-
-	//spin_lock(&the_controller->vdev[rhport].ud.lock);
-	//the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
-	//spin_unlock(&the_controller->vdev[rhport].ud.lock);
-
-	the_controller->pending_port = rhport;
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-}
-
-void rh_port_disconnect(int rhport)
-{
-	unsigned long flags;
-
-	dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-	//stop_activity (dum, driver);
-	the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
-	the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION);
-
-
-	/* not yet complete the disconnection */
-	//spin_lock(&vdev->ud.lock);
-	//vdev->ud.status = VHC_ST_DISCONNECT;
-	//spin_unlock(&vdev->ud.lock);
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-#define PORT_C_MASK \
-	((USB_PORT_STAT_C_CONNECTION \
-	  | USB_PORT_STAT_C_ENABLE \
-	  | USB_PORT_STAT_C_SUSPEND \
-	  | USB_PORT_STAT_C_OVERCURRENT \
-	  | USB_PORT_STAT_C_RESET) << 16)
-
-/*
- * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without
- * suspend/resume support. But, it is modified to provide multiple ports.
- *
- * @buf: a bitmap to show which port status has been changed.
- *  bit  0: reserved or used for another purpose?
- *  bit  1: the status of port 0 has been changed.
- *  bit  2: the status of port 1 has been changed.
- *  ...
- *  bit  7: the status of port 6 has been changed.
- *  bit  8: the status of port 7 has been changed.
- *  ...
- *  bit 15: the status of port 14 has been changed.
- *
- * So, the maximum number of ports is 31 ( port 0 to port 30) ?
- *
- * The return value is the actual transfered length in byte. If nothing has
- * been changed, return 0. In the case that the number of ports is less than or
- * equal to 6 (VHCI_NPORTS==7), return 1.
- *
- */
-static int vhci_hub_status (struct usb_hcd *hcd, char *buf)
-{
-	struct vhci_hcd	*vhci;
-	unsigned long	flags;
-	int		retval = 0;
-
-	/* the enough buffer is allocated according to USB_MAXCHILDREN */
-	unsigned long	*event_bits = (unsigned long *) buf;
-	int		rhport;
-	int		changed = 0;
-
-
-	*event_bits = 0;
-
-	vhci = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&vhci->lock, flags);
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		dbg_vhci_rh("hw accessible flag in on?\n");
-		goto done;
-	}
-
-	/* check pseudo status register for each port */
-	for(rhport = 0; rhport < VHCI_NPORTS; rhport++) {
-		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
-			/* The status of a port has been changed, */
-			dbg_vhci_rh("port %d is changed\n", rhport);
-
-			*event_bits |= 1 << ( rhport + 1);
-			changed = 1;
-		}
-	}
-
-	if (changed)
-		retval = 1 + (VHCI_NPORTS / 8);
-	else
-		retval = 0;
-
-done:
-	spin_unlock_irqrestore (&vhci->lock, flags);
-	return retval;
-}
-
-/* See hub_configure in hub.c */
-static inline void hub_descriptor(struct usb_hub_descriptor *desc)
-{
-	memset(desc, 0, sizeof(*desc));
-	desc->bDescriptorType = 0x29;
-	desc->bDescLength = 9;
-	desc->wHubCharacteristics = (__force __u16)
-		(__constant_cpu_to_le16 (0x0001));
-	desc->bNbrPorts = VHCI_NPORTS;
-	desc->bitmap [0] = 0xff;
-	desc->bitmap [1] = 0xff;
-}
-
-
-static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
-{
-	struct vhci_hcd	*dum;
-	int             retval = 0;
-	unsigned long   flags;
-	int		rhport;
-
-	u32 prev_port_status[VHCI_NPORTS];
-
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
-		return -ETIMEDOUT;
-
-	/*
-	 * NOTE:
-	 * wIndex shows the port number and begins from 1.
-	 */
-	dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex);
-	if (wIndex > VHCI_NPORTS)
-		uerr("invalid port number %d\n", wIndex);
-	rhport = ((__u8 ) (wIndex & 0x00ff)) -1;
-
-	dum = hcd_to_vhci(hcd);
-
-	spin_lock_irqsave (&dum->lock, flags);
-
-	/* store old status and compare now and old later */
-	if (dbg_flag_vhci_rh) {
-		int i = 0;
-		for (i = 0; i < VHCI_NPORTS; i++)
-			prev_port_status[i] = dum->port_status[i];
-	}
-
-	switch (typeReq) {
-		case ClearHubFeature:
-			dbg_vhci_rh(" ClearHubFeature\n");
-			break;
-		case ClearPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					if (dum->port_status[rhport] & (1 << USB_PORT_FEAT_SUSPEND)) {
-						/* 20msec signaling */
-						dum->resuming = 1;
-						dum->re_timeout = jiffies + msecs_to_jiffies(20);
-					}
-					break;
-				case USB_PORT_FEAT_POWER:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
-					dum->port_status[rhport] = 0;
-					//dum->address = 0;
-					//dum->hdev = 0;
-					dum->resuming = 0;
-					break;
-				case USB_PORT_FEAT_C_RESET:
-					dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_C_RESET\n");
-					switch (dum->vdev[rhport].speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							break;
-					}
-				default:
-					dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
-					dum->port_status[rhport] &= ~(1 << wValue);
-			}
-			break;
-		case GetHubDescriptor:
-			dbg_vhci_rh(" GetHubDescriptor\n");
-			hub_descriptor ((struct usb_hub_descriptor *) buf);
-			break;
-		case GetHubStatus:
-			dbg_vhci_rh(" GetHubStatus\n");
-			*(u32 *) buf = __constant_cpu_to_le32 (0);
-			break;
-		case GetPortStatus:
-			dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
-			if (wIndex > VHCI_NPORTS || wIndex < 1) {
-				uerr(" invalid port number %d\n", wIndex);
-				retval = -EPIPE;
-			}
-
-			/* we do no care of resume. */
-
-			/* whoever resets or resumes must GetPortStatus to
-			 * complete it!!
-			 *                                   */
-			if (dum->resuming && time_after (jiffies, dum->re_timeout)) {
-				uerr(" not yet\n");
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_SUSPEND);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_SUSPEND);
-				dum->resuming = 0;
-				dum->re_timeout = 0;
-				//if (dum->driver && dum->driver->resume) {
-				//	spin_unlock (&dum->lock);
-				//	dum->driver->resume (&dum->gadget);
-				//	spin_lock (&dum->lock);
-				//}
-			}
-
-			if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != 0
-					&& time_after (jiffies, dum->re_timeout)) {
-				dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_RESET);
-				dum->port_status[rhport] &= ~(1 << USB_PORT_FEAT_RESET);
-				dum->re_timeout = 0;
-
-				if (dum->vdev[rhport].ud.status == VDEV_ST_NOTASSIGNED) {
-					dbg_vhci_rh(" enable rhport %d (status %u)\n", rhport, dum->vdev[rhport].ud.status);
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-				}
-#if 0
-				if (dum->driver) {
-
-					dum->port_status[rhport] |= USB_PORT_STAT_ENABLE;
-					/* give it the best speed we agree on */
-					dum->gadget.speed = dum->driver->speed;
-					dum->gadget.ep0->maxpacket = 64;
-					switch (dum->gadget.speed) {
-						case USB_SPEED_HIGH:
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_HIGH_SPEED;
-							break;
-						case USB_SPEED_LOW:
-							dum->gadget.ep0->maxpacket = 8;
-							dum->port_status[rhport] |=
-								USB_PORT_STAT_LOW_SPEED;
-							break;
-						default:
-							dum->gadget.speed = USB_SPEED_FULL;
-							break;
-					}
-				}
-#endif
-
-			}
-			((u16 *) buf)[0] = cpu_to_le16 (dum->port_status[rhport]);
-			((u16 *) buf)[1] = cpu_to_le16 (dum->port_status[rhport] >> 16);
-
-			dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], ((u16 *)buf)[1] );
-			break;
-		case SetHubFeature:
-			dbg_vhci_rh(" SetHubFeature\n");
-			retval = -EPIPE;
-			break;
-		case SetPortFeature:
-			switch (wValue) {
-				case USB_PORT_FEAT_SUSPEND:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_SUSPEND\n");
-					uerr(" not yet\n");
-#if 0
-					dum->port_status[rhport] |= (1 << USB_PORT_FEAT_SUSPEND);
-					if (dum->driver->suspend) {
-						spin_unlock (&dum->lock);
-						dum->driver->suspend (&dum->gadget);
-						spin_lock (&dum->lock);
-					}
-#endif
-					break;
-				case USB_PORT_FEAT_RESET:
-					dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
-					/* if it's already running, disconnect first */
-					if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
-						dum->port_status[rhport] &= ~(USB_PORT_STAT_ENABLE
-								| USB_PORT_STAT_LOW_SPEED
-								| USB_PORT_STAT_HIGH_SPEED);
-#if 0
-						if (dum->driver) {
-							dev_dbg (hardware, "disconnect\n");
-							stop_activity (dum, dum->driver);
-						}
-#endif
-
-						/* FIXME test that code path! */
-					}
-					/* 50msec reset signaling */
-					dum->re_timeout = jiffies + msecs_to_jiffies(50);
-
-					/* FALLTHROUGH */
-				default:
-					dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
-					dum->port_status[rhport] |= (1 << wValue);
-			}
-			break;
-
-		default:
-			uerr(" default: no such request\n");
-			//dev_dbg (hardware,
-			//		"hub control req%04x v%04x i%04x l%d\n",
-			//		typeReq, wValue, wIndex, wLength);
-
-			/* "protocol stall" on error */
-			retval = -EPIPE;
-	}
-
-	if (dbg_flag_vhci_rh) {
-		printk("port %d\n", rhport);
-		dump_port_status(prev_port_status[rhport]);
-		dump_port_status(dum->port_status[rhport]);
-	}
-	dbg_vhci_rh(" bye\n");
-
-	spin_unlock_irqrestore (&dum->lock, flags);
-
-	return retval;
-}
-
-
-
-/*----------------------------------------------------------------------*/
-
-static struct vhci_device *get_vdev(struct usb_device *udev)
-{
-	int i;
-
-	if (!udev)
-		return NULL;
-
-	for (i=0; i < VHCI_NPORTS; i++)
-		if (the_controller->vdev[i].udev == udev)
-			return port_to_vdev(i);
-
-	return NULL;
-}
-
-static void vhci_tx_urb(struct urb *urb)
-{
-	struct vhci_device *vdev = get_vdev(urb->dev);
-	struct vhci_priv *priv;
-	unsigned long flag;
-
-	if (!vdev)
-		BUG();
-
-	spin_lock_irqsave(&vdev->priv_lock, flag);
-
-	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
-	if (!priv) {
-		uerr("malloc vhci_priv\n");
-		spin_unlock_irqrestore(&vdev->priv_lock, flag);
-		usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-		return;
-	}
-
-	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
-	if (priv->seqnum == 0xffff)
-		uinfo("seqnum max\n");
-
-	priv->vdev = vdev;
-	priv->urb = urb;
-
-	urb->hcpriv = (void *) priv;
-
-
-	list_add_tail(&priv->list, &vdev->priv_tx);
-
-	wake_up(&vdev->waitq_tx);
-	spin_unlock_irqrestore(&vdev->priv_lock, flag);
-}
-
-static int vhci_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct urb *urb, gfp_t mem_flags)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags);
-
-
-
-	/* patch to usb_sg_init() is in 2.5.60 */
-	BUG_ON (!urb->transfer_buffer && urb->transfer_buffer_length);
-
-	spin_lock_irqsave (&the_controller->lock, flags);
-
-	/* check HC is active or not */
-	if (!HC_IS_RUNNING(hcd->state)) {
-		uerr("HC is not running\n");
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return  -ENODEV;
-	}
-
-	if (urb->status != -EINPROGRESS) {
-		uerr("URB already unlinked!, status %d\n", urb->status);
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return urb->status;
-	}
-
-	/*
-	 * The enumelation process is as follows;
-	 *
-	 *  1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
-	 *     to get max packet length of default pipe
-	 *
-	 *  2. Set_Address request to DevAddr(0) EndPoint(0)
-	 *
-	 */
-
-	if (usb_pipedevice(urb->pipe) == 0) {
-		__u8 type = usb_pipetype(urb->pipe);
-		struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet;
-		struct vhci_device *vdev = port_to_vdev(the_controller->pending_port);
-
-		if (type != PIPE_CONTROL || !ctrlreq ) {
-			uerr("invalid request to devnum 0\n");
-			ret = EINVAL;
-			goto no_need_xmit;
-		}
-
-		switch (ctrlreq->bRequest) {
-
-			case USB_REQ_SET_ADDRESS:
-				vdev->udev = urb->dev;
-				dbg_vhci_hc("SetAddress Request (%d) to port %d\n",
-						ctrlreq->wValue, vdev->rhport);
-
-				spin_lock(&vdev->ud.lock);
-				vdev->ud.status = VDEV_ST_USED;
-				spin_unlock(&vdev->ud.lock);
-
-				spin_lock (&urb->lock);
-				if (urb->status == -EINPROGRESS) {
-					/* This request is successfully completed. */
-					/* If not -EINPROGRESS, possibly unlinked. */
-					urb->status = 0;
-				}
-				spin_unlock (&urb->lock);
-
-				goto no_need_xmit;
-
-			case USB_REQ_GET_DESCRIPTOR:
-				if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
-					dbg_vhci_hc("Not yet?: Get_Descriptor to device 0 (get max pipe size)\n");
-
-				vdev->udev = urb->dev;
-				goto out;
-
-			default:
-				/* NOT REACHED */
-				uerr("invalid request to devnum 0 bRequest %u, wValue %u\n",
-						ctrlreq->bRequest, ctrlreq->wValue);
-				ret =  -EINVAL;
-				goto no_need_xmit;
-		}
-
-	}
-
-out:
-
-
-	vhci_tx_urb(urb);
-
-
-	spin_unlock_irqrestore (&the_controller->lock, flags);
-
-	return 0;
-
-
-no_need_xmit:
-
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-	return 0;
-}
-
-
-/*
- * vhci_rx gives back the urb after recieving the reply of the urb.  If an
- * unlink pdu is sent or not, vhci_rx recieves a normal return pdu and gives
- * back its urb. For the driver unlinking the urb, the content of the urb is
- * not important, but the calling to its completion handler is important; the
- * completion of unlinking is notified by the completion handler.
- *
- *
- * CLIENT SIDE
- *
- * - When vhci_hcd recieves RET_SUBMIT,
- *
- *	- case 1a). the urb of the pdu is not unlinking.
- *		- normal case
- *		=> just give back the urb
- *
- *	- case 1b). the urb of the pdu is unlinking.
- *		- usbip.ko will return a reply of the unlinking request.
- *		=> give back the urb now and go to case 2b).
- *
- * - When vhci_hcd recieves RET_UNLINK,
- *
- *   	- case 2a). a submit request is still pending in vhci_hcd.
- *   		- urb was really pending in usbip.ko and urb_unlink_urb() was
- *   		  completed there.
- *   		=> free a pending submit request
- *   		=> notify unlink completeness by giving back the urb
- *
- *   	- case 2b). a submit request is *not* pending in vhci_hcd.
- *   		- urb was already given back to the core driver.
- *   		=> do not give back the urb
- *
- *
- * SERVER SIDE
- *
- * - When usbip recieves CMD_UNLINK,
- *
- *	- case 3a). the urb of the unlink request is now in submission.
- *		=> do usb_unlink_urb().
- *		=> after the unlink is completed, send RET_UNLINK.
- *
- *	- case 3b). the urb of the unlink request is not in submission.
- *		- may be already completed or never be recieved
- *		=> send RET_UNLINK
- *
- */
-static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-{
-	unsigned long flags;
-	struct vhci_priv *priv;
-	struct vhci_device *vdev;
-
-	uinfo("vhci_hcd: dequeue a urb %p\n", urb);
-
-
-	spin_lock_irqsave(&the_controller->lock, flags);
-
-	priv = urb->hcpriv;
-	if (!priv) {
-		/* URB was never linked! or will be soon given back by vhci_rx. */
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return 0;
-	}
-
-	 /* send unlink request here? */
-	vdev = priv->vdev;
-
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		unsigned long flags2;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
-		list_del(&priv->list);
-		kfree(priv);
-		urb->hcpriv = NULL;
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-
-	} else {
-		/* tcp connection is alive */
-		unsigned long flags2;
-		struct vhci_unlink *unlink;
-
-		spin_lock_irqsave(&vdev->priv_lock, flags2);
-
-		/* setup CMD_UNLINK pdu */
-		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
-		if (!unlink) {
-			uerr("malloc vhci_unlink\n");
-			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-			spin_unlock_irqrestore(&the_controller->lock, flags);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
-			return -ENOMEM;
-		}
-
-		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
-		if (unlink->seqnum == 0xffff)
-			uinfo("seqnum max\n");
-
-		unlink->unlink_seqnum = priv->seqnum;
-
-		uinfo("vhci_hcd: device %p seems to be still connected\n", vdev);
-
-		/* send cmd_unlink and try to cancel the pending URB in the peer */
-		list_add_tail(&unlink->list, &vdev->unlink_tx);
-		wake_up(&vdev->waitq_tx);
-
-		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
-	}
-	
-	spin_unlock_irqrestore(&the_controller->lock, flags);
-
-	/*
-	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will recieve RET_UNLINK and giveb back the URB.
-	 * Otherwise, we give back it here.
-	 */
-	if (!vdev->ud.tcp_socket) {
-		/* tcp connection is closed */
-		uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	dbg_vhci_hc("leave\n");
-	return 0;
-}
-
-
-static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		list_del(&unlink->list);
-		kfree(unlink);
-	}
-
-	spin_unlock(&vdev->priv_lock);
-}
-
-/*
- * The important thing is that only one context begins cleanup.
- * This is why error handling and cleanup become simple.
- * We do not want to consider race condition as possible.
- */
-static void vhci_shutdown_connection(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	/* need this? see stub_dev.c */
-	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
-		ud->tcp_socket->ops->shutdown(ud->tcp_socket,
-				RCV_SHUTDOWN|SEND_SHUTDOWN);
-	}
-
-	usbip_stop_threads(&vdev->ud);
-	uinfo("stop threads\n");
-
-	/* active connection is closed */
-	if (vdev->ud.tcp_socket != NULL) {
-		sock_release(vdev->ud.tcp_socket);
-		vdev->ud.tcp_socket = NULL;
-	}
-	uinfo("release socket\n");
-
-	vhci_device_unlink_cleanup(vdev);
-
-	/*
-	 * rh_port_disconnect() is a trigger of ...
-	 *   usb_disable_device():
-	 * 	disable all the endpoints for a USB device.
-	 *   usb_disable_endpoint():
-	 * 	disable endpoints. pending urbs are unlinked(dequeued).
-	 *
-	 * NOTE: After calling rh_port_disconnect(), the USB device driver of a
-	 * deteched device should release used urbs in a cleanup function(i.e.
-	 * xxx_disconnect()). Therefore, vhci_hcd does not need to release
-	 * pushed urbs and their private data in this function.
-	 *
-	 * NOTE: vhci_dequeue() must be considered carefully. When shutdowning
-	 * a connection, vhci_shutdown_connection() expects vhci_dequeue()
-	 * gives back pushed urbs and frees their private data by request of
-	 * the cleanup function of a USB driver. When unlinking a urb with an
-	 * active connection, vhci_dequeue() does not give back the urb which
-	 * is actually given back by vhci_rx after recieving its return pdu.
-	 *
-	 */
-	rh_port_disconnect(vdev->rhport);
-
-	uinfo("disconnect device\n");
-}
-
-
-static void vhci_device_reset(struct usbip_device *ud)
-{
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	spin_lock(&ud->lock);
-
-	vdev->busnum = 0;
-	vdev->devnum = 0;
-	vdev->speed  = 0;
-
-	ud->tcp_socket = NULL;
-
-	ud->status = VDEV_ST_NULL;
-
-	spin_unlock(&ud->lock);
-}
-
-static void vhci_device_unusable(struct usbip_device* ud)
-{
-	spin_lock(&ud->lock);
-
-	ud->status = VDEV_ST_ERROR;
-
-	spin_unlock(&ud->lock);
-}
-
-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.side   = USBIP_VHCI;
-	vdev->ud.status = VDEV_ST_NULL;
-	vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
-
-	INIT_LIST_HEAD(&vdev->priv_rx);
-	INIT_LIST_HEAD(&vdev->priv_tx);
-	INIT_LIST_HEAD(&vdev->unlink_tx);
-	INIT_LIST_HEAD(&vdev->unlink_rx);
-	vdev->priv_lock = SPIN_LOCK_UNLOCKED;
-
-	init_waitqueue_head(&vdev->waitq_tx);
-
-	vdev->ud.eh_ops.shutdown = vhci_shutdown_connection;
-	vdev->ud.eh_ops.reset = vhci_device_reset;
-	vdev->ud.eh_ops.unusable= vhci_device_unusable;
-
-	usbip_start_eh(&vdev->ud);
-}
-
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_start(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport;
-
-	dbg_vhci_hc("enter vhci_start\n");
-
-
-	/* initialize private data of usb_hcd */
-
-	for(rhport=0; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-		vhci_device_init(vdev);
-		vdev->rhport = rhport;
-	}
-
-	atomic_set(&vhci->seqnum, 0);
-	spin_lock_init(&vhci->lock);
-
-
-
-	//hcd->power_budget = 0; /* no limit ? */
-	hcd->state  = HC_STATE_RUNNING;
-	//hcd->uses_new_polling = 1;
-
-
-	/* vhci_hcd is now ready to be controlled through sysfs */
-	sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	return 0;
-}
-
-static void vhci_stop(struct usb_hcd *hcd)
-{
-	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
-	int rhport = 0;
-
-	dbg_vhci_hc("stop VHCI controller\n");
-
-
-	/* 1. remove the userland interface of vhci_hcd */
-	sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
-
-	/* 2. shutdown all the ports of vhci_hcd */
-	for(rhport = 0 ; rhport < VHCI_NPORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
-
-		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
-		usbip_stop_eh(&vdev->ud);
-	}
-
-
-	uinfo("vhci_stop done\n");
-}
-
-/*----------------------------------------------------------------------*/
-
-static int vhci_get_frame_number(struct usb_hcd *hcd)
-{
-	uerr("Not yet implemented\n");
-	return 0;
-}
-
-
-#ifdef  CONFIG_PM
-
-static int vhci_bus_suspend(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-static int vhci_bus_resume(struct usb_hcd *hcd)
-{
-	dbg("%s\n", __FUNCTION__);
-	return 0;
-}
-
-#else
-
-#define vhci_bus_suspend      NULL
-#define vhci_bus_resume       NULL
-#endif
-
-
-
-static struct hc_driver vhci_hc_driver = {
-	.description	= driver_name,
-	.product_desc	= driver_desc,
-	.hcd_priv_size	= sizeof(struct vhci_hcd),
-
-	.flags		= HCD_USB2,
-
-	.start		= vhci_start,
-	.stop 		= vhci_stop,
-
-	.urb_enqueue	= vhci_urb_enqueue,
-	.urb_dequeue	= vhci_urb_dequeue,
-
-	.get_frame_number = vhci_get_frame_number,
-
-	.hub_status_data = vhci_hub_status,
-	.hub_control    = vhci_hub_control,
-	.bus_suspend	= vhci_bus_suspend,
-	.bus_resume	= vhci_bus_resume,
-};
-
-static int vhci_hcd_probe(struct platform_device *pdev)
-{
-	struct usb_hcd		*hcd;
-	int			ret;
-
-	uinfo("proving...\n");
-
-	dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
-
-
-	/* will be removed */
-	if (pdev->dev.dma_mask) {
-		info("vhci_hcd DMA not supported\n");
-		return -EINVAL;
-	}
-
-
-	/*
-	 * Allocate and initialize hcd.
-	 * Our private data is also allocated automatically.
-	 */
-	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id);
-	if (!hcd) {
-		uerr("create hcd failed\n");
-		return -ENOMEM;
-	}
-
-
-	/* this is private data for vhci_hcd */
-	the_controller = hcd_to_vhci(hcd);
-
-	/*
-	 * Finish generic HCD structure initialization and register.
-	 * Call the driver's reset() and start() routines.
-	 */
-	ret = usb_add_hcd(hcd, 0, 0);
-	if (ret != 0) {
-		uerr("usb_add_hcd failed %d\n", ret);
-		usb_put_hcd(hcd);
-		the_controller = NULL;
-		return ret;
-	}
-	
-
-	dbg_vhci_hc("bye\n");
-	return 0;
-}
-
-
-static int vhci_hcd_remove(struct platform_device *pdev)
-{
-	struct usb_hcd	*hcd;
-
-
-	hcd = platform_get_drvdata(pdev);
-	if(!hcd)
-		return 0;
-
-	/*
-	 * Disconnects the root hub,
-	 * then reverses the effects of usb_add_hcd(),
-	 * invoking the HCD's stop() methods.
-	 */
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-	the_controller = NULL;
-
-
-	return 0;
-}
-
-
-
-#ifdef CONFIG_PM
-
-/* what should happen for USB/IP under suspend/resume? */
-static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = state;
-
-	return 0;
-}
-
-static int vhci_hcd_resume(struct platform_device *pdev)
-{
-	dev_dbg(pdev->dev, "%s\n", __FUNCTION__);
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	return 0;
-}
-
-#else
-
-#define vhci_hcd_suspend	NULL
-#define vhci_hcd_resume		NULL
-
-#endif
-
-
-static struct platform_driver vhci_driver = {
-	.probe	= vhci_hcd_probe,
-	.remove	= __devexit_p(vhci_hcd_remove),
-	.suspend = vhci_hcd_suspend,
-	.resume	= vhci_hcd_resume,
-	.driver	= {
-		.name = (char *) driver_name,
-		.owner = THIS_MODULE,
-	},
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
- * We need to add this virtual device as a platform device arbitrarily:
- * 	1. platform_device_register()
- */
-static void the_pdev_release(struct device *dev)
-{
-	return;
-}
-
-static struct platform_device the_pdev = {
-	/* should be the same name as driver_name */
-	.name = (char *) driver_name,
-	.id = -1,
-	.dev = {
-		//.driver = &vhci_driver,
-		.release = the_pdev_release,
-	},
-};
-
-static int __init vhci_init(void)
-{
-	int ret;
-
-	dbg_vhci_hc("enter\n");
-	if (usb_disabled())
-		return -ENODEV;
-
-	info("driver %s, %s\n", driver_name, DRIVER_VERSION);
-
-	ret = platform_driver_register(&vhci_driver);
-	if (ret < 0)
-		goto err_driver_register;
-
-	ret = platform_device_register(&the_pdev);
-	if (ret < 0)
-		goto err_platform_device_register;
-
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-
-
-
-	/* error occurred */
-
-err_platform_device_register:
-	platform_driver_unregister(&vhci_driver);
-
-err_driver_register:
-
-	dbg_vhci_hc("bye\n");
-	return ret;
-}
-module_init(vhci_init);
-
-
-static void __exit vhci_cleanup(void)
-{
-	dbg_vhci_hc("enter\n");
-
-	platform_device_unregister(&the_pdev);
-	platform_driver_unregister(&vhci_driver);
-
-	dbg_vhci_hc("bye\n");
-}
-module_exit(vhci_cleanup);
diff -Naur usbip-0.1.4/drivers/2.6.18/vhci_rx.c trunk/drivers/2.6.18/vhci_rx.c
--- usbip-0.1.4/drivers/2.6.18/vhci_rx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/vhci_rx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,239 +0,0 @@
-/*
- * $Id: vhci_rx.c 192 2006-10-24 08:51:47Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
-{
-	struct vhci_priv *priv, *tmp;
-	struct urb *urb = NULL;
-
-
-	spin_lock(&vdev->priv_lock);
-
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
-		if (priv->seqnum == seqnum) {
-			urb = priv->urb;
-			dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", urb, priv, seqnum);
-
-
-			if (urb->status != -EINPROGRESS) {
-				 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
-					 uinfo("urb %p was unlinked %ssynchronuously.\n",
-							 urb, urb->status == -ENOENT ? "" : "a");
-				 } else {
-					 uinfo("urb %p may be in a error, status %d\n",
-							 urb, urb->status);
-				 }
-			}
-
-
-			list_del(&priv->list);
-			kfree(priv);
-			urb->hcpriv = NULL;
-
-
-			break;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-
-	return urb;
-}
-
-static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct usbip_device *ud = &vdev->ud;
-	struct urb *urb;
-
-
-	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
-
-
-	if (!urb) {
-		uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
-		uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-
-	/* unpack the pdu to a urb */
-	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
-
-
-	/* recv transfer buffer */
-	if (usbip_recv_xbuff(ud, urb) < 0)
-		return;
-
-
-	/* recv iso_packet_descriptor */
-	if (usbip_recv_iso(ud, urb) < 0)
-		return;
-
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_urb(urb);
-
-
-	dbg_vhci_rx("now giveback urb %p\n", urb);
-
-
-
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-
-
-	dbg_vhci_rx("Leave\n");
-
-	return;
-}
-
-
-static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
-		struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock(&vdev->priv_lock);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		uinfo("unlink->seqnum %lu\n", unlink->seqnum);
-		if (unlink->seqnum == pdu->base.seqnum) {
-			dbg_vhci_rx("found pending unlink, %lu\n", unlink->seqnum);
-			list_del(&unlink->list);
-
-			spin_unlock(&vdev->priv_lock);
-			return unlink;
-		}
-	}
-
-	spin_unlock(&vdev->priv_lock);
-
-	return NULL;
-}
-
-
-static void vhci_recv_ret_unlink(struct vhci_device *vdev, struct usbip_header *pdu)
-{
-	struct vhci_unlink *unlink;
-	struct urb *urb;
-	
-	usbip_dump_header(pdu);
-
-	unlink = dequeue_pending_unlink(vdev, pdu);
-	if (!unlink) {
-		uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
-		return;
-	}
-
-	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
-	if (!urb) {
-		/*
-		 * I get the result of a unlink request. But, it seems that I
-		 * already recieved the result of its submit result and gave
-		 * back the URB.
-		 */
-		uinfo("the urb (seqnum %d) was already given backed\n", pdu->base.seqnum);
-	} else {
-		dbg_vhci_rx("now giveback urb %p\n", urb);
-
-		/* If unlink is succeed, status is -ECONNRESET */
-		urb->status = pdu->u.ret_unlink.status;
-		uinfo("%d\n", urb->status);
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, NULL);
-	}
-
-	kfree(unlink);
-
-	return;
-}
-
-/* recv a pdu */
-static void vhci_rx_pdu(struct usbip_device *ud)
-{
-	int ret;
-	struct usbip_header pdu;
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-
-	dbg_vhci_rx("Enter\n");
-
-	memset(&pdu, 0, sizeof(pdu));
-
-
-	/* 1. recieve a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
-	if (ret != sizeof(pdu)) {
-		uerr("recv a header, %d\n", ret);
-		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-		return;
-	}
-
-	usbip_header_correct_endian(&pdu, 0);
-
-	if (dbg_flag_vhci_rx)
-		usbip_dump_header(&pdu);
-
-	switch(pdu.base.command) {
-		case USBIP_RET_SUBMIT:
-			vhci_recv_ret_submit(vdev, &pdu);
-			break;
-
-		case USBIP_RET_UNLINK:
-			vhci_recv_ret_unlink(vdev, &pdu);
-			break;
-		default:
-			/* NOTREACHED */
-			uerr("unknown pdu %u\n", pdu.base.command);
-			usbip_dump_header(&pdu);
-			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_rx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
-
-
-	while (1) {
-		if (signal_pending(current)) {
-			dbg_vhci_rx("signal catched!\n");
-			break;
-		}
-
-
-		if (usbip_event_happend(ud)) break;
-
-		vhci_rx_pdu(ud);
-	}
-}
-
diff -Naur usbip-0.1.4/drivers/2.6.18/vhci_sysfs.c trunk/drivers/2.6.18/vhci_sysfs.c
--- usbip-0.1.4/drivers/2.6.18/vhci_sysfs.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/vhci_sysfs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,286 +0,0 @@
-/*
- * $Id: vhci_sysfs.c 195 2006-10-24 10:11:08Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* TODO: refine locking ?*/
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to show port status */
-
-static ssize_t show_status(struct device *dev, struct device_attribute *attr,
-		char *out)
-{
-	char *s = out;
-	int i = 0;
-
-	if (!the_controller || !out)
-		BUG();
-
-	spin_lock(&the_controller->lock);
-
-	/*
-	 * output example:
-	 * prt sta bus dev socket           local_busid
-	 * 000 004 000 000         c5a7bb80 1-2.3
-	 * 001 004 000 000         d8cee980 2-3.4
-	 *
-	 * IP address can be retrieved from a socket pointer address by looking
-	 * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
-	 * port number and its peer IP address.
-	 */
-	out += sprintf(out, "prt sta spd bus dev socket           local_busid\n");
-
-	for (i=0; i < VHCI_NPORTS; i++) {
-		struct vhci_device *vdev = port_to_vdev(i);
-
-		spin_lock(&vdev->ud.lock);
-
-		out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
-
-		if (vdev->ud.status == VDEV_ST_USED) {
-			out += sprintf(out, "%03u %03u %03u ",
-					vdev->speed, vdev->busnum, vdev->devnum);
-			out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
-			out += sprintf(out, "%s", vdev->udev->dev.bus_id);
-
-		} else
-			out += sprintf(out, "000 000 000 0000000000000000 0-0");
-
-		out += sprintf(out, "\n");
-
-		spin_unlock(&vdev->ud.lock);
-	}
-
-	spin_unlock(&the_controller->lock);
-
-	return out - s ;
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to shutdown a virtual connection */
-
-static int vhci_port_disconnect(__u32 rhport)
-{
-	struct vhci_device *vdev;
-
-	dbg_vhci_sysfs("enter\n");
-
-	/* lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-	if (vdev->ud.status == VDEV_ST_NULL) {
-		uerr("not connected %d\n", vdev->ud.status);
-
-		/* unlock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		return -EINVAL;
-	}
-
-	/* unlock */
-	spin_unlock(&vdev->ud.lock);
-	spin_unlock(&the_controller->lock);
-
-	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
-
-	return 0;
-}
-
-static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count) {
-	int err;
-	__u32 rhport = 0;
-
-	sscanf(buf, "%u", &rhport);
-
-	/* check rhport */
-	if (rhport >= VHCI_NPORTS) {
-		uerr("invalid port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	err = vhci_port_disconnect(rhport);
-	if (err < 0) {
-		return -EINVAL;
-	}
-
-	dbg_vhci_sysfs("Leave\n");
-	return count;
-}
-
-static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Sysfs entry to establish a virtual connection */
-
-static int valid_args(__u32 rhport, __u32 busnum, __u32 devnum,
-		enum usb_device_speed speed)
-{
-	/* check rhport */
-	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		uerr("port %u\n", rhport);
-		return -EINVAL;
-	}
-
-	/* check busnum & devnum */
-	if ((busnum <= 0) || (busnum >= 128) || (devnum <= 0) || (devnum >= 128)) {
-		uerr("busnum %u devnum %u\n", busnum, devnum);
-		return -EINVAL;
-	}
-
-	/* check speed */
-	switch(speed) {
-		case USB_SPEED_LOW:
-		case USB_SPEED_FULL:
-		case USB_SPEED_HIGH:
-		case USB_SPEED_VARIABLE:
-			break;
-
-		default:
-			uerr("speed %d\n", speed);
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * To start a new USB/IP attachment, a userland program needs to setup a TCP
- * connection and then write its socket descriptor with remote device
- * information into this sysfs file.
- *
- * A remote device is virtually attached to the root-hub port of @rhport with
- * @speed. @busnum and @devnum are used to convert URBs between a client host
- * and a server host.
- *
- * write() returns 0 on success, else negative errno.
- */
-static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct vhci_device *vdev;
-	struct socket *socket;
-	int sockfd = 0;
-	__u32 rhport=0, busnum=0, devnum=0, speed=0;
-
-
-	/*
-	 * @rhport: port number of vhci_hcd
-	 * @sockfd: socket descriptor of an established TCP connection
-	 * @busnum: usb bus number in a remote host
-	 * @devnum: usb device number in a remote host
-	 * @speed: usb device speed in a remote host
-	 */
-	sscanf(buf, "%u %u %u %u %u", &rhport, &sockfd, &busnum, &devnum, &speed);
-
-	dbg_vhci_sysfs("rhport(%u) sockfd(%u) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-
-	/* check recieved parameters */
-	if (valid_args(rhport, busnum, devnum, speed) < 0)
-		return -EINVAL;
-
-	/* check sockfd */
-	socket = sockfd_to_socket(sockfd);
-	if (!socket)
-		return  -EINVAL;
-
-	setnodelay(socket);
-
-
-	/* now need lock until setting vdev status as used */
-
-	/* begin a lock */
-	spin_lock(&the_controller->lock);
-
-	vdev = port_to_vdev(rhport);
-
-	spin_lock(&vdev->ud.lock);
-
-	if (vdev->ud.status != VDEV_ST_NULL) {
-		/* end of the lock */
-		spin_unlock(&vdev->ud.lock);
-		spin_unlock(&the_controller->lock);
-
-		uerr("port %d already used\n", rhport);
-		return -EINVAL;
-	}
-
-	uinfo("rhport(%u) sockfd(%d) busnum(%u) devnum(%u) speed(%u)\n",
-			rhport, sockfd, busnum, devnum, speed);
-
-	vdev->busnum        = busnum;
-	vdev->devnum        = devnum;
-	vdev->speed         = speed;
-	vdev->ud.tcp_socket = socket;
-	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
-
-	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;
-}
-
-static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_status.attr,
-	&dev_attr_detach.attr,
-	&dev_attr_attach.attr,
-	&dev_attr_usbip_debug.attr,
-	NULL,
-};
-
-struct attribute_group dev_attr_group = {
-	.attrs = dev_attrs,
-};
diff -Naur usbip-0.1.4/drivers/2.6.18/vhci_tx.c trunk/drivers/2.6.18/vhci_tx.c
--- usbip-0.1.4/drivers/2.6.18/vhci_tx.c	2007-05-18 11:37:49.000000000 +0200
+++ trunk/drivers/2.6.18/vhci_tx.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,264 +0,0 @@
-/*
- * $Id: vhci_tx.c 194 2006-10-24 09:22:34Z taka-hir $
- *
- * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
- *
- *
- * 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"
-#include "vhci.h"
-
-
-/* @p: pipe whose dev number modified
- * @pdev: new devive number */
-static unsigned long tweak_pipe_devnum(__u32 p, __u8 pdev)
-{
-	__u32 oldp;
-	oldp = p;
-
-	if (pdev > 0x7f)
-		uerr("invalid devnum %u\n", pdev);
-
-	pdev &= 0x7f;    // 0XXX XXXX  confirm MSB be 0
-
-	p &= 0xffff80ff; /* clear p's devnum */
-
-	p |= (pdev << 8);
-
-	dbg_vhci_tx("return new pipe, devnum %u -> %u \n",
-		    usb_pipedevice(oldp), usb_pipedevice(p));
-	dbg_vhci_tx("           pipe %08x -> %08x\n", oldp, p);
-
-	return p;
-}
-
-static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
-{
-	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
-	struct vhci_device *vdev = priv->vdev;
-
-	dbg_vhci_tx("URB, local devnum(%u), busnum(%u) devnum(%u)\n",
-	            usb_pipedevice(urb->pipe), vdev->busnum, vdev->devnum);
-
-	pdup->base.command = USBIP_CMD_SUBMIT;
-	pdup->base.busnum  = vdev->busnum;
-	pdup->base.devnum  = vdev->devnum;
-	pdup->base.seqnum  = priv->seqnum;
-	pdup->base.pipe	   = tweak_pipe_devnum(urb->pipe, vdev->devnum);
-
-	usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
-
-	if (urb->setup_packet)
-		memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8);
-}
-
-static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_priv *priv, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) {
-		list_move_tail(&priv->list, &vdev->priv_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return priv;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-
-
-static int vhci_send_cmd_submit(struct vhci_device *vdev)
-{
-	struct vhci_priv *priv = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((priv = dequeue_from_priv_tx(vdev)) != NULL) {
-		int ret;
-		struct urb *urb = priv->urb;
-		struct usbip_header pdu_header;
-		void *iso_buffer = NULL;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup txdata urb %p\n", urb);
-
-
-		/* 1. setup usbip_header */
-		setup_cmd_submit_pdu(&pdu_header, urb);
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		/* 2. setup transfer buffer */
-		if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) {
-			iov[1].iov_base = urb->transfer_buffer;
-			iov[1].iov_len  = urb->transfer_buffer_length;
-			txsize += urb->transfer_buffer_length;
-		}
-
-		/* 3. setup iso_packet_descriptor */
-		if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-			ssize_t len = 0;
-
-			iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
-			if (!iso_buffer) {
-				usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC);
-				return -1;
-			}
-
-			iov[2].iov_base = iso_buffer;
-			iov[2].iov_len  = len;
-			txsize += len;
-		}
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			if (iso_buffer)
-				kfree(iso_buffer);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		if (iso_buffer)
-			kfree(iso_buffer);
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
-{
-	unsigned long flags;
-	struct vhci_unlink *unlink, *tmp;
-
-	spin_lock_irqsave(&vdev->priv_lock, flags);
-
-	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		list_move_tail(&unlink->list, &vdev->unlink_rx);
-		spin_unlock_irqrestore(&vdev->priv_lock, flags);
-		return unlink;
-	}
-
-	spin_unlock_irqrestore(&vdev->priv_lock, flags);
-
-	return NULL;
-}
-
-static int vhci_send_cmd_unlink(struct vhci_device *vdev)
-{
-	struct vhci_unlink *unlink = NULL;
-
-	struct msghdr msg;
-	struct kvec iov[3];
-	size_t txsize;
-
-	size_t total_size = 0;
-
-	while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) {
-		int ret;
-		struct usbip_header pdu_header;
-
-		txsize = 0;
-		memset(&pdu_header, 0, sizeof(pdu_header));
-		memset(&msg, 0, sizeof(msg));
-		memset(&iov, 0, sizeof(iov));
-
-		dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
-
-
-		/* 1. setup usbip_header */
-		pdu_header.base.command = USBIP_CMD_UNLINK;
-		pdu_header.base.busnum  = vdev->busnum;
-		pdu_header.base.devnum  = vdev->devnum;
-		pdu_header.base.seqnum  = unlink->seqnum;
-		pdu_header.base.pipe	= 0;
-		pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum;
-
-		usbip_header_correct_endian(&pdu_header, 1);
-
-		iov[0].iov_base = &pdu_header;
-		iov[0].iov_len  = sizeof(pdu_header);
-		txsize += sizeof(pdu_header);
-
-		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
-		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret, txsize);
-			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
-			return -1;
-		}
-
-
-		dbg_vhci_tx("send txdata\n");
-
-		total_size += txsize;
-	}
-
-	return total_size;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-void vhci_tx_loop(struct usbip_task *ut)
-{
-	struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
-	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
-
-	while (1) {
-		if (signal_pending(current)) {
-			uinfo("vhci_tx signal catched\n");
-			break;
-		}
-
-		if (vhci_send_cmd_submit(vdev) < 0)
-			break;
-
-		if (vhci_send_cmd_unlink(vdev) < 0)
-			break;
-
-		wait_event_interruptible(vdev->waitq_tx,
-				(!list_empty(&vdev->priv_tx) ||
-				 !list_empty(&vdev->unlink_tx)));
-
-		dbg_vhci_tx("pending urbs ?, now wake up\n");
-	}
-}
diff -Naur usbip-0.1.4/drivers/2.6.19/Makefile trunk/drivers/2.6.19/Makefile
--- usbip-0.1.4/drivers/2.6.19/Makefile	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/Makefile	2007-05-18 11:10:08.000000000 +0200
@@ -1,6 +1,6 @@
 # Makefile for the USB/IP driver
 #
-# $Id: Makefile 97 2006-03-31 16:08:40Z taka-hir $
+# $Id: Makefile 243 2007-02-06 12:50:03Z taka-hir $
 #
 # Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
 #
@@ -51,7 +51,11 @@
 
 
 default:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` modules
+	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  M=`pwd` modules
+
+check:
+	#make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE} C=1 M=`pwd` modules checkstack namespacecheck headers_check
+	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE} C=1 M=`pwd` modules
 
 .PHONY: cscope
 cscope:
@@ -59,5 +63,5 @@
 
 .PHONY: clean
 clean:
-	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  SUBDIRS=`pwd` clean
+	make -C $(KSOURCE) LANG=C KBUILD_VERBOSE=${KBUILD_VERBOSE}  M=`pwd` clean
 	rm -f *.x *~
diff -Naur usbip-0.1.4/drivers/2.6.19/stub_dev.c trunk/drivers/2.6.19/stub_dev.c
--- usbip-0.1.4/drivers/2.6.19/stub_dev.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/stub_dev.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: stub_dev.c 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: stub_dev.c 243 2007-02-06 12:50:03Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -62,7 +62,7 @@
 	.name		= "usbip",
 
 	.probe		= stub_probe,
-	.disconnect 	= stub_disconnect,
+	.disconnect	= stub_disconnect,
 
 	.id_table	= stub_table,
 };
@@ -134,9 +134,11 @@
 			return -EINVAL;
 		}
 
+#if 0
 		setnodelay(socket);
 		setkeepalive(socket);
 		setreuse(socket);
+#endif
 
 		sdev->ud.tcp_socket = socket;
 
@@ -330,7 +332,8 @@
 
 	sdev->ud.side = USBIP_STUB;
 	sdev->ud.status = SDEV_ST_AVAILABLE;
-	sdev->ud.lock = SPIN_LOCK_UNLOCKED;
+	// sdev->ud.lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sdev->ud.lock);
 	sdev->ud.tcp_socket = NULL;
 
 	INIT_LIST_HEAD(&sdev->priv_init);
@@ -338,7 +341,8 @@
 	INIT_LIST_HEAD(&sdev->priv_free);
 	INIT_LIST_HEAD(&sdev->unlink_free);
 	INIT_LIST_HEAD(&sdev->unlink_tx);
-	sdev->priv_lock = SPIN_LOCK_UNLOCKED;
+	// sdev->priv_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sdev->priv_lock);
 
 	init_waitqueue_head(&sdev->tx_waitq);
 
@@ -368,9 +372,12 @@
 
 /*
  * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e. not *an*
+ * the active interfaces. However, usbip exports *a* usb device (i.e., not *an*
  * active interface). Currently, a userland program must ensure that it
  * looks at the usbip's sysfs entries of only the first active interface.
+ *
+ * TODO: use "struct usb_device_driver" to bind a usb device.
+ * However, it seems it is not fully supported in mainline kerenel yet (2.6.19.2).
  */
 static int stub_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
diff -Naur usbip-0.1.4/drivers/2.6.19/stub.h trunk/drivers/2.6.19/stub.h
--- usbip-0.1.4/drivers/2.6.19/stub.h	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/stub.h	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: stub.h 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: stub.h 242 2007-02-06 12:00:19Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -38,9 +38,9 @@
 	 * It is allocated as stub_priv_cache and assigned to urb->context.
 	 *
 	 * stub_priv is always linked to any one of 3 lists;
-	 * 	priv_init: linked to this until the comletion of a urb.
-	 * 	priv_tx  : linked to this after the completion of a urb.
-	 * 	priv_free: linked to this after the sending of the result.
+	 *	priv_init: linked to this until the comletion of a urb.
+	 *	priv_tx  : linked to this after the completion of a urb.
+	 *	priv_free: linked to this after the sending of the result.
 	 *
 	 * Any of these list operations should be locked by priv_lock.
 	 */
@@ -74,7 +74,7 @@
 };
 
 
-extern kmem_cache_t *stub_priv_cache;
+extern struct kmem_cache *stub_priv_cache;
 
 
 /*-------------------------------------------------------------------------*/
diff -Naur usbip-0.1.4/drivers/2.6.19/stub_main.c trunk/drivers/2.6.19/stub_main.c
--- usbip-0.1.4/drivers/2.6.19/stub_main.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/stub_main.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: stub_main.c 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: stub_main.c 243 2007-02-06 12:50:03Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -25,14 +25,14 @@
 #include "stub.h"
 
 /* Version Information */
-#define DRIVER_VERSION "$Id: stub_main.c 198 2006-11-12 10:32:49Z taka-hir $"
+#define DRIVER_VERSION "$Id: stub_main.c 243 2007-02-06 12:50:03Z taka-hir $"
 #define DRIVER_AUTHOR "Takahiro Hirofuchi <taka-hir@is.naist.jp>"
 #define DRIVER_DESC "Stub Driver for USB/IP"
 
 
 
 /* stub_priv is allocated from stub_priv_cache */
-kmem_cache_t *stub_priv_cache = NULL;
+struct kmem_cache *stub_priv_cache = NULL;
 
 
 /*-------------------------------------------------------------------------*/
@@ -47,7 +47,7 @@
  */
 #define MAX_BUSID 16
 static char busid_table[MAX_BUSID][BUS_ID_SIZE];
-spinlock_t busid_table_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t busid_table_lock;
 
 
 int match_busid(char *busid)
@@ -261,6 +261,7 @@
 	info(DRIVER_DESC "" DRIVER_VERSION);
 
 	memset(busid_table, 0, sizeof(busid_table));
+	spin_lock_init(&busid_table_lock);
 
 	ret = driver_create_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid);
 	if (ret) {
diff -Naur usbip-0.1.4/drivers/2.6.19/stub_rx.c trunk/drivers/2.6.19/stub_rx.c
--- usbip-0.1.4/drivers/2.6.19/stub_rx.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/stub_rx.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: stub_rx.c 197 2006-10-24 10:20:25Z taka-hir $
+ * $Id: stub_rx.c 241 2007-02-06 10:21:58Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -67,7 +67,7 @@
 
 	/*
 	 * The stalled endpoint is specified in the wIndex value. The endpoint
-	 * of the urb is the target of this clear_halt request (i.e. control
+	 * of the urb is the target of this clear_halt request (i.e., control
 	 * endpoint).
 	 */
 	target_endp = le16_to_cpu(req->wIndex) & 0x000f;
@@ -145,7 +145,7 @@
 		return;
 
 	if (is_clear_halt_cmd(urb))
-		/* treak clear_halt */
+		/* tweak clear_halt */
 		 tweak_clear_halt_cmd(urb);
 
 	else if (is_set_interface_cmd(urb))
@@ -187,11 +187,11 @@
 			uinfo("unlink urb %p\n", priv->urb);
 
 			/*
-			 * This matched urb is not completed yet (i.e. be in
+			 * This matched urb is not completed yet (i.e., be in
 			 * flight in usb hcd hardware/driver). Now we are
 			 * cancelling it. The unlinking flag means that we are
 			 * now not going to return the normal result pdu of a
-			 * submittion request, but going to return a result pdu
+			 * submission request, but going to return a result pdu
 			 * of the unlink request.
 			 */
 			priv->unlinking = 1;
@@ -217,6 +217,10 @@
 			 * though submission is completed and actual unlinking
 			 * is not executed. OK?
 			 */
+			/* In the above case, urb->status is not -ECONNRESET,
+			 * so a driver in a client host will know the failure
+			 * of the unlink request ?
+			 */
 			ret = usb_unlink_urb(priv->urb);
 			if (ret != -EINPROGRESS)
 				uerr("faild to unlink a urb %p, ret %d\n", priv->urb, ret);
@@ -352,6 +356,7 @@
 	if (usbip_recv_iso(ud, priv->urb) < 0)
 		return;
 
+	/* no need to submit an intercepted request, but harmless? */
 	tweak_special_requests(priv->urb);
 
 	/* urb is now ready to submit */
@@ -364,7 +369,7 @@
 
 		/*
 		 * Pessimistic.
-		 * This connection will be discared.
+		 * This connection will be discarded.
 		 */
 		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
 	}
@@ -386,7 +391,7 @@
 	memset(&pdu, 0, sizeof(pdu));
 
 
-	/* 1. recieve a pdu header */
+	/* 1. receive a pdu header */
 	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
 	if (ret != sizeof(pdu)) {
 		uerr("recv a header, %d\n", ret);
@@ -429,7 +434,7 @@
 
 	while (1) {
 		if (signal_pending(current)) {
-			dbg_stub_rx("signal catched!\n");
+			dbg_stub_rx("signal caught!\n");
 			break;
 		}
 
diff -Naur usbip-0.1.4/drivers/2.6.19/stub_tx.c trunk/drivers/2.6.19/stub_tx.c
--- usbip-0.1.4/drivers/2.6.19/stub_tx.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/stub_tx.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: stub_tx.c 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: stub_tx.c 209 2006-11-15 09:39:53Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -350,10 +350,10 @@
 		/*
 		 * send_ret_submit comes earlier than send_ret_unlink.  stub_rx
 		 * looks at only priv_init queue. If the completion of a URB is
-		 * earlier than the recieve of CMD_UNLINK, priv is moved to
+		 * earlier than the receive of CMD_UNLINK, priv is moved to
 		 * priv_tx queue and stub_rx does not find the target priv. In
-		 * this case, vhci_rx recieves the result of the submit request
-		 * and then recieves the result of the unlink request. The
+		 * this case, vhci_rx receives the result of the submit request
+		 * and then receives the result of the unlink request. The
 		 * result of the submit is given back to the usbcore as the
 		 * completion of the unlink request. The request of the
 		 * unlink is ignored. This is ok because a driver who calls
diff -Naur usbip-0.1.4/drivers/2.6.19/usbip_common.c trunk/drivers/2.6.19/usbip_common.c
--- usbip-0.1.4/drivers/2.6.19/usbip_common.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/usbip_common.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: usbip_common.c 197 2006-10-24 10:20:25Z taka-hir $
+ * $Id: usbip_common.c 242 2007-02-06 12:00:19Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -523,6 +523,9 @@
 	return result;
 }
 
+
+/* now a usrland utility should set options. */
+#if 0
 int setquickack(struct socket *socket)
 {
 	mm_segment_t oldfs;
@@ -572,6 +575,7 @@
 {
 	socket->sk->sk_reuse = 1;
 }
+#endif
 
 struct socket *sockfd_to_socket(unsigned int sockfd)
 {
@@ -791,7 +795,7 @@
 			BUG();
 	}
 }
-	
+
 static void usbip_iso_pakcet_correct_endian(struct usbip_iso_packet_descriptor *iso, int send)
 {
 	/* does not need all members. but copy all simply. */
diff -Naur usbip-0.1.4/drivers/2.6.19/usbip_common.h trunk/drivers/2.6.19/usbip_common.h
--- usbip-0.1.4/drivers/2.6.19/usbip_common.h	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/usbip_common.h	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: usbip_common.h 197 2006-10-24 10:20:25Z taka-hir $
+ * $Id: usbip_common.h 242 2007-02-06 12:00:19Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -43,11 +43,11 @@
 #ifdef CONFIG_USB_DEBUG
 
 #define udbg(fmt, args...)						\
-	do{								\
+	do {								\
 		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
 			(in_interrupt() ? "interrupt" : (current)->comm),\
 			__FILE__, __LINE__, __FUNCTION__ , ##args);	\
-	}while(0)
+	} while(0)
 
 #else  /* CONFIG_USB_DEBUG */
 
@@ -88,7 +88,7 @@
 
 #define dbg_with_flag(flag, fmt, args...)		\
 	do {						\
-		if(flag & usbip_debug_flag) 		\
+		if(flag & usbip_debug_flag)		\
 			udbg(fmt , ##args);		\
 	} while(0)
 
@@ -254,14 +254,16 @@
 	return interface->cur_altsetting->desc.bInterfaceNumber;
 }
 
+#if 0
 int setnodelay(struct socket *);
 int setquickack(struct socket *);
 int setkeepalive(struct socket *socket);
 void setreuse(struct socket *);
+#endif
+
 struct socket *sockfd_to_socket(unsigned int);
 int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
 
-
 void usbip_dump_urb (struct urb *purb);
 void usbip_dump_header(struct usbip_header *pdu);
 
@@ -316,15 +318,15 @@
 #define USBIP_EH_RESET		(1 << 2)
 #define USBIP_EH_UNUSABLE	(1 << 3)
 
-#define SDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
-#define	SDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	SDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
+#define SDEV_EVENT_REMOVED		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE )
+#define	SDEV_EVENT_DOWN			( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
+#define	SDEV_EVENT_ERROR_TCP		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
 #define	SDEV_EVENT_ERROR_SUBMIT		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
 #define	SDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE )
 
-#define	VDEV_EVENT_REMOVED     		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
-#define	VDEV_EVENT_DOWN	       		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
-#define	VDEV_EVENT_ERROR_TCP   		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
+#define	VDEV_EVENT_REMOVED		( USBIP_EH_SHUTDOWN | USBIP_EH_BYE )
+#define	VDEV_EVENT_DOWN			( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
+#define	VDEV_EVENT_ERROR_TCP		( USBIP_EH_SHUTDOWN | USBIP_EH_RESET )
 #define	VDEV_EVENT_ERROR_MALLOC		( USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 
 	unsigned long event;
diff -Naur usbip-0.1.4/drivers/2.6.19/usbip_event.c trunk/drivers/2.6.19/usbip_event.c
--- usbip-0.1.4/drivers/2.6.19/usbip_event.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/usbip_event.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: usbip_event.c 208 2006-11-12 15:22:24Z taka-hir $
+ * $Id: usbip_event.c 205 2006-11-12 15:00:07Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
diff -Naur usbip-0.1.4/drivers/2.6.19/vhci_hcd.c trunk/drivers/2.6.19/vhci_hcd.c
--- usbip-0.1.4/drivers/2.6.19/vhci_hcd.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/vhci_hcd.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: vhci_hcd.c 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: vhci_hcd.c 243 2007-02-06 12:50:03Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -24,7 +24,7 @@
 #include "usbip_common.h"
 #include "vhci.h"
 
-#define DRIVER_VERSION " $Id: vhci_hcd.c 198 2006-11-12 10:32:49Z taka-hir $ "
+#define DRIVER_VERSION " $Id: vhci_hcd.c 243 2007-02-06 12:50:03Z taka-hir $ "
 #define DRIVER_AUTHOR "HIROFUCHI Takahiro <taka-hir@is.naist.jp>"
 #define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
 #define DRIVER_LICENCE "GPL"
@@ -36,12 +36,12 @@
 
 /*
  * TODO
- * 	- update root hub emulation
- * 	- move the emulation code to userland ?
- * 		poring to other operating systems
- * 		minimize kernel code
- * 	- add suspend/resume code
- * 	- clean up everything
+ *	- update root hub emulation
+ *	- move the emulation code to userland ?
+ *		poring to other operating systems
+ *		minimize kernel code
+ *	- add suspend/resume code
+ *	- clean up everything
  */
 
 
@@ -611,7 +611,7 @@
 	vhci_tx_urb(urb);
 
 
-	spin_unlock_irqrestore (&the_controller->lock, flags);
+	spin_unlock_irqrestore(&the_controller->lock, flags);
 
 	return 0;
 
@@ -626,8 +626,8 @@
 
 
 /*
- * vhci_rx gives back the urb after recieving the reply of the urb.  If an
- * unlink pdu is sent or not, vhci_rx recieves a normal return pdu and gives
+ * vhci_rx gives back the urb after receiving the reply of the urb.  If an
+ * unlink pdu is sent or not, vhci_rx receives a normal return pdu and gives
  * back its urb. For the driver unlinking the urb, the content of the urb is
  * not important, but the calling to its completion handler is important; the
  * completion of unlinking is notified by the completion handler.
@@ -635,7 +635,7 @@
  *
  * CLIENT SIDE
  *
- * - When vhci_hcd recieves RET_SUBMIT,
+ * - When vhci_hcd receives RET_SUBMIT,
  *
  *	- case 1a). the urb of the pdu is not unlinking.
  *		- normal case
@@ -645,29 +645,29 @@
  *		- usbip.ko will return a reply of the unlinking request.
  *		=> give back the urb now and go to case 2b).
  *
- * - When vhci_hcd recieves RET_UNLINK,
+ * - When vhci_hcd receives RET_UNLINK,
  *
- *   	- case 2a). a submit request is still pending in vhci_hcd.
- *   		- urb was really pending in usbip.ko and urb_unlink_urb() was
- *   		  completed there.
- *   		=> free a pending submit request
- *   		=> notify unlink completeness by giving back the urb
- *
- *   	- case 2b). a submit request is *not* pending in vhci_hcd.
- *   		- urb was already given back to the core driver.
- *   		=> do not give back the urb
+ *	- case 2a). a submit request is still pending in vhci_hcd.
+ *		- urb was really pending in usbip.ko and urb_unlink_urb() was
+ *		  completed there.
+ *		=> free a pending submit request
+ *		=> notify unlink completeness by giving back the urb
+ *
+ *	- case 2b). a submit request is *not* pending in vhci_hcd.
+ *		- urb was already given back to the core driver.
+ *		=> do not give back the urb
  *
  *
  * SERVER SIDE
  *
- * - When usbip recieves CMD_UNLINK,
+ * - When usbip receives CMD_UNLINK,
  *
  *	- case 3a). the urb of the unlink request is now in submission.
  *		=> do usb_unlink_urb().
  *		=> after the unlink is completed, send RET_UNLINK.
  *
  *	- case 3b). the urb of the unlink request is not in submission.
- *		- may be already completed or never be recieved
+ *		- may be already completed or never be received
  *		=> send RET_UNLINK
  *
  */
@@ -736,12 +736,12 @@
 
 		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
 	}
-	
+
 	spin_unlock_irqrestore(&the_controller->lock, flags);
 
 	/*
 	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will recieve RET_UNLINK and giveb back the URB.
+	 * vhci_rx will receive RET_UNLINK and giveb back the URB.
 	 * Otherwise, we give back it here.
 	 */
 	if (!vdev->ud.tcp_socket) {
@@ -805,11 +805,11 @@
 	/*
 	 * rh_port_disconnect() is a trigger of ...
 	 *   usb_disable_device():
-	 * 	disable all the endpoints for a USB device.
+	 *	disable all the endpoints for a USB device.
 	 *   usb_disable_endpoint():
-	 * 	disable endpoints. pending urbs are unlinked(dequeued).
+	 *	disable endpoints. pending urbs are unlinked(dequeued).
 	 *
-	 * NOTE: After calling rh_port_disconnect(), the USB device driver of a
+	 * NOTE: After calling rh_port_disconnect(), the USB device drivers of a
 	 * deteched device should release used urbs in a cleanup function(i.e.
 	 * xxx_disconnect()). Therefore, vhci_hcd does not need to release
 	 * pushed urbs and their private data in this function.
@@ -819,7 +819,7 @@
 	 * gives back pushed urbs and frees their private data by request of
 	 * the cleanup function of a USB driver. When unlinking a urb with an
 	 * active connection, vhci_dequeue() does not give back the urb which
-	 * is actually given back by vhci_rx after recieving its return pdu.
+	 * is actually given back by vhci_rx after receiving its return pdu.
 	 *
 	 */
 	rh_port_disconnect(vdev->rhport);
@@ -863,13 +863,15 @@
 
 	vdev->ud.side   = USBIP_VHCI;
 	vdev->ud.status = VDEV_ST_NULL;
-	vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
+	// vdev->ud.lock   = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&vdev->ud.lock);
 
 	INIT_LIST_HEAD(&vdev->priv_rx);
 	INIT_LIST_HEAD(&vdev->priv_tx);
 	INIT_LIST_HEAD(&vdev->unlink_tx);
 	INIT_LIST_HEAD(&vdev->unlink_rx);
-	vdev->priv_lock = SPIN_LOCK_UNLOCKED;
+	// vdev->priv_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&vdev->priv_lock);
 
 	init_waitqueue_head(&vdev->waitq_tx);
 
@@ -1037,7 +1039,7 @@
 		the_controller = NULL;
 		return ret;
 	}
-	
+
 
 	dbg_vhci_hc("bye\n");
 	return 0;
@@ -1113,7 +1115,7 @@
 /*
  * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
  * We need to add this virtual device as a platform device arbitrarily:
- * 	1. platform_device_register()
+ *	1. platform_device_register()
  */
 static void the_pdev_release(struct device *dev)
 {
diff -Naur usbip-0.1.4/drivers/2.6.19/vhci_rx.c trunk/drivers/2.6.19/vhci_rx.c
--- usbip-0.1.4/drivers/2.6.19/vhci_rx.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/vhci_rx.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: vhci_rx.c 198 2006-11-12 10:32:49Z taka-hir $
+ * $Id: vhci_rx.c 234 2006-12-15 04:34:04Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -143,7 +143,7 @@
 {
 	struct vhci_unlink *unlink;
 	struct urb *urb;
-	
+
 	usbip_dump_header(pdu);
 
 	unlink = dequeue_pending_unlink(vdev, pdu);
@@ -156,7 +156,7 @@
 	if (!urb) {
 		/*
 		 * I get the result of a unlink request. But, it seems that I
-		 * already recieved the result of its submit result and gave
+		 * already received the result of its submit result and gave
 		 * back the URB.
 		 */
 		uinfo("the urb (seqnum %d) was already given backed\n", pdu->base.seqnum);
@@ -187,7 +187,7 @@
 	memset(&pdu, 0, sizeof(pdu));
 
 
-	/* 1. recieve a pdu header */
+	/* 1. receive a pdu header */
 	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0);
 	if (ret != sizeof(pdu)) {
 		uerr("recv a header, %d\n", ret);
diff -Naur usbip-0.1.4/drivers/2.6.19/vhci_sysfs.c trunk/drivers/2.6.19/vhci_sysfs.c
--- usbip-0.1.4/drivers/2.6.19/vhci_sysfs.c	2007-05-18 11:10:10.000000000 +0200
+++ trunk/drivers/2.6.19/vhci_sysfs.c	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: vhci_sysfs.c 195 2006-10-24 10:11:08Z taka-hir $
+ * $Id: vhci_sysfs.c 242 2007-02-06 12:00:19Z taka-hir $
  *
  * Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
  *
@@ -213,7 +213,7 @@
 			rhport, sockfd, busnum, devnum, speed);
 
 
-	/* check recieved parameters */
+	/* check received parameters */
 	if (valid_args(rhport, busnum, devnum, speed) < 0)
 		return -EINVAL;
 
@@ -222,8 +222,9 @@
 	if (!socket)
 		return  -EINVAL;
 
+#if 0
 	setnodelay(socket);
-
+#endif
 
 	/* now need lock until setting vdev status as used */
 
diff -Naur usbip-0.1.4/NEWS trunk/NEWS
--- usbip-0.1.4/NEWS	2007-05-18 11:10:10.000000000 +0200
+++ trunk/NEWS	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,20 @@
 # vim:tw=78:ts=4:expandtab:ai:sw=4
-# $Id: NEWS 208 2006-11-12 15:22:24Z taka-hir $
+# $Id: NEWS 243 2007-02-06 12:50:03Z taka-hir $
+
+usbip-0.1.5
+    - Fix: "make dist" works.
+    - Cleanup: use autoreconf instead.
+    - Cleanup: change vhci_driver as a global value in libusbip.
+    - Cleanup: change stub_driver as a global value in libusbip.
+    - Cleanup: trim unused spaces.
+    - Add: version info in configure.ac
+    - Fix: auto detection of "glib-2.0 >= 2.6.0"
+    - Add: mailing list information in README
+    - Cleanup: use daemon(3), instead.
+    - Add: usb.ids 
+    - setsockopt in userland
+    - Add: 2.6.20 support?
+    - Fix: use spin_lock_init() instead of SPIN_...
 
 usbip-0.1.4
     - Fix: compile error & warning fix for 2.6.19
diff -Naur usbip-0.1.4/README trunk/README
--- usbip-0.1.4/README	2007-05-18 11:10:10.000000000 +0200
+++ trunk/README	2007-05-18 11:10:08.000000000 +0200
@@ -1,6 +1,6 @@
 # vim:tw=78:ts=4:expandtab:ai:sw=4
 #
-# $Id: README 124 2006-06-02 13:45:36Z taka-hir $
+# $Id: README 242 2007-02-06 12:00:19Z taka-hir $
 #
 # Copyright (C) 2003-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
 
@@ -84,8 +84,21 @@
     A.  No.
 
 
+Public Forum and Mailing List
+    They are available in the project page on sourceforge.net.
+        Forums
+            http://sourceforge.net/forum/forum.php?forum_id=418509
+        Mailing List
+            http://sourceforge.net/mail/?group_id=122798
+
+
+RSS feeds (e.g., the latest file releases)
+    http://sourceforge.net/export/rss2_project.php?group_id=122798
+
+
 Contact
     Bug reports, feature requests, and your comments are welcome.
+    Please use the above forums and the mailing list, or contact me.
 
     Nara Institute of Science and Technology
     Takahiro Hirofuchi <taka-hir@is.naist.jp>
diff -Naur usbip-0.1.4/src/autogen.sh trunk/src/autogen.sh
--- usbip-0.1.4/src/autogen.sh	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/autogen.sh	2007-05-18 11:10:08.000000000 +0200
@@ -0,0 +1,9 @@
+#!/bin/sh -x
+
+#aclocal
+#autoheader
+#libtoolize --copy --force
+#automake-1.9 -acf
+#autoconf
+
+autoreconf -i -f -v
diff -Naur usbip-0.1.4/src/cleanup trunk/src/cleanup
--- usbip-0.1.4/src/cleanup	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/cleanup	2007-05-18 11:10:08.000000000 +0200
@@ -5,6 +5,6 @@
 	make distclean
 fi
 
-FILES="configure cscope.out Makefile.in depcomp compile config.guess config.sub config.h.in~ config.log config.status libtool config.h.in autom4te.cache missing aclocal.m4 install-sh cmd/Makefile.in lib/Makefile.in"
+FILES="configure cscope.out Makefile.in depcomp compile config.guess config.sub config.h.in~ config.log config.status ltmain.sh libtool config.h.in autom4te.cache missing aclocal.m4 install-sh cmd/Makefile.in lib/Makefile.in Makefile lib/Makefile cmd/Makefile"
 
 rm -Rf $FILES
diff -Naur usbip-0.1.4/src/cmd/bind-driver.c trunk/src/cmd/bind-driver.c
--- usbip-0.1.4/src/cmd/bind-driver.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/bind-driver.c	2007-05-18 11:10:07.000000000 +0200
@@ -8,6 +8,8 @@
 	{"usbip",	required_argument,	NULL, 'u'},
 	{"other",	required_argument,	NULL, 'o'},
 	{"list",	no_argument,		NULL, 'l'},
+	{"scriptlist",	no_argument,	NULL, 's'},
+	{"autobind",	no_argument,	NULL, 'a'},
 	{"help",	no_argument,		NULL, 'h'},
 	{NULL,		0,			NULL,  0}
 };
@@ -60,7 +62,7 @@
 	snprintf(unbind_path, sizeof(unbind_path), unbind_path_format, busid);
 
 	fd = open(unbind_path, O_WRONLY);
-	if (fd < 0) 
+	if (fd < 0)
 		return -1;
 
 	ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
@@ -95,7 +97,7 @@
 	snprintf(bind_path, sizeof(bind_path), bind_path_format, driver);
 
 	fd = open(bind_path, O_WRONLY);
-	if (fd < 0) 
+	if (fd < 0)
 		return -1;
 
 	ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
@@ -139,11 +141,11 @@
 		g_message("skip unbinding of hub");
 		return -1;
 	}
- 
+
  	for (i = 0; i < ninterface; i++) {
  		char driver[PATH_MAX];
 		int ret;
- 
+
 		bzero(&driver, sizeof(driver));
 
  		getdriver(busid, configvalue, i, driver, PATH_MAX-1);
@@ -188,7 +190,7 @@
 		g_debug("read config and ninf value, removed?");
 		return -1;
 	}
- 
+
  	for (i = 0; i < ninterface; i++) {
 		int ret;
 
@@ -207,7 +209,7 @@
 		return 0;
 }
 
- 
+
 static int use_device_by_usbip(char *busid)
 {
 	int ret;
@@ -289,7 +291,7 @@
 		g_error("regcomp: %s\n", strerror(errno));
 
 	ret = regexec(&regex, busid, 0, pmatch, 0);
-	if (ret) 
+	if (ret)
 		return 0;	/* not matched */
 
 	return 1;
@@ -342,6 +344,104 @@
 	return 0;
 }
 
+static int show_devices_script(void)
+{
+	DIR *dir;
+
+	dir = opendir("/sys/bus/usb/devices/");
+	if (!dir)
+		g_error("opendir: %s", strerror(errno));
+
+	for (;;) {
+		struct dirent *dirent;
+		char *busid;
+
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		busid = dirent->d_name;
+
+		if (is_usb_device(busid)) {
+			char name[100] = {'\0'};
+			char driver[100] =  {'\0'};
+			int conf, ninf = 0;
+			int i;
+			int islocal = 0;
+
+			conf = read_bConfigurationValue(busid);
+			ninf = read_bNumInterfaces(busid);
+
+			getdevicename(busid, name, sizeof(name));
+
+			for (i = 0; i < ninf; i++) {
+				getdriver(busid, conf, i, driver, sizeof(driver));
+				
+				if (strncmp(driver, "usbhid", 6) == 0 || strncmp(driver, "usb-storage", 11) == 0) {
+					islocal = 1;
+					break;
+				}
+			}
+			
+			if (islocal == 0)
+				printf("%s|%s|%s\n", busid, driver, name);
+		}
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+
+static int auto_bind(void)
+{
+	DIR *dir;
+
+	dir = opendir("/sys/bus/usb/devices/");
+	if (!dir)
+		g_error("opendir: %s", strerror(errno));
+
+	for (;;) {
+		struct dirent *dirent;
+		char *busid;
+
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		busid = dirent->d_name;
+
+		if (is_usb_device(busid)) {
+			char name[100] = {'\0'};
+			char driver[100] =  {'\0'};
+			int conf, ninf = 0;
+			int i;
+			int islocal = 0;
+
+			conf = read_bConfigurationValue(busid);
+			ninf = read_bNumInterfaces(busid);
+
+			getdevicename(busid, name, sizeof(name));
+
+			for (i = 0; i < ninf; i++) {
+				getdriver(busid, conf, i, driver, sizeof(driver));
+				
+				if (strncmp(driver, "usbhid", 6) == 0 || strncmp(driver, "usb-storage", 11) == 0) {
+					islocal = 1;
+					break;
+				}
+			}
+			
+			if (islocal == 0)
+				use_device_by_usbip(busid);
+		}
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+
 static void show_help(void)
 {
 	printf("Usage: bind-driver [OPTION]\n");
@@ -349,25 +449,29 @@
 	printf("  --usbip busid        make a device exportable by USB/IP\n");
 	printf("  --other busid        use a device by a local driver\n");
 	printf("  --list               print usb devices and their drivers\n");
+	printf("  --scriptlist      print usb devices and their drivers. handy for scripts\n");
+	printf("  --autobind     make all devices exportable by USB/IP\n");
 }
 
 int main(int argc, char **argv)
 {
-	char *busid = NULL; 
+	char *busid = NULL;
 
 	enum {
 		cmd_unknown = 0,
 		cmd_use_by_usbip,
 		cmd_use_by_other,
 		cmd_list,
+		cmd_scriptlist,
+		cmd_autobind,
 		cmd_help
 	} cmd = cmd_unknown;
 
-	for(;;) {
+	for (;;) {
 		int c;
 		int index = 0;
 
-		c = getopt_long(argc, argv, "u:o:hl", longopts, &index);
+		c = getopt_long(argc, argv, "u:o:hlsa", longopts, &index);
 		if (c == -1)
 			break;
 
@@ -383,6 +487,12 @@
 			case 'l' :
 				cmd = cmd_list;
 				break;
+			case 's' :
+				cmd = cmd_scriptlist;
+				break;
+			case 'a' :
+				cmd = cmd_autobind;
+				break;
 			case 'h':
 			case '?':
 				cmd = cmd_help;
@@ -405,6 +515,12 @@
 		case cmd_list:
 			show_devices();
 			break;
+		case cmd_scriptlist:
+			show_devices_script();
+			break;
+		case cmd_autobind:
+			auto_bind();
+			break;
 		case cmd_help:
 		case cmd_unknown:
 			show_help();
diff -Naur usbip-0.1.4/src/cmd/Makefile.am trunk/src/cmd/Makefile.am
--- usbip-0.1.4/src/cmd/Makefile.am	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/Makefile.am	2007-05-18 11:10:07.000000000 +0200
@@ -1,12 +1,15 @@
 bin_PROGRAMS = usbip usbipd bind_driver
+
 usbip_SOURCES = vhci_attach.c usbip_network.c usbip_network.h
 usbipd_SOURCES = stub_server.c usbip_network.c usbip_network.h
 bind_driver_SOURCES = bind-driver.c utils.c utils.h
-bind_driver_CFLAGS = -Wall -g @PACKAGE_CFLAGS@
-bind_driver_LDADD = @PACKAGE_LIBS@
-AM_CPPFLAGS = -I../include -Wall -std=gnu99
-#INCLUDES = -I../include
-LDADD = ../lib/libusbip.la
+
+#bind_driver_CFLAGS = -Wall -W -Wstrict-prototypes @PACKAGE_CFLAGS@
+#bind_driver_LDADD = @PACKAGE_LIBS@
+
+#AM_CPPFLAGS = -I../include -Wall -std=gnu99
+INCLUDES = -I$(top_srcdir)/lib
+LDADD = ../lib/libusbip.la @PACKAGE_LIBS@
 EXTRA_CFLAGS = @EXTRA_CFLAGS@
-AM_CFLAGS = -Wall -W -Wstrict-prototypes $(EXTRA_CFLAGS)
+AM_CFLAGS = -Wall -W -Wstrict-prototypes -std=gnu99 $(EXTRA_CFLAGS) @PACKAGE_CFLAGS@
 
diff -Naur usbip-0.1.4/src/cmd/stub_server.c trunk/src/cmd/stub_server.c
--- usbip-0.1.4/src/cmd/stub_server.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/stub_server.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #ifdef HAVE_CONFIG_H
@@ -27,12 +27,13 @@
 #include "usbip.h"
 #include "usbip_network.h"
 
+#include <glib.h>
+
 static const char version[] = PACKAGE_STRING
 	" ($Id: stub_server.c 97 2006-03-31 16:08:40Z taka-hir $)";
 
-static struct usbip_stub_driver *StubDriver;
 
-static int send_reply_devlist(struct usbip_stub_driver *driver, int sockfd)
+static int send_reply_devlist(int sockfd)
 {
 	int ret;
 	struct usbip_exported_device *edev;
@@ -42,14 +43,14 @@
 	reply.ndev = 0;
 
 	/* how many devices are exported ? */
-	dlist_for_each_data(driver->edev_list, edev, struct usbip_exported_device) {
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
 		reply.ndev += 1;
 	}
 
 	dbg("%d devices are exported", reply.ndev);
 
 	ret = usbip_send_op_common(sockfd, OP_REP_DEVLIST,  ST_OK);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_common");
 		return ret;
 	}
@@ -57,12 +58,12 @@
 	PACK_OP_DEVLIST_REPLY(1, &reply);
 
 	ret = usbip_send(sockfd, (void *) &reply, sizeof(reply));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_devlist_reply");
 		return ret;
 	}
 
-	dlist_for_each_data(driver->edev_list, edev, struct usbip_exported_device) {
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
 		struct usb_device pdu_udev;
 
 		dump_usb_device(&edev->udev);
@@ -70,12 +71,12 @@
 		pack_usb_device(1, &pdu_udev);
 
 		ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev));
-		if(ret < 0) {
+		if (ret < 0) {
 			err("send pdu_udev");
 			return ret;
 		}
 
-		for(int i=0; i < edev->udev.bNumInterfaces; i++) {
+		for (int i=0; i < edev->udev.bNumInterfaces; i++) {
 			struct usb_interface pdu_uinf;
 
 			dump_usb_interface(&edev->uinf[i]);
@@ -83,7 +84,7 @@
 			pack_usb_interface(1, &pdu_uinf);
 
 			ret = usbip_send(sockfd, (void *) &pdu_uinf, sizeof(pdu_uinf));
-			if(ret < 0) {
+			if (ret < 0) {
 				err("send pdu_uinf");
 				return ret;
 			}
@@ -102,13 +103,13 @@
 	bzero(&req, sizeof(req));
 
 	ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv devlist request");
 		return -1;
 	}
 
-	ret = send_reply_devlist(StubDriver, sockfd);
-	if(ret < 0) {
+	ret = send_reply_devlist(sockfd);
+	if (ret < 0) {
 		err("send devlist reply");
 		return -1;
 	}
@@ -130,25 +131,28 @@
 	bzero(&reply, sizeof(reply));
 
 	ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv import request");
 		return -1;
 	}
 
 	PACK_OP_IMPORT_REQUEST(0, &req);
 
-	dlist_for_each_data(StubDriver->edev_list, edev, struct usbip_exported_device) {
-		if(!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
+		if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
 			dbg("found requested device %s", req.busid);
 			found = 1;
 			break;
 		}
 	}
 
-	if(found) {
+	if (found) {
+		/* should set TCP_NODELAY for usbip */
+		usbip_set_nodelay(sockfd);
+
 		/* export_device needs a TCP/IP socket descriptor */
-		ret = usbip_stub_export_device(StubDriver, edev, sockfd);
-		if(ret < 0) 
+		ret = usbip_stub_export_device(edev, sockfd);
+		if (ret < 0)
 			error = 1;
 	} else {
 		info("not found requested device %s", req.busid);
@@ -157,19 +161,19 @@
 
 
 	ret = usbip_send_op_common(sockfd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send import reply");
 		return -1;
 	}
 
-	if(!error) {
+	if (!error) {
 		struct usb_device pdu_udev;
 
 		memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
 		pack_usb_device(1, &pdu_udev);
 
 		ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev));
-		if(ret < 0) {
+		if (ret < 0) {
 			err("send devinfo");
 			return -1;
 		}
@@ -187,14 +191,14 @@
 
 
 	ret = usbip_recv_op_common(sockfd, &code);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_common, %d", ret);
 		return ret;
 	}
 
 
-	ret = usbip_stub_refresh_device_list(StubDriver);
-	if(ret < 0) 
+	ret = usbip_stub_refresh_device_list();
+	if (ret < 0)
 		return -1;
 
 	switch(code) {
@@ -229,10 +233,10 @@
 
 	ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf),
 			sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
-	if(ret)
+	if (ret)
 		err("getnameinfo, %s", gai_strerror(ret));
 
-	dbg("listen at [%s]:%s", hbuf, sbuf);
+	info("listen at [%s]:%s", hbuf, sbuf);
 }
 
 static struct addrinfo *my_getaddrinfo(char *host, int ai_family)
@@ -242,12 +246,13 @@
 
 	bzero(&hints, sizeof(hints));
 
+	hints.ai_family   = ai_family;
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags    = AI_PASSIVE;
 
 	ret = getaddrinfo(host, USBIP_PORT_STRING, &hints, &ai_head);
-	if (ret){
-		err("%s: %s", USBIP_PORT_STRING, gai_strerror(ret) );
+	if (ret) {
+		err("%s: %s", USBIP_PORT_STRING, gai_strerror(ret));
 		return NULL;
 	}
 
@@ -255,36 +260,36 @@
 }
 
 #define MAXSOCK 20
-static int listen_all_addrinfo(struct addrinfo *ai_head, int lsock[], int *maxfd)
+static int listen_all_addrinfo(struct addrinfo *ai_head, int lsock[])
 {
 	struct addrinfo *ai;
 	int n = 0;		/* number of sockets */
-	*maxfd = -1;		/* maximum descriptor number */
 
-	for(ai = ai_head; ai && n < MAXSOCK; ai = ai->ai_next){
+	for (ai = ai_head; ai && n < MAXSOCK; ai = ai->ai_next) {
 		int ret;
 
 		lsock[n] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-		if(lsock[n] < 0)
+		if (lsock[n] < 0)
 			continue;
 
 		usbip_set_reuseaddr(lsock[n]);
+		usbip_set_nodelay(lsock[n]);
 
-		if(lsock[n] >= FD_SETSIZE){
+		if (lsock[n] >= FD_SETSIZE) {
 			close(lsock[n]);
 			lsock[n] = -1;
 			continue;
 		}
 
 		ret = bind(lsock[n], ai->ai_addr, ai->ai_addrlen);
-		if(ret < 0){
+		if (ret < 0) {
 			close(lsock[n]);
 			lsock[n] = -1;
 			continue;
 		}
 
 		ret = listen(lsock[n], SOMAXCONN);
-		if(ret < 0){
+		if (ret < 0) {
 			close(lsock[n]);
 			lsock[n] = -1;
 			continue;
@@ -292,13 +297,11 @@
 
 		log_addrinfo(ai);
 
-		if(lsock[n] > *maxfd)
-			*maxfd = lsock[n];
-
+		/* next if succeed */
 		n++;
 	}
 
-	if(n == 0){
+	if (n == 0) {
 		err("no socket to listen to");
 		return -1;
 	}
@@ -319,10 +322,10 @@
 	fromhost(&request);
 
 	ret = hosts_access(&request);
-	if(!ret)
+	if (!ret)
 		return -1;
 
-	return 0;	
+	return 0;
 }
 #endif
 
@@ -337,21 +340,23 @@
 	bzero(&ss, sizeof(ss));
 
 	csock = accept(lsock, (struct sockaddr *) &ss, &len);
-	if(csock < 0) {
+	if (csock < 0) {
 		err("accept");
 		return -1;
 	}
 
-	ret = getnameinfo((struct sockaddr *)&ss, len,
+	ret = getnameinfo((struct sockaddr *) &ss, len,
 			host, sizeof(host), port, sizeof(port),
-			NI_NUMERICHOST | NI_NUMERICSERV);
-	if(ret)
+			(NI_NUMERICHOST | NI_NUMERICSERV));
+	if (ret)
 		err("getnameinfo, %s", gai_strerror(ret));
 
 #ifdef HAVE_LIBWRAP
 	ret = tcpd_auth(csock);
-	if(ret < 0) {
-		info("deny %s", host);
+	if (ret < 0) {
+		info("deny access from %s", host);
+		close(csock);
+		return -1;
 	}
 #endif
 
@@ -360,138 +365,123 @@
 	return csock;
 }
 
-static int loop_standalone = 1;
+
+GMainLoop *main_loop;
 
 static void signal_handler(int i)
 {
-	dbg("signal catched %d", i);
-	loop_standalone = 0;
+	dbg("signal catched, code %d", i);
+
+	if (main_loop)
+		g_main_loop_quit(main_loop);
 }
 
-static void daemon_init(void)
+static void set_signal(void)
 {
-	pid_t pid;
+	struct sigaction act;
 
-	usbip_use_stderr = 0;
-	usbip_use_syslog = 1;
+	bzero(&act, sizeof(act));
+	act.sa_handler = signal_handler;
+	sigemptyset(&act.sa_mask);
+	sigaction(SIGTERM, &act, NULL);
+	sigaction(SIGINT, &act, NULL);
+}
 
-	pid = fork();
-	if(pid < 0) {
-		err("fork");
-		exit(EXIT_FAILURE);
-	} else if(pid > 0)
-		/* bye parent */
-		exit(EXIT_SUCCESS);
 
-	setsid();
+gboolean process_comming_request(GIOChannel *gio, GIOCondition condition, gpointer data)
+{
+	int ret;
 
-	signal(SIGHUP, SIG_IGN);
+	if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+		g_error("unknown condition");
 
-	pid = fork();
-	if(pid < 0) {
-		err("fork");
-		exit(EXIT_FAILURE);
-	} else if(pid > 0)
-		/* bye parent */
-		exit(EXIT_SUCCESS);
 
-	chdir("/");
-	umask(0);
+	if (condition & G_IO_IN) {
+		int lsock;
+		int csock;
 
-	for(int i=0; i < 3; i++)
-		close(i);
+		lsock = g_io_channel_unix_get_fd(gio);
 
-}
+		csock = my_accept(lsock);
+		if (csock < 0)
+			return TRUE;
 
-static void set_signal(void)
-{
-	struct sigaction act;
+		ret = recv_pdu(csock);
+		if (ret < 0)
+			err("process recieved pdu");
 
-	bzero(&act, sizeof(act));
-	act.sa_handler = signal_handler;
-	sigemptyset(&act.sa_mask);
-	sigaction(SIGTERM, &act, NULL);
-	sigaction(SIGINT, &act, NULL);
+		close(csock);
+	}
+
+	return TRUE;
 }
 
-static void do_standalone_mode(void)
+
+static void do_standalone_mode(gboolean daemonize)
 {
 	int ret;
 	int lsock[MAXSOCK];
 	struct addrinfo *ai_head;
 	int n;
-	int maxfd;
 
-	if(!usbip_use_debug)
-		daemon_init();
+
+
+	ret = usbip_names_init(USBIDS_FILE);
+	if (ret)
+		err("open usb.ids");
+
+	ret = usbip_stub_driver_open();
+	if (ret < 0)
+		g_error("driver open failed");
+
+	if (daemonize) {
+		if (daemon(0,0) < 0)
+			g_error("daemonizing failed: %s", g_strerror(errno));
+
+		usbip_use_syslog = 1;
+	}
 
 	set_signal();
 
 	ai_head = my_getaddrinfo(NULL, PF_UNSPEC);
-	if(!ai_head)
+	if (!ai_head)
 		return;
 
-	n = listen_all_addrinfo(ai_head, lsock, &maxfd);
-	if(n <= 0) {
+	n = listen_all_addrinfo(ai_head, lsock);
+	if (n <= 0)
 		err("no socket to listen to");
-		goto err;
-	}
 
-	StubDriver = usbip_stub_driver_open();
-	if(!StubDriver) 
-		goto err_driver_open;
+	for (int i = 0; i < n; i++) {
+		GIOChannel *gio;
 
- 	ret = names_init(USBIDS_FILE);
- 	if(ret) 
- 		err("open usb.ids");
+		gio = g_io_channel_unix_new(lsock[i]);
+		g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+				process_comming_request, NULL);
+	}
 
-	info("usbipd start (%s)", version);
 
-	/* setup fd_set */
-	fd_set rfd0;
-	FD_ZERO(&rfd0);
-	for(int i = 0; i < n; i++)
-		FD_SET(lsock[i], &rfd0);
-
-	while(loop_standalone){
-		fd_set rfd = rfd0;
-		ret = select(maxfd + 1, &rfd, NULL, NULL, NULL);
-		if(ret < 0){
-			if(!(errno == EINTR))
-				err("select");
-			break;
-		}
+	info("usbipd start (%s)", version);
 
-		for(int i = 0; i < n; i++){
-			if(FD_ISSET(lsock[i], &rfd)){
-				int csock;
-
-				csock = my_accept(lsock[i]);
-				if(csock < 0)
-					continue;
-
-				ret = recv_pdu(csock);
-				if(ret < 0)
-					err("process recieved pdu");
 
-				close(csock);
-			}
-		}
-	}
+	main_loop = g_main_loop_new(FALSE, FALSE);
+	g_main_loop_run(main_loop);
 
-err:
-	usbip_stub_driver_close(StubDriver);
-err_driver_open:
 	info("shutdown");
+
 	freeaddrinfo(ai_head);
-	names_deinit();
+	usbip_names_free();
+	usbip_stub_driver_close();
+
 	return;
 }
 
 
-const char help_message[] = "\
+static const char help_message[] = "\
 Usage: usbipd [options]				\n\
-	-D, --debug				\n\
+	-D, --daemon				\n\
+		Run as a daemon process.	\n\
+						\n\
+	-d, --debug				\n\
 		Print debugging information.	\n\
 						\n\
 	-v, --version				\n\
@@ -506,14 +496,17 @@
 }
 
 static const struct option longopts[] = {
+	{"daemon",	no_argument,	NULL, 'D'},
+	{"debug",	no_argument,	NULL, 'd'},
 	{"version",	no_argument,	NULL, 'v'},
 	{"help",	no_argument,	NULL, 'h'},
-	{"debug",	no_argument,	NULL, 'D'},
 	{NULL,		0,		NULL,  0}
 };
 
 int main(int argc, char *argv[])
 {
+	gboolean daemonize = FALSE;
+
 	enum {
 		cmd_standalone_mode = 1,
 		cmd_help,
@@ -521,21 +514,23 @@
 	} cmd = cmd_standalone_mode;
 
 
-
 	usbip_use_stderr = 1;
 	usbip_use_syslog = 0;
 
 
-	while(1){
+	for (;;) {
 		int c;
 		int index = 0;
 
-		c = getopt_long(argc, argv, "vhD", longopts, &index);
+		c = getopt_long(argc, argv, "vhdD", longopts, &index);
 
-		if(c == -1)
+		if (c == -1)
 			break;
 
-		switch(c){
+		switch (c) {
+			case 'd':
+				usbip_use_debug = 1;
+				continue;
 			case 'v':
 				cmd = cmd_version;
 				break;
@@ -543,7 +538,7 @@
 				cmd = cmd_help;
 				break;
 			case 'D':
-				usbip_use_debug = 1;
+				daemonize = TRUE;
 				break;
 			case '?':
 				break;
@@ -552,9 +547,9 @@
 		}
 	}
 
-	switch(cmd) {
+	switch (cmd) {
 		case cmd_standalone_mode:
-			do_standalone_mode();
+			do_standalone_mode(daemonize);
 			break;
 		case cmd_version:
 			printf("%s\n", version);
diff -Naur usbip-0.1.4/src/cmd/usbip_network.c trunk/src/cmd/usbip_network.c
--- usbip-0.1.4/src/cmd/usbip_network.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/usbip_network.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,26 +1,66 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #include "usbip_network.h"
 
+void pack_uint32_t(int pack, uint32_t *num)
+{
+	uint32_t i;
+
+	if (pack)
+		i = htonl(*num);
+	else
+		i = ntohl(*num);
+
+	*num = i;
+}
+
+void pack_uint16_t(int pack, uint16_t *num)
+{
+	uint16_t i;
+
+	if (pack)
+		i = htons(*num);
+	else
+		i = ntohs(*num);
+
+	*num = i;
+}
+
+void pack_usb_device(int pack, struct usb_device *udev)
+{
+	pack_uint32_t(pack, &udev->busnum);
+	pack_uint32_t(pack, &udev->devnum);
+	pack_uint32_t(pack, &udev->speed );
+
+	pack_uint16_t(pack, &udev->idVendor );
+	pack_uint16_t(pack, &udev->idProduct);
+	pack_uint16_t(pack, &udev->bcdDevice);
+}
+
+void pack_usb_interface(int pack, struct usb_interface *udev)
+{
+	/* uint8_t members need nothing */
+}
+
 
 static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending)
 {
 	ssize_t total = 0;
 
-	if(!bufflen)
+	if (!bufflen)
 		return 0;
 
 	do {
 		ssize_t nbytes;
 
-		if(sending)
+		if (sending)
 			nbytes = send(sockfd, buff, bufflen, 0);
 		else
 			nbytes = recv(sockfd, buff, bufflen, MSG_WAITALL);
 
-		if(nbytes <= 0)
+		if (nbytes <= 0)
 			return -1;
 
 		buff	= (void *) ((intptr_t) buff + nbytes);
@@ -57,7 +97,7 @@
 	PACK_OP_COMMON(1, &op_common);
 
 	ret = usbip_send(sockfd, (void *) &op_common, sizeof(op_common));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_common");
 		return -1;
 	}
@@ -73,14 +113,14 @@
 	bzero(&op_common, sizeof(op_common));
 
 	ret = usbip_recv(sockfd, (void *) &op_common, sizeof(op_common));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_common, %d", ret);
 		goto err;
 	}
 
 	PACK_OP_COMMON(0, &op_common);
 
-	if(op_common.version != USBIP_VERSION) {
+	if (op_common.version != USBIP_VERSION) {
 		err("version mismatch, %d %d", op_common.version, USBIP_VERSION);
 		goto err;
 	}
@@ -89,13 +129,13 @@
 		case OP_UNSPEC:
 			break;
 		default:
-			if(op_common.code != *code) {
+			if (op_common.code != *code) {
 				info("unexpected pdu %d for %d", op_common.code, *code);
 				goto err;
 			}
 	}
 
-	if(op_common.status != ST_OK) {
+	if (op_common.status != ST_OK) {
 		info("request failed at peer, %d", op_common.status);
 		goto err;
 	}
@@ -107,40 +147,39 @@
 	return -1;
 }
 
-/* IPv6 ready */
-void usbip_peername(char *host, char *port, int sockfd)
+
+int usbip_set_reuseaddr(int sockfd)
 {
+	const int val = 1;
 	int ret;
 
-	struct sockaddr_storage ss;
-	socklen_t len = sizeof(ss);
+	ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt SO_REUSEADDR");
 
-	bzero(&ss, sizeof(ss));
+	return ret;
+}
 
-	ret = getpeername(sockfd, (struct sockaddr *) &ss, &len);
-	if(ret < 0) {
-		err("getpeername, %s", gai_strerror(ret));
-		return;
+int usbip_set_nodelay(int sockfd)
+{
+	const int val = 1;
+	int ret;
 
-	}
+	ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt TCP_NODELAY");
 
-	ret = getnameinfo((struct sockaddr *)&ss, len,
-			host, sizeof(host), port, sizeof(port),
-			NI_NUMERICHOST | NI_NUMERICSERV);
-
-	if(ret){
-		err("getnameinfo, %s", gai_strerror(ret));
-		return;
-	}
+	return ret;
 }
 
-
-void usbip_set_reuseaddr(int sockfd)
+int usbip_set_keepalive(int sockfd)
 {
 	const int val = 1;
 	int ret;
 
-	ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-	if(ret < 0)
-		err("setsockopt");
+	ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt SO_KEEPALIVE");
+
+	return ret;
 }
diff -Naur usbip-0.1.4/src/cmd/usbip_network.h trunk/src/cmd/usbip_network.h
--- usbip-0.1.4/src/cmd/usbip_network.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/usbip_network.h	2007-05-18 11:10:06.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #ifndef _USBIP_NETWORK_H
@@ -8,6 +8,7 @@
 #include "usbip.h"
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <netinet/tcp.h>
 
 
 /* -------------------------------------------------- */
@@ -24,7 +25,7 @@
 #define OP_REPLY	(0x00 << 8)
 	uint16_t code;
 
-	/* add more error code */ 
+	/* add more error code */
 #define ST_OK	0x00
 #define ST_NA	0x01
 	uint32_t status; /* op_code status (for reply) */
@@ -35,7 +36,7 @@
 	pack_uint16_t(pack, &(op_common)->version);\
 	pack_uint16_t(pack, &(op_common)->code   );\
 	pack_uint32_t(pack, &(op_common)->status );\
-} while(0)
+} while (0)
 
 
 /* ---------------------------------------------------------------------- */
@@ -76,11 +77,11 @@
 } __attribute__((packed));
 
 #define PACK_OP_IMPORT_REQUEST(pack, request)  do {\
-} while(0)
+} while (0)
 
 #define PACK_OP_IMPORT_REPLY(pack, reply)  do {\
 	pack_usb_device(pack, &(reply)->udev);\
-} while(0)
+} while (0)
 
 /* ---------------------------------------------------------------------- */
 /* Negotiate IPSec encryption key. (still not used) */
@@ -118,23 +119,29 @@
 } __attribute__((packed));
 
 #define PACK_OP_DEVLIST_REQUEST(pack, request)  do {\
-} while(0)
+} while (0)
 
 #define PACK_OP_DEVLIST_REPLY(pack, reply)  do {\
 	pack_uint32_t(pack, &(reply)->ndev);\
-} while(0)
+} while (0)
 
 
 /* -------------------------------------------------- */
 /* Declare Prototype Function                         */
 /* -------------------------------------------------- */
 
+void pack_uint32_t(int pack, uint32_t *num);
+void pack_uint16_t(int pack, uint16_t *num);
+void pack_usb_device(int pack, struct usb_device *udev);
+void pack_usb_interface(int pack, struct usb_interface *uinf);
+
 ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen);
 ssize_t usbip_send(int sockfd, void *buff, size_t bufflen);
 int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status);
 int usbip_recv_op_common(int sockfd, uint16_t *code);
-void usbip_peername(char *host, char *port, int sockfd);
-void usbip_set_reuseaddr(int sockfd);
+int usbip_set_reuseaddr(int sockfd);
+int usbip_set_nodelay(int sockfd);
+int usbip_set_keepalive(int sockfd);
 
 #define USBIP_PORT 3240
 #define USBIP_PORT_STRING "3240"
diff -Naur usbip-0.1.4/src/cmd/utils.c trunk/src/cmd/utils.c
--- usbip-0.1.4/src/cmd/utils.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/utils.c	2007-05-18 11:10:07.000000000 +0200
@@ -176,7 +176,7 @@
 			/* end of line */
 			buff[index-1] = '\0';	/* get rid of delimitor */
 			return index;
-		} else 
+		} else
 			index++;
 	}
 
@@ -191,7 +191,7 @@
 	int len;
 	char buff[MAXLINE];
 
-	if (strlen + 3 > MAXLINE) 
+	if (strlen + 3 > MAXLINE)
 		return -1;
 
 	strncpy(buff, str, strlen);
diff -Naur usbip-0.1.4/src/cmd/utils.h trunk/src/cmd/utils.h
--- usbip-0.1.4/src/cmd/utils.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/utils.h	2007-05-18 11:10:07.000000000 +0200
@@ -23,7 +23,7 @@
 
 
 /* Be sync to kernel header */
-#define BUS_ID_SIZE 20 
+#define BUS_ID_SIZE 20
 
 int read_string(char *path, char *, size_t len);
 int read_integer(char *path);
diff -Naur usbip-0.1.4/src/cmd/vhci_attach.c trunk/src/cmd/vhci_attach.c
--- usbip-0.1.4/src/cmd/vhci_attach.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/cmd/vhci_attach.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #ifdef HAVE_CONFIG_H
@@ -18,36 +18,36 @@
 
 
 /* /sys/devices/platform/vhci_hcd/usb6/6-1/6-1:1.1  -> 1 */
-static int get_interface_number(struct usbip_vhci_driver *driver, char *path)
+static int get_interface_number(char *path)
 {
 	char *c;
 
-	c = strstr(path, driver->hc_device->bus_id);
-	if(!c) 
+	c = strstr(path, vhci_driver->hc_device->bus_id);
+	if (!c)
 		return -1;	/* hc exist? */
 	c++;
 	/* -> usb6/6-1/6-1:1.1 */
 
 	c = strchr(c, '/');
-	if(!c)
+	if (!c)
 		return -1;	/* hc exist? */
 	c++;
 	/* -> 6-1/6-1:1.1 */
 
 	c = strchr(c, '/');
-	if(!c) 
+	if (!c)
 		return -1;	/* no interface path */
 	c++;
 	/* -> 6-1:1.1 */
 
 	c = strchr(c, ':');
-	if(!c)
+	if (!c)
 		return -1;	/* no configuration? */
 	c++;
 	/* -> 1.1 */
 
 	c = strchr(c, '.');
-	if(!c)
+	if (!c)
 		return -1;	/* no interface? */
 	c++;
 	/* -> 1 */
@@ -66,7 +66,7 @@
 			udev->busid, udev->bConfigurationValue, i);
 
 	suinf = sysfs_open_device("usb", busid);
-	if(!suinf)
+	if (!suinf)
 		err("sysfs_open_device %s", busid);
 
 	return suinf;
@@ -89,7 +89,7 @@
 	if (fd < 0)
 		return -1;
 
-	snprintf(buff, MAX_BUFF, "%s %s %s\n", 
+	snprintf(buff, MAX_BUFF, "%s %s %s\n",
 			host, port, busid);
 
 	ret = write(fd, buff, strlen(buff));
@@ -124,7 +124,7 @@
 }
 
 
-void usbip_vhci_imported_device_dump(struct usbip_vhci_driver *driver, struct usbip_imported_device *idev)
+void usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
 {
 	char product_name[100];
 	char host[NI_MAXHOST] = "unknown host";
@@ -132,19 +132,19 @@
 	char remote_busid[SYSFS_BUS_ID_SIZE];
 	int ret;
 
-	if(idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) {
+	if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) {
 		info("Port %02d: <%s>", idev->port, usbip_status_string(idev->status));
 		return;
 	}
 
 	ret = read_record(idev->port, host, serv, remote_busid);
-	if(ret)
+	if (ret)
 		err("red_record");
 
 	info("Port %02d: <%s> at %s", idev->port,
 			usbip_status_string(idev->status), usbip_speed_string(idev->udev.speed));
 
-	usbip_product_name(product_name, sizeof(product_name),
+	usbip_names_get_product(product_name, sizeof(product_name),
 			idev->udev.idVendor, idev->udev.idProduct);
 
 	info("       %s",  product_name);
@@ -153,13 +153,14 @@
 			idev->udev.busid, host, serv, remote_busid,
 			idev->busnum, idev->devnum);
 
-	for(int i=0; i < idev->udev.bNumInterfaces; i++) {
+	for (int i=0; i < idev->udev.bNumInterfaces; i++) {
 		/* show interface information */
 		struct sysfs_device *suinf;
 
 		suinf = open_usb_interface(&idev->udev, i);
-		if(!suinf)
+		if (!suinf)
 			continue;
+
 		info("       %6s used by %-17s", suinf->bus_id, suinf->driver_name);
 		sysfs_close_device(suinf);
 
@@ -167,8 +168,8 @@
 		struct class_device *cdev;
 
 		dlist_for_each_data(idev->cdev_list, cdev, struct class_device) {
-			int ifnum = get_interface_number(driver, cdev->devpath);
-			if(ifnum == i) {
+			int ifnum = get_interface_number(cdev->devpath);
+			if (ifnum == i) {
 				info("           %s", cdev->clspath);
 			}
 		}
@@ -188,18 +189,18 @@
 
 	/* get all possible addresses */
 	err = getaddrinfo(hostname, service, &hints, &res0);
-	if(err) {
+	if (err) {
 		err("%s %s: %s", hostname, service, gai_strerror(err));
 		return -1;
 	}
 
 	/* try all the addresses */
-	for(res = res0; res; res = res->ai_next) {
+	for (res = res0; res; res = res->ai_next) {
 		char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
 
 		err = getnameinfo(res->ai_addr, res->ai_addrlen,
 				hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
-		if(err) {
+		if (err) {
 			err("%s %s: %s", hostname, service, gai_strerror(err));
 			continue;
 		}
@@ -207,13 +208,18 @@
 		dbg("trying %s port %s\n", hbuf, sbuf);
 
 		sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-		if(sockfd < 0) {
+		if (sockfd < 0) {
 			err("socket");
 			continue;
 		}
 
+		/* should set TCP_NODELAY for usbip */
+		usbip_set_nodelay(sockfd);
+		/* TODO: write code for heatbeat */
+		usbip_set_keepalive(sockfd);
+
 		err = connect(sockfd, res->ai_addr, res->ai_addrlen);
-		if(err < 0) {
+		if (err < 0) {
 			close(sockfd);
 			continue;
 		}
@@ -242,19 +248,19 @@
 	bzero(&rep, sizeof(rep));
 
 	ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_common");
 		return -1;
 	}
 
 	ret = usbip_recv_op_common(sockfd, &code);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_common");
 		return -1;
 	}
 
 	ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_devlist");
 		return -1;
 	}
@@ -262,7 +268,7 @@
 	PACK_OP_DEVLIST_REPLY(0, &rep);
 	dbg("exportable %d devices", rep.ndev);
 
-	for(unsigned int i=0; i < rep.ndev; i++) {
+	for (unsigned int i=0; i < rep.ndev; i++) {
 		char product_name[100];
 		char class_name[100];
 		struct usb_device udev;
@@ -270,32 +276,32 @@
 		bzero(&udev, sizeof(udev));
 
 		ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
-		if(ret < 0) {
+		if (ret < 0) {
 			err("recv usb_device[%d]", i);
 			return -1;
 		}
 		pack_usb_device(0, &udev);
 
-		usbip_product_name(product_name, sizeof(product_name),
+		usbip_names_get_product(product_name, sizeof(product_name),
 				udev.idVendor, udev.idProduct);
-		usbip_class_name(class_name, sizeof(class_name), udev.bDeviceClass,
+		usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
 				udev.bDeviceSubClass, udev.bDeviceProtocol);
 
 		info("%8s: %s", udev.busid, product_name);
 		info("%8s: %s", " ", udev.path);
 		info("%8s: %s", " ", class_name);
 
-		for(int j=0; j < udev.bNumInterfaces; j++) {
+		for (int j=0; j < udev.bNumInterfaces; j++) {
 			struct usb_interface uinf;
 
 			ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
-			if(ret < 0) {
+			if (ret < 0) {
 				err("recv usb_interface[%d]", j);
 				return -1;
 			}
 
 			pack_usb_interface(0, &uinf);
-			usbip_class_name(class_name, sizeof(class_name), uinf.bInterfaceClass,
+			usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass,
 					uinf.bInterfaceSubClass, uinf.bInterfaceProtocol);
 
 			info("%8s: %2d - %s", " ", j, class_name);
@@ -310,30 +316,30 @@
 static int import_device(int sockfd, struct usb_device *udev)
 {
 	int ret;
-	struct usbip_vhci_driver *driver;
 	int port;
 
-	driver = usbip_vhci_driver_open();
-	if(!driver) {
+	ret = usbip_vhci_driver_open();
+	if (ret < 0) {
 		err("open vhci_driver");
 		return -1;
 	}
 
-	port = usbip_vhci_get_free_port(driver);
-	if(port < 0) {
+	port = usbip_vhci_get_free_port();
+	if (port < 0) {
 		err("no free port");
-		usbip_vhci_driver_close(driver);
+		usbip_vhci_driver_close();
 		return -1;
 	}
 
-	ret = usbip_vhci_import_device(driver, port, sockfd, udev);
-	if(ret < 0) {
+	ret = usbip_vhci_attach_device(port, sockfd, udev->busnum,
+			udev->devnum, udev->speed);
+	if (ret < 0) {
 		err("import device");
-		usbip_vhci_driver_close(driver);
+		usbip_vhci_driver_close();
 		return -1;
 	}
 
-	usbip_vhci_driver_close(driver);
+	usbip_vhci_driver_close();
 
 	return port;
 }
@@ -352,7 +358,7 @@
 
 	/* send a request */
 	ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_common");
 		return -1;
 	}
@@ -362,7 +368,7 @@
 	PACK_OP_IMPORT_REQUEST(0, &request);
 
 	ret = usbip_send(sockfd, (void *) &request, sizeof(request));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("send op_import_request");
 		return -1;
 	}
@@ -370,13 +376,13 @@
 
 	/* recieve a reply */
 	ret = usbip_recv_op_common(sockfd, &code);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_common");
 		return -1;
 	}
 
 	ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("recv op_import_reply");
 		return -1;
 	}
@@ -385,7 +391,7 @@
 
 
 	/* check the reply */
-	if(strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) {
+	if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) {
 		err("recv different busid %s", reply.udev.busid);
 		return -1;
 	}
@@ -402,13 +408,13 @@
 	int rhport;
 
 	sockfd = tcp_connect(host, USBIP_PORT_STRING);
-	if(sockfd < 0) {
+	if (sockfd < 0) {
 		err("tcp connect");
 		return;
 	}
 
 	rhport = query_import_device(sockfd, busid);
-	if(rhport < 0) {
+	if (rhport < 0) {
 		err("query");
 		return;
 	}
@@ -417,7 +423,7 @@
 
 	ret = record_connection(host, USBIP_PORT_STRING,
 			busid, rhport);
-	if (ret < 0) 
+	if (ret < 0)
 		err("record connection");
 
 	return;
@@ -425,11 +431,11 @@
 
 static void detach_port(char *port)
 {
-	struct usbip_vhci_driver *driver;
+	int ret;
 	uint8_t portnum;
 
-	for(unsigned int i=0; i < strlen(port); i++)
-		if(!isdigit(port[i])) {
+	for (unsigned int i=0; i < strlen(port); i++)
+		if (!isdigit(port[i])) {
 			err("invalid port %s", port);
 			return;
 		}
@@ -438,15 +444,15 @@
 
 	portnum = atoi(port);
 
-	driver = usbip_vhci_driver_open();
-	if(!driver) {
+	ret = usbip_vhci_driver_open();
+	if (ret < 0) {
 		err("open vhci_driver");
 		return;
 	}
 
-	usbip_vhci_detach_device(driver, portnum);
+	usbip_vhci_detach_device(portnum);
 
-	usbip_vhci_driver_close(driver);
+	usbip_vhci_driver_close();
 }
 
 static void show_exported_devices(char *host)
@@ -455,7 +461,7 @@
 	int sockfd;
 
 	sockfd = tcp_connect(host, USBIP_PORT_STRING);
-	if(sockfd < 0) {
+	if (sockfd < 0) {
 		info("- %s failed", host);
 		return;
 	}
@@ -463,6 +469,82 @@
 	info("- %s", host);
 
 	ret = query_exported_devices(sockfd);
+	if (ret < 0) {
+		err("query");
+	}
+
+	close(sockfd);
+}
+
+static int attach_exported_devices(char *host, int sockfd)
+{
+	int ret;
+	struct op_devlist_reply rep;
+	uint16_t code = OP_REP_DEVLIST;
+
+	bzero(&rep, sizeof(rep));
+
+	ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
+	if(ret < 0) {
+		err("send op_common");
+		return -1;
+	}
+
+	ret = usbip_recv_op_common(sockfd, &code);
+	if(ret < 0) {
+		err("recv op_common");
+		return -1;
+	}
+
+	ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
+	if(ret < 0) {
+		err("recv op_devlist");
+		return -1;
+	}
+
+	PACK_OP_DEVLIST_REPLY(0, &rep);
+	dbg("exportable %d devices", rep.ndev);
+
+	for(unsigned int i=0; i < rep.ndev; i++) {
+		char product_name[100];
+		char class_name[100];
+		struct usb_device udev;
+
+		bzero(&udev, sizeof(udev));
+
+		ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
+		if(ret < 0) {
+			err("recv usb_device[%d]", i);
+			return -1;
+		}
+		pack_usb_device(0, &udev);
+
+		usbip_names_get_product(product_name, sizeof(product_name),
+				udev.idVendor, udev.idProduct);
+		usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
+				udev.bDeviceSubClass, udev.bDeviceProtocol);
+
+		dbg("Attaching usb port %s from host %s on usbip, with deviceid: %s", udev.busid, host, product_name);
+		attach_device(host, udev.busid);
+	}
+
+	return rep.ndev;
+}
+
+static void attach_devices_all(char *host)
+{
+	int ret;
+	int sockfd;
+
+	sockfd = tcp_connect(host, USBIP_PORT_STRING);
+	if(sockfd < 0) {
+		info("- %s failed", host);
+		return;
+	}
+
+	info("- %s", host);
+
+	ret = attach_exported_devices(host, sockfd);
 	if(ret < 0) {
 		err("query");
 	}
@@ -476,6 +558,9 @@
 	-a, --attach [host] [bus_id]		\n\
 		Attach a remote USB device.	\n\
 						\n\
+	-x, --attachall [host]		\n\
+		Attach all remote USB devices on the specific host.	\n\
+						\n\
 	-d, --detach [ports]			\n\
 		Detach an imported USB device.	\n\
 						\n\
@@ -499,29 +584,30 @@
 	printf("%s", help_message);
 }
 
-static void show_port_status(void) 
+static void show_port_status(void)
 {
+	int ret;
 	struct usbip_imported_device *idev;
-	struct usbip_vhci_driver *driver;
 
-	driver = usbip_vhci_driver_open();
-	if(!driver) {
+	ret = usbip_vhci_driver_open();
+	if (ret < 0)
 		return;
-	}
 
-	for(int i = 0; i < driver->nports; i++) {
-		idev = &driver->idev[i];
 
-		usbip_vhci_imported_device_dump(driver, idev);
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		idev = &vhci_driver->idev[i];
+
+		usbip_vhci_imported_device_dump(idev);
 	}
 
-	usbip_vhci_driver_close(driver);
+	usbip_vhci_driver_close();
 }
 
 #define _GNU_SOURCE
 #include <getopt.h>
 static const struct option longopts[] = {
 	{"attach",	no_argument,	NULL, 'a'},
+	{"attachall",	no_argument,	NULL, 'x'},
 	{"detach",	no_argument,	NULL, 'd'},
 	{"port",	no_argument,	NULL, 'p'},
 	{"list",	no_argument,	NULL, 'l'},
@@ -538,6 +624,7 @@
 
 	enum {
 		cmd_attach = 1,
+		cmd_attachall,
 		cmd_detach,
 		cmd_port,
 		cmd_list,
@@ -547,49 +634,55 @@
 
 	usbip_use_stderr = 1;
 
- 	ret = names_init(USBIDS_FILE);
- 	if(ret)
+ 	ret = usbip_names_init(USBIDS_FILE);
+ 	if (ret)
  		err("open usb.ids");
 
-	while(1) {
+	for (;;) {
 		int c;
 		int index = 0;
 
-		c = getopt_long(argc, argv, "adplvhDS", longopts, &index);
+		c = getopt_long(argc, argv, "adplvhDSx", longopts, &index);
 
-		if(c == -1)
+		if (c == -1)
 			break;
 
 		switch(c) {
 			case 'a':
-				if(!cmd)
+				if (!cmd)
 					cmd = cmd_attach;
 				else
 					cmd = cmd_help;
 				break;
 			case 'd':
-				if(!cmd)
+				if (!cmd)
 					cmd = cmd_detach;
 				else
 					cmd = cmd_help;
 				break;
 			case 'p':
-				if(!cmd)
+				if (!cmd)
 					cmd = cmd_port;
 				else cmd = cmd_help;
 				break;
 			case 'l':
-				if(!cmd)
+				if (!cmd)
 					cmd = cmd_list;
 				else
 					cmd = cmd_help;
 				break;
 			case 'v':
-				if(!cmd)
+				if (!cmd)
 					cmd = cmd_version;
 				else
 					cmd = cmd_help;
 				break;
+			case 'x':
+				if(!cmd)
+					cmd = cmd_attachall;
+				else
+					cmd = cmd_help;
+				break;
 			case 'h':
 				cmd = cmd_help;
 				break;
@@ -610,22 +703,26 @@
 
 	switch(cmd) {
 		case cmd_attach:
-			if(optind == argc - 2)
+			if (optind == argc - 2)
 				attach_device(argv[optind], argv[optind+1]);
 			else
 				show_help();
 			break;
 		case cmd_detach:
-			while(optind < argc)
+			while (optind < argc)
 				detach_port(argv[optind++]);
 			break;
 		case cmd_port:
 			show_port_status();
 			break;
 		case cmd_list:
-			while(optind < argc)
+			while (optind < argc)
 				show_exported_devices(argv[optind++]);
 			break;
+		case cmd_attachall:
+			while(optind < argc)
+				attach_devices_all(argv[optind++]);
+			break;
 		case cmd_version:
 			printf("%s\n", version);
 			break;
@@ -637,7 +734,7 @@
 	}
 
 
-	names_deinit();
+	usbip_names_free();
 
 	return 0;
 }
diff -Naur usbip-0.1.4/src/configure.ac trunk/src/configure.ac
--- usbip-0.1.4/src/configure.ac	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/configure.ac	2007-05-18 11:10:08.000000000 +0200
@@ -2,8 +2,9 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(usbip, 0.1.4, taka-hir@is.naist.jp)
-AC_DEFINE(USBIP_VERSION, 0x000104, Numeric version number)
+AC_REVISION($Id: configure.ac 239 2006-12-26 09:51:23Z taka-hir $)
+AC_INIT(usbip, 0.1.5, taka-hir@is.naist.jp)
+AC_DEFINE(USBIP_VERSION, 0x000105, Numeric version number)
 
 AC_CONFIG_SRCDIR([config.h.in])
 AM_INIT_AUTOMAKE
@@ -38,44 +39,62 @@
 AC_CHECK_HEADER(sysfs/libsysfs.h,
 	[AC_CHECK_LIB(sysfs, sysfs_open_directory_list,
 		[LIBS="$LIBS -lsysfs"],
-	[AC_MSG_ERROR([Missing sysfs2 library!])])],
+		[AC_MSG_ERROR([Missing sysfs2 library!])])],
 	[AC_MSG_ERROR([Missing /usr/include/sysfs/libsysfs.h])])
 
 
 # get from stunnel
 dnl Check for libwrap library.
 AC_MSG_CHECKING([whether to use the libwrap (TCP wrappers) library])
+
 AC_ARG_WITH(tcp-wrappers,
-	[ --with-tcp-wrappers     Use the libwrap (TCP wrappers) library ],
-	[
-	   saved_LIBS="$LIBS"
-	   if test "$withval" = "yes"; then
-	       	    AC_MSG_RESULT([yes])
-	       	    AC_MSG_CHECKING([for hosts_access in -lwrap])
-	       	    LIBS="-lwrap $LIBS"
-	       	    AC_TRY_LINK([int hosts_access(); int allow_severity, deny_severity;],
-			    [hosts_access()],
-			    [AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_LIBWRAP, 1, use tcp wrapper) wrap_LIB="-lwrap"],
-			    [AC_MSG_RESULT([not found]); exit 1])
-	   else
-	       	    AC_MSG_RESULT([no])
-	   fi
-	   LIBS="$saved_LIBS"
-	 ],
-	 [
-	    AC_MSG_RESULT([(default)])
-	    AC_MSG_CHECKING([for hosts_access in -lwrap])
-	    saved_LIBS="$LIBS"
-	    LIBS="-lwrap $saved_LIBS"
-	    AC_TRY_LINK([int hosts_access(); int allow_severity, deny_severity;],
-	            [hosts_access()],
-	            [AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_LIBWRAP, 1, use tcp wrapper)],
-	            [AC_MSG_RESULT([no]); LIBS="$saved_LIBS"])
-	]
-    )
+[  --with-tcp-wrappers     Use the libwrap (TCP wrappers) library ],
+[saved_LIBS="$LIBS"
+ if test "$withval" = "yes"; then
+      AC_MSG_RESULT([yes])
+      AC_MSG_CHECKING([for hosts_access in -lwrap])
+      LIBS="-lwrap $LIBS"
+      AC_TRY_LINK(
+	[int hosts_access(); int allow_severity, deny_severity;],
+	[hosts_access()],
+	[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_LIBWRAP, 1, use tcp wrapper) wrap_LIB="-lwrap"],
+	[AC_MSG_RESULT([not found]); exit 1])
+ else
+ 	     AC_MSG_RESULT([no])
+ fi
+ LIBS="$saved_LIBS"],
+[AC_MSG_RESULT([(default)])
+ AC_MSG_CHECKING([for hosts_access in -lwrap])
+ saved_LIBS="$LIBS"
+ LIBS="-lwrap $saved_LIBS"
+ AC_TRY_LINK(
+	[int hosts_access(); int allow_severity, deny_severity;],
+ 	[hosts_access()],
+ 	[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_LIBWRAP, 1, use tcp wrapper)],
+ 	[AC_MSG_RESULT([no]); LIBS="$saved_LIBS"])
+])
+
+
+
+USBIDS_DIR='${datadir}/usbip'
+AC_ARG_WITH(usbids-dir, [  --with-usbids-dir=DIR   where usb.ids is found (default ${datadir}/usbip)], [USBIDS_DIR=$withval])
+AC_SUBST(USBIDS_DIR)
+
+dnl FIXME: when disabled, empty directry is created
+usbids=install
+AC_ARG_ENABLE(usbids-install,
+[  --enable-usbids-install     install usb.ids (default)],
+[case "${enableval}" in
+ yes) usbids=install ;;
+ no)  usbids=notinstall ;;
+ *)   AC_MSG_ERROR(bad value ${enableval} for --enable-usbids-install) ;;
+ esac])
+AM_CONDITIONAL(INSTALL_USBIDS, test x$usbids = xinstall)
+    	
+
 
-pkg_modules="glib-2.0"
-PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
+GLIB2_REQUIRED=2.6.0
+PKG_CHECK_MODULES(PACKAGE, glib-2.0 >= $GLIB2_REQUIRED)
 AC_SUBST(PACKAGE_CFLAGS)
 AC_SUBST(PACKAGE_LIBS)
 
diff -Naur usbip-0.1.4/src/include/names.h trunk/src/include/names.h
--- usbip-0.1.4/src/include/names.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/include/names.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,57 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      names.h  --  USB name database manipulation routines
- *
- *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *      This program 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 program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-/*
- *	Copyright (C) 2005 Takahiro Hirofuchi
- *	       - names_deinit() is added. 
- */
-
-/*****************************************************************************/
-
-#ifndef _NAMES_H
-#define _NAMES_H
-
-#include <sys/types.h>
-
-/* ---------------------------------------------------------------------- */
-
-extern const char *names_vendor(u_int16_t vendorid);
-extern const char *names_product(u_int16_t vendorid, u_int16_t productid);
-extern const char *names_class(u_int8_t classid);
-extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid);
-extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid);
-extern const char *names_audioterminal(u_int16_t termt);
-extern const char *names_hid(u_int8_t hidd);
-extern const char *names_reporttag(u_int8_t rt);
-extern const char *names_huts(unsigned int data);
-extern const char *names_hutus(unsigned int data);
-extern const char *names_langid(u_int16_t langid);
-extern const char *names_physdes(u_int8_t ph);
-extern const char *names_bias(u_int8_t b);
-extern const char *names_countrycode(unsigned int countrycode);
-extern int  names_init(char *n);
-extern void names_deinit(void);
-
-/* ---------------------------------------------------------------------- */
-#endif /* _NAMES_H */
diff -Naur usbip-0.1.4/src/include/stub_driver.h trunk/src/include/stub_driver.h
--- usbip-0.1.4/src/include/stub_driver.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/include/stub_driver.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
- */
-
-#ifndef _USBIP_STUB_DRIVER_H
-#define _USBIP_STUB_DRIVER_H
-
-#include "usbip.h"
-
-
-struct usbip_stub_driver {
-	int ndevs;
-	struct sysfs_driver *sysfs_driver;
-
-	struct dlist *edev_list;	/* list of exported device */
-};
-
-struct usbip_exported_device {
-	struct sysfs_device *sudev;
-
-	int32_t status;
-	struct usb_device    udev;
-	struct usb_interface uinf[];
-};
-
-
-
-struct usbip_stub_driver *usbip_stub_driver_open(void);
-void usbip_stub_driver_close(struct usbip_stub_driver *driver);
-int usbip_stub_refresh_device_list(struct usbip_stub_driver *driver);
-int usbip_stub_export_device(struct usbip_stub_driver *driver,
-		struct usbip_exported_device *edev, int sockfd);
-
-/* add for SWIG */
-struct usbip_exported_device *usbip_stub_get_device(struct usbip_stub_driver *, int num);
-#endif
diff -Naur usbip-0.1.4/src/include/usbip_common.h trunk/src/include/usbip_common.h
--- usbip-0.1.4/src/include/usbip_common.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/include/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
- */
-
-#ifndef _USBIP_COMMON_H
-#define _USBIP_COMMON_H
-
-#include <unistd.h>
-#include <stdint.h>
-#include <syslog.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <strings.h>
-
-#include <sysfs/libsysfs.h>
-#include <netdb.h>
-#include <sys/socket.h>
-
-#define USBIDS_FILE "/usr/share/hwdata/usb.ids"
-
-extern int usbip_use_syslog;
-extern int usbip_use_stderr;
-extern int usbip_use_debug ;
-
-//#include <linux/usb_ch9.h>
-enum usb_device_speed {
-	USB_SPEED_UNKNOWN = 0,                  /* enumerating */
-	USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */
-	USB_SPEED_HIGH,                         /* usb 2.0 */
-	USB_SPEED_VARIABLE                      /* wireless (usb 2.5) */
-};
-
-/* FIXME: how to sync with drivers/usbip_common.h ? */
-enum usbip_device_status{
-	/* sdev is available. */
-	SDEV_ST_AVAILABLE = 0x01,
-	/* sdev is now used. */
-	SDEV_ST_USED,
-	/* sdev is unusable because of a fatal error. */
-	SDEV_ST_ERROR,
-
-	/* vdev does not connect a remote device. */
-	VDEV_ST_NULL,
-	/* vdev is used, but the USB address is not assigned yet */
-	VDEV_ST_NOTASSIGNED,
-	VDEV_ST_USED,
-	VDEV_ST_ERROR
-};
-
-#define err(fmt, args...)	do { \
-	if(usbip_use_syslog) { \
-		syslog(LOG_ERR, "usbip err: %13s:%4d (%-12s) " fmt "  [%s]", \
-			__FILE__, __LINE__, __FUNCTION__,  ##args, strerror(errno)); \
-	} \
-	if(usbip_use_stderr) { \
-		fprintf(stderr, "usbip err: %13s:%4d (%-12s) " fmt "  [%s]\n", \
-			__FILE__, __LINE__, __FUNCTION__,  ##args, strerror(errno)); \
-	} \
-} while (0)
-		
-#define notice(fmt, args...)	do { \
-	if(usbip_use_syslog) { \
-		syslog(LOG_DEBUG, "usbip: " fmt, ##args); \
-	} \
-	if(usbip_use_stderr) { \
-		fprintf(stderr, "usbip: " fmt "\n",  ##args); \
-	} \
-} while (0)
-
-#define info(fmt, args...)	do { \
-	if(usbip_use_syslog) { \
-		syslog(LOG_DEBUG, fmt, ##args); \
-	} \
-	if(usbip_use_stderr) { \
-		fprintf(stderr, fmt "\n",  ##args); \
-	} \
-} while (0)
-
-#define dbg(fmt, args...)	do { \
-	if(usbip_use_debug) { \
-		if(usbip_use_syslog) { \
-			syslog(LOG_DEBUG, "usbip dbg: %13s:%4d (%-12s) " fmt, \
-				__FILE__, __LINE__, __FUNCTION__,  ##args); \
-		} \
-		if(usbip_use_stderr) { \
-			fprintf(stderr, "usbip dbg: %13s:%4d (%-12s) " fmt "\n", \
-				__FILE__, __LINE__, __FUNCTION__,  ##args); \
-		} \
-	} \
-} while (0)
-
-
-#define BUG()	do { err("sorry, it's a bug"); abort(); } while(0)
-
-struct usb_interface {
-	uint8_t bInterfaceClass;
-	uint8_t bInterfaceSubClass;
-	uint8_t bInterfaceProtocol;
-} __attribute__((packed));
-
-
-
-struct usb_device {
-	char path[SYSFS_PATH_MAX];
-	char busid[SYSFS_BUS_ID_SIZE];
-
-	uint32_t busnum;
-	uint32_t devnum;
-	uint32_t speed;
-
-	uint16_t idVendor;
-	uint16_t idProduct;
-	uint16_t bcdDevice;
-
-	uint8_t bDeviceClass;
-	uint8_t bDeviceSubClass;
-	uint8_t bDeviceProtocol;
-	uint8_t bConfigurationValue;
-	uint8_t bNumConfigurations;
-	uint8_t bNumInterfaces;
-} __attribute__((packed));
-
-#define to_string(s)	#s
-
-void dump_usb_interface(struct usb_interface *);
-void dump_usb_device(struct usb_device *);
-int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev);
-int read_attr_value(struct sysfs_device *dev, const char *name, const char *format);
-int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf);
-
-const char *usbip_speed_string(int num);
-const char *usbip_status_string(int32_t status);
-
-void usbip_product_name(char *buff, size_t size, uint16_t vendor, uint16_t product);
-void usbip_class_name(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol);
-
-void pack_uint32_t(int pack, uint32_t *num);
-void pack_uint16_t(int pack, uint16_t *num);
-void pack_usb_device(int pack, struct usb_device *udev);
-void pack_usb_interface(int pack, struct usb_interface *uinf);
-
-#endif
diff -Naur usbip-0.1.4/src/include/usbip.h trunk/src/include/usbip.h
--- usbip-0.1.4/src/include/usbip.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/include/usbip.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
- */
-
-#ifndef _USBIP_H
-#define _USBIP_H
-
-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
-
-#include "names.h"
-#include "usbip_common.h"
-#include "stub_driver.h"
-#include "vhci_driver.h"
-#ifdef DMALLOC
-#include <dmalloc.h>
-#endif
-
-#endif
diff -Naur usbip-0.1.4/src/include/vhci_driver.h trunk/src/include/vhci_driver.h
--- usbip-0.1.4/src/include/vhci_driver.h	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/include/vhci_driver.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
- */
-
-#ifndef _VHCI_DRIVER_H
-#define _VHCI_DRIVER_H
-
-#include "usbip.h"
-
-
-extern const char *portst_str[];
-
-
-#define MAXNPORT 128
-
-struct class_device {
-	char clspath[SYSFS_PATH_MAX];
-	char devpath[SYSFS_PATH_MAX];
-};
-
-struct usbip_imported_device {
-	uint8_t port;
-	uint32_t status;
-
-	uint8_t busnum;
-	uint8_t devnum;
-
-
-	struct dlist *cdev_list;	/* list of class device */
-	struct usb_device udev;
-};
-
-struct usbip_vhci_driver {
-	char sysfs_mntpath[SYSFS_PATH_MAX];
-	struct sysfs_device *hc_device; /* /sys/devices/platform/vhci_hcd */
-
-	struct dlist *cdev_list;	/* list of class device */
-
-	int nports;
-	struct usbip_imported_device idev[MAXNPORT];
-};
-
-
-
-struct usbip_vhci_driver *usbip_vhci_driver_open(void);
-void   usbip_vhci_driver_close(struct usbip_vhci_driver *driver);
-int  usbip_vhci_refresh_device_list(struct usbip_vhci_driver *driver);
-
-
-int usbip_vhci_get_free_port(struct usbip_vhci_driver *driver);
-int usbip_vhci_import_device(struct usbip_vhci_driver *driver,
-		uint8_t port, int sockfd, struct usb_device *udev);
-int usbip_vhci_import_device2(struct usbip_vhci_driver *driver,
-		uint8_t port, int sockfd, uint8_t busnum,
-		uint8_t devnum, uint32_t speed);
-int usbip_vhci_detach_device(struct usbip_vhci_driver *driver, uint8_t port);
-#endif
diff -Naur usbip-0.1.4/src/INSTALL trunk/src/INSTALL
--- usbip-0.1.4/src/INSTALL	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/INSTALL	2007-05-18 11:10:08.000000000 +0200
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
-Software Foundation, Inc.
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
 
 This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
@@ -10,7 +10,10 @@
 Basic Installation
 ==================
 
-These are generic installation instructions.
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -23,9 +26,9 @@
 
    It can also use an optional file (typically called `config.cache'
 and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  (Caching is
+the results of its tests to speed up reconfiguring.  Caching is
 disabled by default to prevent problems with accidental use of stale
-cache files.)
+cache files.
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
@@ -35,20 +38,17 @@
 may remove or edit it.
 
    The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
 
 The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
+     `./configure' to configure the package for your system.
 
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
@@ -78,7 +78,7 @@
 by setting variables in the command line or in the environment.  Here
 is an example:
 
-     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
 
    *Note Defining Variables::, for more details.
 
@@ -87,17 +87,15 @@
 
 You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
 source code in the directory that `configure' is in and in `..'.
 
-   If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a
-time in the source code directory.  After you have installed the
-package for one architecture, use `make distclean' before reconfiguring
-for another architecture.
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
 
 Installation Names
 ==================
@@ -190,12 +188,12 @@
      ./configure CC=/usr/local2/bin/gcc
 
 causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).  Here is a another example:
+overridden in the site shell script).
 
-     /bin/bash ./configure CONFIG_SHELL=/bin/bash
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
 
-Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
-configuration-related scripts to be executed by `/bin/bash'.
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
 
 `configure' Invocation
 ======================
diff -Naur usbip-0.1.4/src/lib/Makefile.am trunk/src/lib/Makefile.am
--- usbip-0.1.4/src/lib/Makefile.am	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/lib/Makefile.am	2007-05-18 11:10:07.000000000 +0200
@@ -1,8 +1,10 @@
 # AM_CFLAGS = -Wall -std=gnu99
 lib_LTLIBRARIES = libusbip.la
 libusbip_la_SOURCES = names.c names.h stub_driver.c stub_driver.h usbip.h usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h
-AM_CPPFLAGS = -I../include -Wall -std=gnu99
+#libusbip_la_SOURCES = names.c names.h stub_driver.c usbip_common.c vhci_driver.c
+#INCLUDES = -I../include
+#AM_CPPFLAGS = -I../include -Wall -std=gnu99
 libusbip_la_LDFLAGS = -version-info 0:1:0
 EXTRA_CFLAGS = @EXTRA_CLFAGS@
-libusbip_la_CFLAGS = -Wall -W -Wstrict-prototypes $(EXTRA_CLFAGS)
+libusbip_la_CFLAGS = -Wall -W -Wstrict-prototypes -std=gnu99 $(EXTRA_CLFAGS) -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"'
 
diff -Naur usbip-0.1.4/src/lib/names.c trunk/src/lib/names.c
--- usbip-0.1.4/src/lib/names.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/lib/names.c	2007-05-18 11:10:07.000000000 +0200
@@ -239,27 +239,27 @@
 }
 
 /* ---------------------------------------------------------------------- */
+/* add a cleanup function by takahiro */
 
-/* add a cleanup function */
 struct pool {
 	struct pool *next;
 	void *mem;
 };
 
-struct pool *pool_head = NULL;
+static struct pool *pool_head = NULL;
 
 static void *my_malloc(size_t size)
 {
 	struct pool *p;
 
 	p = calloc(1, sizeof(struct pool));
-	if(!p) {
+	if (!p) {
 		free(p);
 		return NULL;
 	}
 
 	p->mem = calloc(1, size);
-	if(!p->mem)
+	if (!p->mem)
 		return NULL;
 
 	p->next = pool_head;
@@ -268,17 +268,17 @@
 	return p->mem;
 }
 
-void names_deinit(void)
+void names_free(void)
 {
 	struct pool *pool;
 
-	if(!pool_head)
+	if (!pool_head)
 		return;
 
-	for(pool = pool_head; pool != NULL; ) {
+	for (pool = pool_head; pool != NULL; ) {
 		struct pool *tmp;
 
-		if(pool->mem)
+		if (pool->mem)
 			free(pool->mem);
 
 		tmp = pool;
@@ -411,7 +411,7 @@
 {
         struct genericstrtable *g;
 	unsigned int h = hashnum(index);
-        
+
         for (g = t[h]; g; g = g->next)
                 if (g->num == index)
                         return -1;
@@ -466,7 +466,7 @@
 
 /* ---------------------------------------------------------------------- */
 
-#define DBG(x) 
+#define DBG(x)
 
 static void parse(FILE *f)
 {
@@ -769,7 +769,7 @@
                         DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
                         continue;
 
-                }			
+                }
                 if (buf[0] == 'V' && buf[1] == 'T') {
 			/* add here */
 			continue;
@@ -783,7 +783,7 @@
 int names_init(char *n)
 {
 	FILE *f;
-	
+
 	if (!(f = fopen(n, "r"))) {
 		return errno;
 	}
diff -Naur usbip-0.1.4/src/lib/names.h trunk/src/lib/names.h
--- usbip-0.1.4/src/lib/names.h	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/lib/names.h	2007-05-18 11:10:07.000000000 +0200
@@ -0,0 +1,57 @@
+/*****************************************************************************/
+
+/*
+ *      names.h  --  USB name database manipulation routines
+ *
+ *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ *      This program 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 program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+/*
+ *	Copyright (C) 2005 Takahiro Hirofuchi
+ *	       - names_free() is added.
+ */
+
+/*****************************************************************************/
+
+#ifndef _NAMES_H
+#define _NAMES_H
+
+#include <sys/types.h>
+
+/* ---------------------------------------------------------------------- */
+
+extern const char *names_vendor(u_int16_t vendorid);
+extern const char *names_product(u_int16_t vendorid, u_int16_t productid);
+extern const char *names_class(u_int8_t classid);
+extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid);
+extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid);
+extern const char *names_audioterminal(u_int16_t termt);
+extern const char *names_hid(u_int8_t hidd);
+extern const char *names_reporttag(u_int8_t rt);
+extern const char *names_huts(unsigned int data);
+extern const char *names_hutus(unsigned int data);
+extern const char *names_langid(u_int16_t langid);
+extern const char *names_physdes(u_int8_t ph);
+extern const char *names_bias(u_int8_t b);
+extern const char *names_countrycode(unsigned int countrycode);
+extern int  names_init(char *n);
+extern void names_free(void);
+
+/* ---------------------------------------------------------------------- */
+#endif /* _NAMES_H */
diff -Naur usbip-0.1.4/src/lib/stub_driver.c trunk/src/lib/stub_driver.c
--- usbip-0.1.4/src/lib/stub_driver.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/lib/stub_driver.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #include "usbip.h"
@@ -7,6 +7,7 @@
 static const char *usbip_stub_driver_name = "usbip";
 
 
+struct usbip_stub_driver *stub_driver;
 
 static struct sysfs_driver *open_sysfs_stub_driver(void)
 {
@@ -18,7 +19,7 @@
 
 
 	ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("sysfs must be mounted");
 		return NULL;
 	}
@@ -28,7 +29,7 @@
 			usbip_stub_driver_name);
 
 	stub_driver = sysfs_open_driver_path(stub_driver_path);
-	if(!stub_driver) {
+	if (!stub_driver) {
 		err("stub.ko must be loaded");
 		return NULL;
 	}
@@ -36,19 +37,6 @@
 	return stub_driver;
 }
 
-#if 0
-static void unshift_if_new(struct dlist *dlist, struct sysfs_device *target)
-{
-	struct sysfs_device *dev;
-
-	dlist_for_each_data(dlist, dev, struct sysfs_device) {
-		if(!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE))
-			return;
-	}
-
-	dlist_unshift(dlist, (void *) target);
-}
-#endif
 
 
 /* only the first interface value is true! */
@@ -61,17 +49,17 @@
 
 	snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status",
 			udev->path, udev->busid,
-			udev->bConfigurationValue, 
+			udev->bConfigurationValue,
 			0);
 
 	attr = sysfs_open_attribute(attrpath);
-	if(!attr) {
+	if (!attr) {
 		err("open %s", attrpath);
 		return -1;
 	}
 
 	ret = sysfs_read_attribute(attr);
-	if(ret) {
+	if (ret) {
 		err("read %s", attrpath);
 		sysfs_close_attribute(attr);
 		return -1;
@@ -87,7 +75,7 @@
 
 static void usbip_exported_device_delete(void *dev)
 {
-	struct usbip_exported_device *edev = 
+	struct usbip_exported_device *edev =
 		(struct usbip_exported_device *) dev;
 
 	sysfs_close_device(edev->sudev);
@@ -100,13 +88,13 @@
 	struct usbip_exported_device *edev = NULL;
 
 	edev = (struct usbip_exported_device *) calloc(1, sizeof(*edev));
-	if(!edev) {
+	if (!edev) {
 		err("alloc device");
 		return NULL;
 	}
 
 	edev->sudev = sysfs_open_device_path(sdevpath);
-	if(!edev->sudev) {
+	if (!edev->sudev) {
 		err("open %s", sdevpath);
 		goto err;
 	}
@@ -114,26 +102,26 @@
 	read_usb_device(edev->sudev, &edev->udev);
 
 	edev->status = read_attr_usbip_status(&edev->udev);
-	if(edev->status < 0) 
+	if (edev->status < 0)
 		goto err;
 
 	/* reallocate buffer to include usb interface data */
 	size_t size = sizeof(*edev) + edev->udev.bNumInterfaces * sizeof(struct usb_interface);
 	edev = (struct usbip_exported_device *) realloc(edev, size);
-	if(!edev) {
+	if (!edev) {
 		err("alloc device");
 		goto err;
 	}
 
-	for(int i=0; i < edev->udev.bNumInterfaces; i++)
+	for (int i=0; i < edev->udev.bNumInterfaces; i++)
 		read_usb_interface(&edev->udev, i, &edev->uinf[i]);
 
 	return edev;
 
 err:
-	if(edev && edev->sudev)
+	if (edev && edev->sudev)
 		sysfs_close_device(edev->sudev);
-	if(edev)
+	if (edev)
 		free(edev);
 	return NULL;
 }
@@ -144,7 +132,7 @@
 	struct sysfs_device *dev;
 
 	dlist_for_each_data(dlist, dev, struct sysfs_device) {
-		if(!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE))
+		if (!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE))
 			/* found. not new */
 			return 0;
 	}
@@ -157,19 +145,19 @@
 	/* do not delete anything. but, its container will be deleted. */
 }
 
-static int refresh_exported_devices(struct usbip_stub_driver *driver)
+static int refresh_exported_devices(void)
 {
 	struct sysfs_device	*suinf;  /* sysfs_device of usb_interface */
 	struct dlist		*suinf_list;
 
 	struct sysfs_device	*sudev;  /* sysfs_device of usb_device */
-	struct dlist		*sudev_list; 
+	struct dlist		*sudev_list;
 
 
 	sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device), delete_nothing);
 
-	suinf_list = sysfs_get_driver_devices(driver->sysfs_driver);
-	if(!suinf_list) {
+	suinf_list = sysfs_get_driver_devices(stub_driver->sysfs_driver);
+	if (!suinf_list) {
 		printf("Bind usbip.ko to a usb device to be exportable!\n");
 		goto bye;
 	}
@@ -179,27 +167,27 @@
 
 		/* get usb device of this usb interface */
 		sudev = sysfs_get_device_parent(suinf);
-		if(!sudev) {
+		if (!sudev) {
 			err("get parent dev of %s", suinf->name);
 			continue;
-		} 
+		}
 
-		if(check_new(sudev_list, sudev)) {
+		if (check_new(sudev_list, sudev)) {
 			dlist_unshift(sudev_list, sudev);
 		}
 	}
 
 	dlist_for_each_data(sudev_list, sudev, struct sysfs_device) {
-		struct usbip_exported_device *edev; 
+		struct usbip_exported_device *edev;
 
 		edev = usbip_exported_device_new(sudev->path);
-		if(!edev) {
+		if (!edev) {
 			err("usbip_exported_device new");
 			continue;
 		}
 
-		dlist_unshift(driver->edev_list, (void *) edev);
-		driver->ndevs++;
+		dlist_unshift(stub_driver->edev_list, (void *) edev);
+		stub_driver->ndevs++;
 	}
 
 
@@ -210,91 +198,95 @@
 	return 0;
 }
 
-int usbip_stub_refresh_device_list(struct usbip_stub_driver *driver)
+int usbip_stub_refresh_device_list(void)
 {
 	int ret;
 
-	if(driver->edev_list)
-		dlist_destroy(driver->edev_list);
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
 
-	driver->ndevs = 0;
+	stub_driver->ndevs = 0;
 
-	driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
+	stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
 			usbip_exported_device_delete);
-	if(!driver->edev_list) {
+	if (!stub_driver->edev_list) {
 		err("alloc dlist");
 		return -1;
 	}
 
-	ret = refresh_exported_devices(driver);
-	if(ret < 0) 
+	ret = refresh_exported_devices();
+	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-struct usbip_stub_driver *usbip_stub_driver_open(void)
+int usbip_stub_driver_open(void)
 {
 	int ret;
-	struct usbip_stub_driver *driver;
 
-	
-	driver = (struct usbip_stub_driver *) calloc(1, sizeof(*driver));
-	if(!driver) {
-		err("alloc driver");
-		return NULL;
+
+	stub_driver = (struct usbip_stub_driver *) calloc(1, sizeof(*stub_driver));
+	if (!stub_driver) {
+		err("alloc stub_driver");
+		return -1;
 	}
 
-	driver->ndevs = 0;
+	stub_driver->ndevs = 0;
 
-	driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
+	stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
 			usbip_exported_device_delete);
-	if(!driver->edev_list) {
+	if (!stub_driver->edev_list) {
 		err("alloc dlist");
 		goto err;
 	}
 
-	driver->sysfs_driver = open_sysfs_stub_driver();
-	if(!driver->sysfs_driver)
+	stub_driver->sysfs_driver = open_sysfs_stub_driver();
+	if (!stub_driver->sysfs_driver)
 		goto err;
 
-	ret = refresh_exported_devices(driver);
-	if(ret < 0) 
+	ret = refresh_exported_devices();
+	if (ret < 0)
 		goto err;
 
-	return driver;
+	return 0;
 
 
 err:
-	if(driver->sysfs_driver)
-		sysfs_close_driver(driver->sysfs_driver);
-	if(driver->edev_list)
-		dlist_destroy(driver->edev_list);
-	free(driver);
+	if (stub_driver->sysfs_driver)
+		sysfs_close_driver(stub_driver->sysfs_driver);
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
+	free(stub_driver);
 
-	return NULL;
+	stub_driver = NULL;
+	return -1;
 }
 
 
-void usbip_stub_driver_close(struct usbip_stub_driver *driver)
+void usbip_stub_driver_close(void)
 {
-	if(driver->edev_list)
-		dlist_destroy(driver->edev_list);
-	if(driver->sysfs_driver)
-		sysfs_close_driver(driver->sysfs_driver);
-	free(driver);
+	if (!stub_driver)
+		return;
+
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
+	if (stub_driver->sysfs_driver)
+		sysfs_close_driver(stub_driver->sysfs_driver);
+	free(stub_driver);
+
+	stub_driver = NULL;
 }
 
-int usbip_stub_export_device(struct usbip_stub_driver *driver,
-		struct usbip_exported_device *edev, int sockfd)
+int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd)
 {
 	char attrpath[SYSFS_PATH_MAX];
 	struct sysfs_attribute *attr;
 	char sockfd_buff[30];
-	int ret; 
+	int ret;
 
 
-	if(edev->status != SDEV_ST_AVAILABLE) {
+	if (edev->status != SDEV_ST_AVAILABLE) {
 		info("device not available, %s", edev->udev.busid);
 		return -1;
 	}
@@ -307,7 +299,7 @@
 			"usbip_sockfd");
 
 	attr = sysfs_open_attribute(attrpath);
-	if(!attr) {
+	if (!attr) {
 		err("open %s", attrpath);
 		return -1;
 	}
@@ -317,7 +309,7 @@
 	dbg("write: %s", sockfd_buff);
 
 	ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff));
-	if(ret < 0) {
+	if (ret < 0) {
 		err("write sockfd %s to %s", sockfd_buff, attrpath);
 		goto err_write_sockfd;
 	}
@@ -330,15 +322,14 @@
 	return ret;
 }
 
-struct usbip_exported_device *usbip_stub_get_device(struct usbip_stub_driver *driver,
-		int num)
+struct usbip_exported_device *usbip_stub_get_device(int num)
 {
-	struct usbip_exported_device *edev; 
-	struct dlist		*dlist = driver->edev_list;
+	struct usbip_exported_device *edev;
+	struct dlist		*dlist = stub_driver->edev_list;
 	int count = 0;
 
 	dlist_for_each_data(dlist, edev, struct usbip_exported_device) {
-		if(num == count)
+		if (num == count)
 			return edev;
 		else
 			count++ ;
diff -Naur usbip-0.1.4/src/lib/stub_driver.h trunk/src/lib/stub_driver.h
--- usbip-0.1.4/src/lib/stub_driver.h	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/lib/stub_driver.h	2007-05-18 11:10:07.000000000 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_STUB_DRIVER_H
+#define _USBIP_STUB_DRIVER_H
+
+#include "usbip.h"
+
+
+struct usbip_stub_driver {
+	int ndevs;
+	struct sysfs_driver *sysfs_driver;
+
+	struct dlist *edev_list;	/* list of exported device */
+};
+
+struct usbip_exported_device {
+	struct sysfs_device *sudev;
+
+	int32_t status;
+	struct usb_device    udev;
+	struct usb_interface uinf[];
+};
+
+
+extern struct usbip_stub_driver *stub_driver;
+
+int usbip_stub_driver_open(void);
+void usbip_stub_driver_close(void);
+
+int usbip_stub_refresh_device_list(void);
+int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd);
+
+struct usbip_exported_device *usbip_stub_get_device(int num);
+#endif
diff -Naur usbip-0.1.4/src/lib/usbip_common.c trunk/src/lib/usbip_common.c
--- usbip-0.1.4/src/lib/usbip_common.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/lib/usbip_common.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,8 +1,9 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 #include "usbip.h"
+#include "names.h"
 
 int usbip_use_syslog = 0;
 int usbip_use_stderr = 0;
@@ -40,8 +41,8 @@
 
 const char *usbip_status_string(int32_t status)
 {
-	for(int i=0; portst_strings[i].desc != NULL; i++) 
-		if(portst_strings[i].num == status)
+	for (int i=0; portst_strings[i].desc != NULL; i++)
+		if (portst_strings[i].num == status)
 			return portst_strings[i].desc;
 
 	return "Unknown Status";
@@ -49,53 +50,13 @@
 
 const char *usbip_speed_string(int num)
 {
-	for(int i=0; speed_strings[i].speed != NULL; i++) 
-		if(speed_strings[i].num == num)
+	for (int i=0; speed_strings[i].speed != NULL; i++)
+		if (speed_strings[i].num == num)
 			return speed_strings[i].desc;
 
 	return "Unknown Speed";
 }
 
-void pack_uint32_t(int pack, uint32_t *num)
-{
-	uint32_t i;
-
-	if(pack)
-		i = htonl(*num);
-	else
-		i = ntohl(*num);
-
-	*num = i;
-}
-
-void pack_uint16_t(int pack, uint16_t *num)
-{
-	uint16_t i;
-
-	if(pack)
-		i = htons(*num);
-	else
-		i = ntohs(*num);
-
-	*num = i;
-}
-
-void pack_usb_device(int pack, struct usb_device *udev)
-{
-	pack_uint32_t(pack, &udev->busnum);
-	pack_uint32_t(pack, &udev->devnum);
-	pack_uint32_t(pack, &udev->speed );
-
-	pack_uint16_t(pack, &udev->idVendor );
-	pack_uint16_t(pack, &udev->idProduct);
-	pack_uint16_t(pack, &udev->bcdDevice);
-}
-
-void pack_usb_interface(int pack, struct usb_interface *udev)
-{
-	/* uint8_t members need nothing */
-}
-
 
 #define DBG_UDEV_INTEGER(name)\
 	dbg("%-20s = %x", to_string(name), (int) udev->name)
@@ -106,7 +67,7 @@
 void dump_usb_interface(struct usb_interface *uinf)
 {
 	char buff[100];
-	usbip_class_name(buff, sizeof(buff),
+	usbip_names_get_class(buff, sizeof(buff),
 			uinf->bInterfaceClass,
 			uinf->bInterfaceSubClass,
 			uinf->bInterfaceProtocol);
@@ -121,7 +82,7 @@
 	dbg("%-20s = %s", "path",  udev->path);
 	dbg("%-20s = %s", "busid", udev->busid);
 
-	usbip_class_name(buff, sizeof(buff),
+	usbip_names_get_class(buff, sizeof(buff),
 			udev->bDeviceClass,
 			udev->bDeviceSubClass,
 			udev->bDeviceProtocol);
@@ -129,7 +90,7 @@
 
 	DBG_UDEV_INTEGER(bcdDevice);
 
-	usbip_product_name(buff, sizeof(buff),
+	usbip_names_get_product(buff, sizeof(buff),
 			udev->idVendor,
 			udev->idProduct);
 	dbg("%-20s = %s", "Vendor/Product", buff);
@@ -137,7 +98,7 @@
 	DBG_UDEV_INTEGER(bNumConfigurations);
 	DBG_UDEV_INTEGER(bNumInterfaces);
 
-	dbg("%-20s = %s", "speed", 
+	dbg("%-20s = %s", "speed",
 			usbip_speed_string(udev->speed));
 
 	DBG_UDEV_INTEGER(busnum);
@@ -155,19 +116,19 @@
 	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name);
 
 	attr = sysfs_open_attribute(attrpath);
-	if(!attr) {
+	if (!attr) {
 		err("open attr %s", attrpath);
 		return 0;
 	}
 
 	ret = sysfs_read_attribute(attr);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("read attr");
 		goto err;
 	}
 
 	ret = sscanf(attr->value, format, &num);
-	if(ret < 1) {
+	if (ret < 1) {
 		err("sscanf");
 		goto err;
 	}
@@ -189,27 +150,27 @@
 	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, "speed");
 
 	attr = sysfs_open_attribute(attrpath);
-	if(!attr) {
+	if (!attr) {
 		err("open attr");
 		return 0;
 	}
 
 	ret = sysfs_read_attribute(attr);
-	if(ret < 0) {
+	if (ret < 0) {
 		err("read attr");
 		goto err;
 	}
 
 	ret = sscanf(attr->value, "%s\n", speed);
-	if(ret < 1) {
+	if (ret < 1) {
 		err("sscanf");
 		goto err;
 	}
 err:
 	sysfs_close_attribute(attr);
 
-	for(int i=0; speed_strings[i].speed != NULL; i++) {
-		if(!strcmp(speed, speed_strings[i].speed))
+	for (int i=0; speed_strings[i].speed != NULL; i++) {
+		if (!strcmp(speed, speed_strings[i].speed))
 			return speed_strings[i].num;
 	}
 
@@ -217,7 +178,7 @@
 }
 
 #define READ_ATTR(object, type, dev, name, format)\
-	do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while(0)
+	do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0)
 
 
 int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev)
@@ -256,7 +217,7 @@
 	sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);
 
 	sif = sysfs_open_device("usb", busid);
-	if(!sif) {
+	if (!sif) {
 		err("open sif of %s", busid);
 		return -1;
 	}
@@ -270,24 +231,33 @@
 	return 0;
 }
 
+int usbip_names_init(char *f)
+{
+	return names_init(f);
+}
+
+void usbip_names_free()
+{
+	names_free();
+}
 
-void usbip_product_name(char *buff, size_t size, uint16_t vendor, uint16_t product)
+void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product)
 {
 	const char *prod, *vend;
 
 	prod = names_product(vendor, product);
-	if(!prod)
+	if (!prod)
 		prod = "unknown product";
 
 
 	vend = names_vendor(vendor);
-	if(!vend)
+	if (!vend)
 		vend = "unknown vendor";
 
 	snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product);
 }
 
-void usbip_class_name(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol)
+void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol)
 {
 	const char *c, *s, *p;
 
@@ -297,15 +267,15 @@
 	}
 
 	p = names_protocol(class, subclass, protocol);
-	if(!p)
+	if (!p)
 		p = "unknown protocol";
 
 	s = names_subclass(class, subclass);
-	if(!s)
+	if (!s)
 		s = "unknown subclass";
 
 	c = names_class(class);
-	if(!c)
+	if (!c)
 		c = "unknown class";
 
 	snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, class, subclass, protocol);
diff -Naur usbip-0.1.4/src/lib/usbip_common.h trunk/src/lib/usbip_common.h
--- usbip-0.1.4/src/lib/usbip_common.h	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/lib/usbip_common.h	2007-05-18 11:10:07.000000000 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_COMMON_H
+#define _USBIP_COMMON_H
+
+#include <unistd.h>
+#include <stdint.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <sysfs/libsysfs.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#ifndef USBIDS_FILE
+#define USBIDS_FILE "/usr/share/hwdata/usb.ids"
+#endif
+
+extern int usbip_use_syslog;
+extern int usbip_use_stderr;
+extern int usbip_use_debug ;
+
+//#include <linux/usb_ch9.h>
+enum usb_device_speed {
+	USB_SPEED_UNKNOWN = 0,                  /* enumerating */
+	USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */
+	USB_SPEED_HIGH,                         /* usb 2.0 */
+	USB_SPEED_VARIABLE                      /* wireless (usb 2.5) */
+};
+
+/* FIXME: how to sync with drivers/usbip_common.h ? */
+enum usbip_device_status{
+	/* sdev is available. */
+	SDEV_ST_AVAILABLE = 0x01,
+	/* sdev is now used. */
+	SDEV_ST_USED,
+	/* sdev is unusable because of a fatal error. */
+	SDEV_ST_ERROR,
+
+	/* vdev does not connect a remote device. */
+	VDEV_ST_NULL,
+	/* vdev is used, but the USB address is not assigned yet */
+	VDEV_ST_NOTASSIGNED,
+	VDEV_ST_USED,
+	VDEV_ST_ERROR
+};
+
+#define err(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_ERR, "usbip err: %13s:%4d (%-12s) " fmt "\n", \
+			__FILE__, __LINE__, __FUNCTION__,  ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, "usbip err: %13s:%4d (%-12s) " fmt "\n", \
+			__FILE__, __LINE__, __FUNCTION__,  ##args); \
+	} \
+} while (0)
+
+#define notice(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_DEBUG, "usbip: " fmt, ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, "usbip: " fmt "\n",  ##args); \
+	} \
+} while (0)
+
+#define info(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_DEBUG, fmt, ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, fmt "\n",  ##args); \
+	} \
+} while (0)
+
+#define dbg(fmt, args...)	do { \
+	if (usbip_use_debug) { \
+		if (usbip_use_syslog) { \
+			syslog(LOG_DEBUG, "usbip dbg: %13s:%4d (%-12s) " fmt, \
+				__FILE__, __LINE__, __FUNCTION__,  ##args); \
+		} \
+		if (usbip_use_stderr) { \
+			fprintf(stderr, "usbip dbg: %13s:%4d (%-12s) " fmt "\n", \
+				__FILE__, __LINE__, __FUNCTION__,  ##args); \
+		} \
+	} \
+} while (0)
+
+
+#define BUG()	do { err("sorry, it's a bug"); abort(); } while (0)
+
+struct usb_interface {
+	uint8_t bInterfaceClass;
+	uint8_t bInterfaceSubClass;
+	uint8_t bInterfaceProtocol;
+	uint8_t padding;	/* alignment */
+} __attribute__((packed));
+
+
+
+struct usb_device {
+	char path[SYSFS_PATH_MAX];
+	char busid[SYSFS_BUS_ID_SIZE];
+
+	uint32_t busnum;
+	uint32_t devnum;
+	uint32_t speed;
+
+	uint16_t idVendor;
+	uint16_t idProduct;
+	uint16_t bcdDevice;
+
+	uint8_t bDeviceClass;
+	uint8_t bDeviceSubClass;
+	uint8_t bDeviceProtocol;
+	uint8_t bConfigurationValue;
+	uint8_t bNumConfigurations;
+	uint8_t bNumInterfaces;
+} __attribute__((packed));
+
+#define to_string(s)	#s
+
+void dump_usb_interface(struct usb_interface *);
+void dump_usb_device(struct usb_device *);
+int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev);
+int read_attr_value(struct sysfs_device *dev, const char *name, const char *format);
+int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf);
+
+const char *usbip_speed_string(int num);
+const char *usbip_status_string(int32_t status);
+
+int usbip_names_init(char *);
+void usbip_names_free(void);
+void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product);
+void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol);
+
+#endif
diff -Naur usbip-0.1.4/src/lib/usbip.h trunk/src/lib/usbip.h
--- usbip-0.1.4/src/lib/usbip.h	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/lib/usbip.h	2007-05-18 11:10:07.000000000 +0200
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_H
+#define _USBIP_H
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include "usbip_common.h"
+#include "stub_driver.h"
+#include "vhci_driver.h"
+#ifdef DMALLOC
+#include <dmalloc.h>
+#endif
+
+#endif
diff -Naur usbip-0.1.4/src/lib/vhci_driver.c trunk/src/lib/vhci_driver.c
--- usbip-0.1.4/src/lib/vhci_driver.c	2007-05-18 11:10:09.000000000 +0200
+++ trunk/src/lib/vhci_driver.c	2007-05-18 11:10:07.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Takahiro Hirofuchi
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
  */
 
 
@@ -8,55 +8,14 @@
 
 static const char vhci_driver_name[] = "vhci_hcd";
 
+struct usbip_vhci_driver *vhci_driver;
 
-#if 0
-static struct sockaddr_storage *get_sockaddr_s(char *ipaddr, char *ipport, struct sockaddr_storage *ss)
-{
-	struct addrinfo hints, *res;
-	int ret;
-
-	/* kernel api should be changed to be simpler */
-	while(*ipaddr == '0' && *ipaddr != '\0')
-		ipaddr += 1;
-
-	while(*ipport == '0' && *ipport != '\0')
-		ipport += 1;
-
-	bzero(&hints, sizeof(hints));
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_flags    = AI_NUMERICHOST;
-
-	ret = getaddrinfo(ipaddr, ipport, &hints, &res);
-	if(ret) {
-		err("getaddrinfo %s", gai_strerror(ret));
-	}
-
-	if(res->ai_addrlen > sizeof(*ss)) {
-		err("sockaddr too large");
-		freeaddrinfo(res);
-		return NULL;
-	}
-
-	memcpy(ss, res->ai_addr, res->ai_addrlen);
-
-	freeaddrinfo(res);
-
-	return ss;
-}
-#endif
-
-
-
-
-
-
-static struct usbip_imported_device *imported_device_init(struct usbip_vhci_driver *driver, 
-		struct usbip_imported_device *idev, char *busid)
+static struct usbip_imported_device *imported_device_init(struct usbip_imported_device *idev, char *busid)
 {
 	struct sysfs_device *sudev;
 
 	sudev = sysfs_open_device("usb", busid);
-	if(!sudev) {
+	if (!sudev) {
 		err("sysfs_open_device %s", busid);
 		goto err;
 	}
@@ -65,13 +24,13 @@
 
 	/* add class devices of this imported device */
 	struct class_device *cdev;
-	dlist_for_each_data(driver->cdev_list, cdev, struct class_device) {
-		if(!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
+	dlist_for_each_data(vhci_driver->cdev_list, cdev, struct class_device) {
+		if (!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
 			struct class_device *new_cdev;
 
 			/* alloc and copy because dlist is linked from only one list */
 			new_cdev = calloc(1, sizeof(*new_cdev));
-			if(!new_cdev) 
+			if (!new_cdev)
 				goto err;
 
 			memcpy(new_cdev, cdev, sizeof(*new_cdev));
@@ -87,29 +46,29 @@
 
 
 
-static int parse_status(char *value, struct usbip_vhci_driver *driver)
+static int parse_status(char *value)
 {
 	int ret = 0;
 	char *c;
 
-	
-	for(int i = 0; i < driver->nports; i++)
-		bzero(&driver->idev[i], sizeof(struct usbip_imported_device));
+
+	for (int i = 0; i < vhci_driver->nports; i++)
+		bzero(&vhci_driver->idev[i], sizeof(struct usbip_imported_device));
 
 
 	/* skip a header line */
 	c = strchr(value, '\n') + 1;
 
-	while(*c != '\0') {
+	while (*c != '\0') {
 		int port, status, speed, busnum, devnum;
 		unsigned long socket;
 		char lbusid[SYSFS_BUS_ID_SIZE];
 
-		ret = sscanf(c, "%d %d %d %d %d %lx %s\n", 
+		ret = sscanf(c, "%d %d %d %d %d %lx %s\n",
 				&port, &status, &speed, &busnum,
 				&devnum, &socket, lbusid);
 
-		if(ret < 5) {
+		if (ret < 5) {
 			err("scanf %d", ret);
 			BUG();
 		}
@@ -121,7 +80,7 @@
 
 		/* if a device is connected, look at it */
 		{
-			struct usbip_imported_device *idev = &driver->idev[port];
+			struct usbip_imported_device *idev = &vhci_driver->idev[port];
 
 			idev->port	= port;
 			idev->status	= status;
@@ -129,14 +88,14 @@
 			idev->devnum	= devnum;
 
 			idev->cdev_list = dlist_new(sizeof(struct class_device));
-			if(!idev->cdev_list) {
+			if (!idev->cdev_list) {
 				err("init new device");
 				return -1;
 			}
 
-			if(idev->status != VDEV_ST_NULL && idev->status != VDEV_ST_NOTASSIGNED) {
-				idev = imported_device_init(driver, idev, lbusid);
-				if(!idev) {
+			if (idev->status != VDEV_ST_NULL && idev->status != VDEV_ST_NOTASSIGNED) {
+				idev = imported_device_init(idev, lbusid);
+				if (!idev) {
 					err("init new device");
 					return -1;
 				}
@@ -154,7 +113,7 @@
 }
 
 
-static int check_usbip_device(struct usbip_vhci_driver *driver,  struct sysfs_class_device *cdev)
+static int check_usbip_device(struct sysfs_class_device *cdev)
 {
 	char clspath[SYSFS_PATH_MAX];	/* /sys/class/video4linux/video0/device     */
 	char devpath[SYSFS_PATH_MAX];	/* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1  */
@@ -164,18 +123,18 @@
 	snprintf(clspath, sizeof(clspath), "%s/device", cdev->path);
 
 	ret = sysfs_get_link(clspath, devpath, SYSFS_PATH_MAX);
-	if(!ret) {
-		if(!strncmp(devpath, driver->hc_device->path,
-					strlen(driver->hc_device->path))) { 
+	if (!ret) {
+		if (!strncmp(devpath, vhci_driver->hc_device->path,
+					strlen(vhci_driver->hc_device->path))) {
 			/* found usbip device */
 			struct class_device *cdev;
 
-			cdev = calloc(1, sizeof*cdev);
-			if(!cdev) {
+			cdev = calloc(1, sizeof(*cdev));
+			if (!cdev) {
 				err("calloc cdev");
 				return -1;
 			}
-			dlist_unshift(driver->cdev_list, (void*) cdev);
+			dlist_unshift(vhci_driver->cdev_list, (void*) cdev);
 			strncpy(cdev->clspath, clspath, sizeof(cdev->clspath));
 			strncpy(cdev->devpath, devpath, sizeof(cdev->clspath));
 			dbg("  found %s %s", clspath, devpath);
@@ -186,7 +145,7 @@
 }
 
 
-static int search_class_for_usbip_device(struct usbip_vhci_driver *driver, char *cname)
+static int search_class_for_usbip_device(char *cname)
 {
 	struct sysfs_class *class;
 	struct dlist *cdev_list;
@@ -194,7 +153,7 @@
 	int ret = 0;
 
 	class = sysfs_open_class(cname);
-	if(!class) {
+	if (!class) {
 		err("open class");
 		return -1;
 	}
@@ -202,14 +161,14 @@
 	dbg("class %s", class->name);
 
 	cdev_list = sysfs_get_class_devices(class);
-	if(!cdev_list) 
+	if (!cdev_list)
 		/* nothing */
 		goto out;
 
 	dlist_for_each_data(cdev_list, cdev, struct sysfs_class_device) {
 		dbg("   cdev %s", cdev->name);
-		ret = check_usbip_device(driver, cdev);
-		if(ret < 0) 
+		ret = check_usbip_device(cdev);
+		if (ret < 0)
 			goto out;
 	}
 
@@ -220,7 +179,7 @@
 }
 
 
-static int refresh_class_device_list(struct usbip_vhci_driver *driver)
+static int refresh_class_device_list(void)
 {
 	int ret;
 	struct dlist *cname_list;
@@ -228,14 +187,14 @@
 
 	/* search under /sys/class */
 	cname_list = sysfs_open_directory_list("/sys/class");
-	if(!cname_list) {
+	if (!cname_list) {
 		err("open class directory");
 		return -1;
 	}
 
 	dlist_for_each_data(cname_list, cname, char) {
-		ret = search_class_for_usbip_device(driver, cname);
-		if(ret < 0) {
+		ret = search_class_for_usbip_device(cname);
+		if (ret < 0) {
 			sysfs_close_list(cname_list);
 			return -1;
 		}
@@ -244,22 +203,22 @@
 	sysfs_close_list(cname_list);
 
 	/* seach under /sys/block */
-	ret = search_class_for_usbip_device(driver, SYSFS_BLOCK_NAME);
-	if(ret < 0)
+	ret = search_class_for_usbip_device(SYSFS_BLOCK_NAME);
+	if (ret < 0)
 		return -1;
 
 	return 0;
 }
 
 
-static int refresh_imported_device_list(struct usbip_vhci_driver *driver)
+static int refresh_imported_device_list(void)
 {
 	struct sysfs_attribute *attr_status;
 
 
-	attr_status = sysfs_get_device_attr(driver->hc_device, "status");
-	if(!attr_status) {
-		err("get attr %s of %s", "status", driver->hc_device->name);
+	attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+	if (!attr_status) {
+		err("get attr %s of %s", "status", vhci_driver->hc_device->name);
 		return -1;
 	}
 
@@ -268,17 +227,17 @@
 
 	dbg("%s", attr_status->value);
 
-	return parse_status(attr_status->value, driver);
+	return parse_status(attr_status->value);
 }
 
-static int get_nports(struct usbip_vhci_driver *driver)
+static int get_nports(void)
 {
 	int nports = 0;
 	struct sysfs_attribute *attr_status;
 
-	attr_status = sysfs_get_device_attr(driver->hc_device, "status");
-	if(!attr_status) {
-		err("get attr %s of %s", "status", driver->hc_device->name);
+	attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+	if (!attr_status) {
+		err("get attr %s of %s", "status", vhci_driver->hc_device->name);
 		return -1;
 	}
 
@@ -293,7 +252,7 @@
 		/* skip a header line */
 		c = strchr(attr_status->value, '\n') + 1;
 
-		while(*c != '\0') {
+		while (*c != '\0') {
 			/* go to the next line */
 			c = strchr(c, '\n') + 1;
 			nports += 1;
@@ -312,25 +271,25 @@
 	struct dlist *hc_devs;
 
 	int found = 0;
- 
+
         snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/platform/%s/%s",
                                 sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
                                 vhci_driver_name);
- 
+
         sdriver = sysfs_open_driver_path(sdriver_path);
-        if(!sdriver) {
+        if (!sdriver) {
 		info("%s is not found", sdriver_path);
                 info("load vhci-hcd.ko !");
                 return -1;
         }
 
 	hc_devs = sysfs_get_driver_devices(sdriver);
-	if(!hc_devs) {
+	if (!hc_devs) {
 		err("get hc list");
 		goto err;
 	}
 
-	/* only vhci_hcd */
+	/* assume only one vhci_hcd */
 	dlist_for_each_data(hc_devs, hc_dev, struct sysfs_device) {
 		strncpy(hc_busid, hc_dev->bus_id, SYSFS_BUS_ID_SIZE);
 		found = 1;
@@ -339,7 +298,7 @@
 err:
 	sysfs_close_driver(sdriver);
 
-	if(found)
+	if (found)
 		return 0;
 
 	err("not found usbip hc");
@@ -349,110 +308,115 @@
 
 /* ---------------------------------------------------------------------- */
 
-struct usbip_vhci_driver *usbip_vhci_driver_open(void)
+int usbip_vhci_driver_open(void)
 {
 	int ret;
 	char hc_busid[SYSFS_BUS_ID_SIZE];
-	struct usbip_vhci_driver *driver;
-
 
-	driver = (struct usbip_vhci_driver *) calloc(1, sizeof(*driver));
-	if(!driver) {
-		err("alloc driver");
-		return NULL;
+	vhci_driver = (struct usbip_vhci_driver *) calloc(1, sizeof(*vhci_driver));
+	if (!vhci_driver) {
+		err("alloc vhci_driver");
+		return -1;
 	}
 
-	ret = sysfs_get_mnt_path(driver->sysfs_mntpath, SYSFS_PATH_MAX);
-	if(ret < 0) {
+	ret = sysfs_get_mnt_path(vhci_driver->sysfs_mntpath, SYSFS_PATH_MAX);
+	if (ret < 0) {
 		err("sysfs must be mounted");
 		goto err;
 	}
 
-	ret = get_hc_busid(driver->sysfs_mntpath, hc_busid);
-	if(ret < 0)
+	ret = get_hc_busid(vhci_driver->sysfs_mntpath, hc_busid);
+	if (ret < 0)
 		goto err;
 
 	/* will be freed in usbip_driver_close() */
-	driver->hc_device = sysfs_open_device("platform", hc_busid);
-	if(!driver->hc_device) {
-		err("get sysfs driver");
+	vhci_driver->hc_device = sysfs_open_device("platform", hc_busid);
+	if (!vhci_driver->hc_device) {
+		err("get sysfs vhci_driver");
 		goto err;
 	}
 
-	driver->nports = get_nports(driver);
+	vhci_driver->nports = get_nports();
 
-	info("%d ports available\n", driver->nports);
+	info("%d ports available\n", vhci_driver->nports);
 
-	driver->cdev_list = dlist_new(sizeof(struct class_device));
-	if(!driver->cdev_list)
+	vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+	if (!vhci_driver->cdev_list)
 		goto err;
 
-	if(refresh_class_device_list(driver))
+	if (refresh_class_device_list())
 		goto err;
 
-	if(refresh_imported_device_list(driver))
+	if (refresh_imported_device_list())
 		goto err;
 
 
-	return driver;
+	return 0;
 
 
 err:
-	if(driver->cdev_list)
-		dlist_destroy(driver->cdev_list);
-	if(driver->hc_device)
-		sysfs_close_device(driver->hc_device);
-	if(driver)
-		free(driver);
-	return NULL;
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
+	if (vhci_driver->hc_device)
+		sysfs_close_device(vhci_driver->hc_device);
+	if (vhci_driver)
+		free(vhci_driver);
+
+	vhci_driver = NULL;
+	return -1;
 }
 
 
-void usbip_vhci_driver_close(struct usbip_vhci_driver *driver)
+void usbip_vhci_driver_close()
 {
-	if(driver->cdev_list)
-		dlist_destroy(driver->cdev_list);
+	if (!vhci_driver)
+		return;
+
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
 
-	for(int i = 0; i < driver->nports; i++) {
-		if(driver->idev[i].cdev_list)
-			dlist_destroy(driver->idev[i].cdev_list);
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
 	}
 
-	if(driver->hc_device)
-		sysfs_close_device(driver->hc_device);
-	free(driver);
+	if (vhci_driver->hc_device)
+		sysfs_close_device(vhci_driver->hc_device);
+	free(vhci_driver);
+
+	vhci_driver = NULL;
 }
 
 
-int usbip_vhci_refresh_device_list(struct usbip_vhci_driver *driver)
+int usbip_vhci_refresh_device_list(void)
 {
-	if(driver->cdev_list)
-		dlist_destroy(driver->cdev_list);
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
 
 
-	for(int i = 0; i < driver->nports; i++) {
-		if(driver->idev[i].cdev_list)
-			dlist_destroy(driver->idev[i].cdev_list);
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
 	}
 
-	driver->cdev_list = dlist_new(sizeof(struct class_device));
-	if(!driver->cdev_list)
+	vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+	if (!vhci_driver->cdev_list)
 		goto err;
 
-	if(refresh_class_device_list(driver))
+	if (refresh_class_device_list())
 		goto err;
 
-	if(refresh_imported_device_list(driver))
+	if (refresh_imported_device_list())
 		goto err;
 
 	return 0;
 err:
-	if(driver->cdev_list)
-		dlist_destroy(driver->cdev_list);
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
 
-	for(int i = 0; i < driver->nports; i++) {
-		if(driver->idev[i].cdev_list)
-			dlist_destroy(driver->idev[i].cdev_list);
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
 	}
 
 	err("refresh device list");
@@ -460,11 +424,10 @@
 }
 
 
-int usbip_vhci_get_free_port(struct usbip_vhci_driver *driver)
+int usbip_vhci_get_free_port(void)
 {
-
-	for(int i = 0; i < driver->nports; i++) {
-		if(driver->idev[i].status == VDEV_ST_NULL)
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].status == VDEV_ST_NULL)
 			return i;
 	}
 
@@ -472,26 +435,25 @@
 }
 
 
-int usbip_vhci_import_device2(struct usbip_vhci_driver *driver,
-		uint8_t port, int sockfd, uint8_t busnum,
+int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum,
 		uint8_t devnum, uint32_t speed)
 {
 	struct sysfs_attribute *attr_attach;
-	char newvalue[200]; /* what size should be ? */
+	char buff[200]; /* what size should be ? */
 	int ret;
 
-	attr_attach = sysfs_get_device_attr(driver->hc_device, "attach");
-	if(!attr_attach) {
+	attr_attach = sysfs_get_device_attr(vhci_driver->hc_device, "attach");
+	if (!attr_attach) {
 		err("get attach");
 		return -1;
 	}
 
-	snprintf(newvalue, 200, "%u %u %u %u %u",
+	snprintf(buff, sizeof(buff), "%u %u %u %u %u",
 			port, sockfd, busnum, devnum, speed);
-	dbg("writing: %s", newvalue);
+	dbg("writing: %s", buff);
 
-	ret = sysfs_write_attribute(attr_attach, newvalue, strlen(newvalue));
-	if(ret < 0) {
+	ret = sysfs_write_attribute(attr_attach, buff, strlen(buff));
+	if (ret < 0) {
 		err("write to attach failed");
 		return -1;
 	}
@@ -501,39 +463,24 @@
 	return 0;
 }
 
-
-int usbip_vhci_import_device(struct usbip_vhci_driver *driver, uint8_t port,
-		int sockfd, struct usb_device *udev)
-{
-	int ret;
-
-	ret = usbip_vhci_import_device2(driver, port, sockfd, 
-			udev->busnum, udev->devnum, udev->speed);
-	if(ret < 0)
-		err("import device");
-
-	return ret;
-}
-
-
-int usbip_vhci_detach_device(struct usbip_vhci_driver *driver, uint8_t port)
+int usbip_vhci_detach_device(uint8_t port)
 {
 	struct sysfs_attribute  *attr_detach;
-	char newvalue[200]; /* what size should be ? */
+	char buff[200]; /* what size should be ? */
 	int ret;
 
-	attr_detach = sysfs_get_device_attr(driver->hc_device, "detach");
-	if(!attr_detach) {
+	attr_detach = sysfs_get_device_attr(vhci_driver->hc_device, "detach");
+	if (!attr_detach) {
 		err("get detach");
 		return -1;
 	}
 
-	snprintf(newvalue, 200, "%u", port);
+	snprintf(buff, sizeof(buff), "%u", port);
 	dbg("writing to detach");
-	dbg("writing: %s", newvalue);
+	dbg("writing: %s", buff);
 
-	ret = sysfs_write_attribute(attr_detach, newvalue, strlen(newvalue));
-	if(ret < 0) {
+	ret = sysfs_write_attribute(attr_detach, buff, strlen(buff));
+	if (ret < 0) {
 		err("write to detach failed");
 		return -1;
 	}
@@ -542,5 +489,3 @@
 
 	return 0;
 }
-
-
diff -Naur usbip-0.1.4/src/lib/vhci_driver.h trunk/src/lib/vhci_driver.h
--- usbip-0.1.4/src/lib/vhci_driver.h	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/lib/vhci_driver.h	2007-05-18 11:10:07.000000000 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _VHCI_DRIVER_H
+#define _VHCI_DRIVER_H
+
+#include "usbip.h"
+
+
+
+#define MAXNPORT 128
+
+struct class_device {
+	char clspath[SYSFS_PATH_MAX];
+	char devpath[SYSFS_PATH_MAX];
+};
+
+struct usbip_imported_device {
+	uint8_t port;
+	uint32_t status;
+
+	uint8_t busnum;
+	uint8_t devnum;
+
+
+	struct dlist *cdev_list;	/* list of class device */
+	struct usb_device udev;
+};
+
+struct usbip_vhci_driver {
+	char sysfs_mntpath[SYSFS_PATH_MAX];
+	struct sysfs_device *hc_device; /* /sys/devices/platform/vhci_hcd */
+
+	struct dlist *cdev_list;	/* list of class device */
+
+	int nports;
+	struct usbip_imported_device idev[MAXNPORT];
+};
+
+
+extern struct usbip_vhci_driver *vhci_driver;
+
+int usbip_vhci_driver_open(void);
+void usbip_vhci_driver_close(void);
+
+int  usbip_vhci_refresh_device_list(void);
+
+
+int usbip_vhci_get_free_port(void);
+int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum,
+		uint8_t devnum, uint32_t speed);
+int usbip_vhci_detach_device(uint8_t port);
+#endif
diff -Naur usbip-0.1.4/src/ltmain.sh trunk/src/ltmain.sh
--- usbip-0.1.4/src/ltmain.sh	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/ltmain.sh	1970-01-01 01:00:00.000000000 +0100
@@ -1,6871 +0,0 @@
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun configure.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program 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 program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-basename="s,^.*/,,g"
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
-
-# The name of this program:
-progname=`echo "$progpath" | $SED $basename`
-modename="$progname"
-
-# Global variables:
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION="1.5.22 Debian 1.5.22-4"
-TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
-
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes.
-if test -n "${ZSH_VERSION+set}" ; then
-  setopt NO_GLOB_SUBST
-fi
-
-# Check that we have a working $echo.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
-  # Yippee, $echo works!
-  :
-else
-  # Restart under the correct shell, and then maybe $echo will work.
-  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit $EXIT_SUCCESS
-fi
-
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed="${SED}"' -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
-    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
-  SP2NL='tr \040 \012'
-  NL2SP='tr \015\012 \040\040'
-  ;;
- *) # EBCDIC based system
-  SP2NL='tr \100 \n'
-  NL2SP='tr \r\n \100\100'
-  ;;
-esac
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-if test "${LC_ALL+set}" = set; then
-  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
-fi
-if test "${LANG+set}" = set; then
-  save_LANG="$LANG"; LANG=C; export LANG
-fi
-
-# Make sure IFS has a sensible default
-lt_nl='
-'
-IFS=" 	$lt_nl"
-
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-  $echo "$modename: not configured to build any kind of library" 1>&2
-  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit $EXIT_FAILURE
-fi
-
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-duplicate_deps=no
-preserve_args=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-
-#####################################
-# Shell function definitions:
-# This seems to be the best place for them
-
-# func_mktempdir [string]
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible.  If
-# given, STRING is the basename for that directory.
-func_mktempdir ()
-{
-    my_template="${TMPDIR-/tmp}/${1-$progname}"
-
-    if test "$run" = ":"; then
-      # Return a directory name, but don't create it in dry-run mode
-      my_tmpdir="${my_template}-$$"
-    else
-
-      # If mktemp works, use that first and foremost
-      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
-
-      if test ! -d "$my_tmpdir"; then
-	# Failing that, at least try and use $RANDOM to avoid a race
-	my_tmpdir="${my_template}-${RANDOM-0}$$"
-
-	save_mktempdir_umask=`umask`
-	umask 0077
-	$mkdir "$my_tmpdir"
-	umask $save_mktempdir_umask
-      fi
-
-      # If we're not in dry-run mode, bomb out on failure
-      test -d "$my_tmpdir" || {
-        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
-	exit $EXIT_FAILURE
-      }
-    fi
-
-    $echo "X$my_tmpdir" | $Xsed
-}
-
-
-# func_win32_libid arg
-# return the library type of file 'arg'
-#
-# Need a lot of goo to handle *both* DLLs and import libs
-# Has to be a shell function in order to 'eat' the argument
-# that is supplied when $file_magic_command is called.
-func_win32_libid ()
-{
-  win32_libid_type="unknown"
-  win32_fileres=`file -L $1 2>/dev/null`
-  case $win32_fileres in
-  *ar\ archive\ import\ library*) # definitely import
-    win32_libid_type="x86 archive import"
-    ;;
-  *ar\ archive*) # could be an import, or static
-    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
-      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
-      win32_nmres=`eval $NM -f posix -A $1 | \
-	$SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
-      case $win32_nmres in
-      import*)  win32_libid_type="x86 archive import";;
-      *)        win32_libid_type="x86 archive static";;
-      esac
-    fi
-    ;;
-  *DLL*)
-    win32_libid_type="x86 DLL"
-    ;;
-  *executable*) # but shell scripts are "executable" too...
-    case $win32_fileres in
-    *MS\ Windows\ PE\ Intel*)
-      win32_libid_type="x86 DLL"
-      ;;
-    esac
-    ;;
-  esac
-  $echo $win32_libid_type
-}
-
-
-# func_infer_tag arg
-# Infer tagged configuration to use if any are available and
-# if one wasn't chosen via the "--tag" command line option.
-# Only attempt this if the compiler in the base compile
-# command doesn't match the default compiler.
-# arg is usually of the form 'gcc ...'
-func_infer_tag ()
-{
-    if test -n "$available_tags" && test -z "$tagname"; then
-      CC_quoted=
-      for arg in $CC; do
-	case $arg in
-	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	CC_quoted="$CC_quoted $arg"
-      done
-      case $@ in
-      # Blanks in the command may have been stripped by the calling shell,
-      # but not from the CC environment variable when configure was run.
-      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
-      # Blanks at the start of $base_compile will cause this to fail
-      # if we don't check for them as well.
-      *)
-	for z in $available_tags; do
-	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
-	    # Evaluate the configuration.
-	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
-	    CC_quoted=
-	    for arg in $CC; do
-	    # Double-quote args containing other shell metacharacters.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    CC_quoted="$CC_quoted $arg"
-	  done
-	    case "$@ " in
-	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
-	      # The compiler in the base compile command matches
-	      # the one in the tagged configuration.
-	      # Assume this is the tagged configuration we want.
-	      tagname=$z
-	      break
-	      ;;
-	    esac
-	  fi
-	done
-	# If $tagname still isn't set, then no tagged configuration
-	# was found and let the user know that the "--tag" command
-	# line option must be used.
-	if test -z "$tagname"; then
-	  $echo "$modename: unable to infer tagged configuration"
-	  $echo "$modename: specify a tag with \`--tag'" 1>&2
-	  exit $EXIT_FAILURE
-#        else
-#          $echo "$modename: using $tagname tagged configuration"
-	fi
-	;;
-      esac
-    fi
-}
-
-
-# func_extract_an_archive dir oldlib
-func_extract_an_archive ()
-{
-    f_ex_an_ar_dir="$1"; shift
-    f_ex_an_ar_oldlib="$1"
-
-    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
-    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
-    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
-     :
-    else
-      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
-      exit $EXIT_FAILURE
-    fi
-}
-
-# func_extract_archives gentop oldlib ...
-func_extract_archives ()
-{
-    my_gentop="$1"; shift
-    my_oldlibs=${1+"$@"}
-    my_oldobjs=""
-    my_xlib=""
-    my_xabs=""
-    my_xdir=""
-    my_status=""
-
-    $show "${rm}r $my_gentop"
-    $run ${rm}r "$my_gentop"
-    $show "$mkdir $my_gentop"
-    $run $mkdir "$my_gentop"
-    my_status=$?
-    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
-      exit $my_status
-    fi
-
-    for my_xlib in $my_oldlibs; do
-      # Extract the objects.
-      case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
-	*) my_xabs=`pwd`"/$my_xlib" ;;
-      esac
-      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
-      my_xdir="$my_gentop/$my_xlib"
-
-      $show "${rm}r $my_xdir"
-      $run ${rm}r "$my_xdir"
-      $show "$mkdir $my_xdir"
-      $run $mkdir "$my_xdir"
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
-	exit $exit_status
-      fi
-      case $host in
-      *-darwin*)
-	$show "Extracting $my_xabs"
-	# Do not bother doing anything if just a dry run
-	if test -z "$run"; then
-	  darwin_orig_dir=`pwd`
-	  cd $my_xdir || exit $?
-	  darwin_archive=$my_xabs
-	  darwin_curdir=`pwd`
-	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
-	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
-	  if test -n "$darwin_arches"; then 
-	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
-	    darwin_arch=
-	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches ; do
-	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
-	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
-	      cd "$darwin_curdir"
-	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
-	    done # $darwin_arches
-      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
-	    darwin_file=
-	    darwin_files=
-	    for darwin_file in $darwin_filelist; do
-	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
-	      lipo -create -output "$darwin_file" $darwin_files
-	    done # $darwin_filelist
-	    ${rm}r unfat-$$
-	    cd "$darwin_orig_dir"
-	  else
-	    cd "$darwin_orig_dir"
- 	    func_extract_an_archive "$my_xdir" "$my_xabs"
-	  fi # $darwin_arches
-	fi # $run
-	;;
-      *)
-        func_extract_an_archive "$my_xdir" "$my_xabs"
-        ;;
-      esac
-      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
-    done
-    func_extract_archives_result="$my_oldobjs"
-}
-# End of Shell function definitions
-#####################################
-
-# Darwin sucks
-eval std_shrext=\"$shrext_cmds\"
-
-disable_libs=no
-
-# Parse our command line options once, thoroughly.
-while test "$#" -gt 0
-do
-  arg="$1"
-  shift
-
-  case $arg in
-  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) optarg= ;;
-  esac
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$prev"; then
-    case $prev in
-    execute_dlfiles)
-      execute_dlfiles="$execute_dlfiles $arg"
-      ;;
-    tag)
-      tagname="$arg"
-      preserve_args="${preserve_args}=$arg"
-
-      # Check whether tagname contains only valid characters
-      case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-	$echo "$progname: invalid tag name: $tagname" 1>&2
-	exit $EXIT_FAILURE
-	;;
-      esac
-
-      case $tagname in
-      CC)
-	# Don't test for the "default" C tag, as we know, it's there, but
-	# not specially marked.
-	;;
-      *)
-	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
-	  taglist="$taglist $tagname"
-	  # Evaluate the configuration.
-	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
-	else
-	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
-	fi
-	;;
-      esac
-      ;;
-    *)
-      eval "$prev=\$arg"
-      ;;
-    esac
-
-    prev=
-    prevopt=
-    continue
-  fi
-
-  # Have we seen a non-optional argument yet?
-  case $arg in
-  --help)
-    show_help=yes
-    ;;
-
-  --version)
-    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
-    $echo
-    $echo "Copyright (C) 2005  Free Software Foundation, Inc."
-    $echo "This is free software; see the source for copying conditions.  There is NO"
-    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-    exit $?
-    ;;
-
-  --config)
-    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
-    # Now print the configurations for the tags.
-    for tagname in $taglist; do
-      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
-    done
-    exit $?
-    ;;
-
-  --debug)
-    $echo "$progname: enabling shell trace mode"
-    set -x
-    preserve_args="$preserve_args $arg"
-    ;;
-
-  --dry-run | -n)
-    run=:
-    ;;
-
-  --features)
-    $echo "host: $host"
-    if test "$build_libtool_libs" = yes; then
-      $echo "enable shared libraries"
-    else
-      $echo "disable shared libraries"
-    fi
-    if test "$build_old_libs" = yes; then
-      $echo "enable static libraries"
-    else
-      $echo "disable static libraries"
-    fi
-    exit $?
-    ;;
-
-  --finish) mode="finish" ;;
-
-  --mode) prevopt="--mode" prev=mode ;;
-  --mode=*) mode="$optarg" ;;
-
-  --preserve-dup-deps) duplicate_deps="yes" ;;
-
-  --quiet | --silent)
-    show=:
-    preserve_args="$preserve_args $arg"
-    ;;
-
-  --tag)
-    prevopt="--tag"
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
-  --tag=*)
-    set tag "$optarg" ${1+"$@"}
-    shift
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
-
-  -dlopen)
-    prevopt="-dlopen"
-    prev=execute_dlfiles
-    ;;
-
-  -*)
-    $echo "$modename: unrecognized option \`$arg'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
-    ;;
-
-  *)
-    nonopt="$arg"
-    break
-    ;;
-  esac
-done
-
-if test -n "$prevopt"; then
-  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
-  $echo "$help" 1>&2
-  exit $EXIT_FAILURE
-fi
-
-case $disable_libs in
-no) 
-  ;;
-shared)
-  build_libtool_libs=no
-  build_old_libs=yes
-  ;;
-static)
-  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
-  ;;
-esac
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-if test -z "$show_help"; then
-
-  # Infer the operation mode.
-  if test -z "$mode"; then
-    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
-    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
-    case $nonopt in
-    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
-      mode=link
-      for arg
-      do
-	case $arg in
-	-c)
-	   mode=compile
-	   break
-	   ;;
-	esac
-      done
-      ;;
-    *db | *dbx | *strace | *truss)
-      mode=execute
-      ;;
-    *install*|cp|mv)
-      mode=install
-      ;;
-    *rm)
-      mode=uninstall
-      ;;
-    *)
-      # If we have no mode, but dlfiles were specified, then do execute mode.
-      test -n "$execute_dlfiles" && mode=execute
-
-      # Just use the default operation mode.
-      if test -z "$mode"; then
-	if test -n "$nonopt"; then
-	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
-	else
-	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
-	fi
-      fi
-      ;;
-    esac
-  fi
-
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
-  fi
-
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$modename --help --mode=$mode' for more information."
-
-  # These modes are in order of execution frequency so that they run quickly.
-  case $mode in
-  # libtool compile mode
-  compile)
-    modename="$modename: compile"
-    # Get the compilation command and the source file.
-    base_compile=
-    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
-    suppress_opt=yes
-    suppress_output=
-    arg_mode=normal
-    libobj=
-    later=
-
-    for arg
-    do
-      case $arg_mode in
-      arg  )
-	# do not "continue".  Instead, add this to base_compile
-	lastarg="$arg"
-	arg_mode=normal
-	;;
-
-      target )
-	libobj="$arg"
-	arg_mode=normal
-	continue
-	;;
-
-      normal )
-	# Accept any command-line options.
-	case $arg in
-	-o)
-	  if test -n "$libobj" ; then
-	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  arg_mode=target
-	  continue
-	  ;;
-
-	-static | -prefer-pic | -prefer-non-pic)
-	  later="$later $arg"
-	  continue
-	  ;;
-
-	-no-suppress)
-	  suppress_opt=no
-	  continue
-	  ;;
-
-	-Xcompiler)
-	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
-	  continue      #  The current "srcfile" will either be retained or
-	  ;;            #  replaced later.  I would guess that would be a bug.
-
-	-Wc,*)
-	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
-	  lastarg=
-	  save_ifs="$IFS"; IFS=','
- 	  for arg in $args; do
-	    IFS="$save_ifs"
-
-	    # Double-quote args containing other shell metacharacters.
-	    # Many Bourne shells cannot handle close brackets correctly
-	    # in scan sets, so we specify it separately.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    lastarg="$lastarg $arg"
-	  done
-	  IFS="$save_ifs"
-	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
-
-	  # Add the arguments to base_compile.
-	  base_compile="$base_compile $lastarg"
-	  continue
-	  ;;
-
-	* )
-	  # Accept the current argument as the source file.
-	  # The previous "srcfile" becomes the current argument.
-	  #
-	  lastarg="$srcfile"
-	  srcfile="$arg"
-	  ;;
-	esac  #  case $arg
-	;;
-      esac    #  case $arg_mode
-
-      # Aesthetically quote the previous argument.
-      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
-
-      case $lastarg in
-      # Double-quote args containing other shell metacharacters.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, and some SunOS ksh mistreat backslash-escaping
-      # in scan sets (worked around with variable expansion),
-      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
-      # at all, so we specify them separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	lastarg="\"$lastarg\""
-	;;
-      esac
-
-      base_compile="$base_compile $lastarg"
-    done # for arg
-
-    case $arg_mode in
-    arg)
-      $echo "$modename: you must specify an argument for -Xcompile"
-      exit $EXIT_FAILURE
-      ;;
-    target)
-      $echo "$modename: you must specify a target with \`-o'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *)
-      # Get the name of the library object.
-      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
-      ;;
-    esac
-
-    # Recognize several different file suffixes.
-    # If the user specifies -o file.o, it is replaced with file.lo
-    xform='[cCFSifmso]'
-    case $libobj in
-    *.ada) xform=ada ;;
-    *.adb) xform=adb ;;
-    *.ads) xform=ads ;;
-    *.asm) xform=asm ;;
-    *.c++) xform=c++ ;;
-    *.cc) xform=cc ;;
-    *.ii) xform=ii ;;
-    *.class) xform=class ;;
-    *.cpp) xform=cpp ;;
-    *.cxx) xform=cxx ;;
-    *.f90) xform=f90 ;;
-    *.for) xform=for ;;
-    *.java) xform=java ;;
-    esac
-
-    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
-
-    case $libobj in
-    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
-    *)
-      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    esac
-
-    func_infer_tag $base_compile
-
-    for arg in $later; do
-      case $arg in
-      -static)
-	build_old_libs=yes
-	continue
-	;;
-
-      -prefer-pic)
-	pic_mode=yes
-	continue
-	;;
-
-      -prefer-non-pic)
-	pic_mode=no
-	continue
-	;;
-      esac
-    done
-
-    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
-    case $qlibobj in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qlibobj="\"$qlibobj\"" ;;
-    esac
-    test "X$libobj" != "X$qlibobj" \
-	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
-	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
-    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$xdir" = "X$obj"; then
-      xdir=
-    else
-      xdir=$xdir/
-    fi
-    lobj=${xdir}$objdir/$objname
-
-    if test -z "$base_compile"; then
-      $echo "$modename: you must specify a compilation command" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    # Delete any leftover library objects.
-    if test "$build_old_libs" = yes; then
-      removelist="$obj $lobj $libobj ${libobj}T"
-    else
-      removelist="$lobj $libobj ${libobj}T"
-    fi
-
-    $run $rm $removelist
-    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
-
-    # On Cygwin there's no "real" PIC flag so we must build both object types
-    case $host_os in
-    cygwin* | mingw* | pw32* | os2*)
-      pic_mode=default
-      ;;
-    esac
-    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
-      # non-PIC code in shared libraries is not supported
-      pic_mode=default
-    fi
-
-    # Calculate the filename of the output object if compiler does
-    # not support -o with -c
-    if test "$compiler_c_o" = no; then
-      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
-      lockfile="$output_obj.lock"
-      removelist="$removelist $output_obj $lockfile"
-      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
-    else
-      output_obj=
-      need_locks=no
-      lockfile=
-    fi
-
-    # Lock this critical section if it is needed
-    # We use this script file to make the link, it avoids creating a new file
-    if test "$need_locks" = yes; then
-      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
-	$show "Waiting for $lockfile to be removed"
-	sleep 2
-      done
-    elif test "$need_locks" = warn; then
-      if test -f "$lockfile"; then
-	$echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-      $echo "$srcfile" > "$lockfile"
-    fi
-
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
-    fi
-    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
-    case $qsrcfile in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-      qsrcfile="\"$qsrcfile\"" ;;
-    esac
-
-    $run $rm "$libobj" "${libobj}T"
-
-    # Create a libtool object file (analogous to a ".la" file),
-    # but don't create it if we're doing a dry run.
-    test -z "$run" && cat > ${libobj}T <<EOF
-# $libobj - a libtool object file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# Name of the PIC object.
-EOF
-
-    # Only build a PIC object if we are building libtool libraries.
-    if test "$build_libtool_libs" = yes; then
-      # Without this assignment, base_compile gets emptied.
-      fbsd_hideous_sh_bug=$base_compile
-
-      if test "$pic_mode" != no; then
-	command="$base_compile $qsrcfile $pic_flag"
-      else
-	# Don't build PIC code
-	command="$base_compile $qsrcfile"
-      fi
-
-      if test ! -d "${xdir}$objdir"; then
-	$show "$mkdir ${xdir}$objdir"
-	$run $mkdir ${xdir}$objdir
-	exit_status=$?
-	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
-	  exit $exit_status
-	fi
-      fi
-
-      if test -z "$output_obj"; then
-	# Place PIC objects in $objdir
-	command="$command -o $lobj"
-      fi
-
-      $run $rm "$lobj" "$output_obj"
-
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-	test -n "$output_obj" && $run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-
-      if test "$need_locks" = warn &&
-	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-
-      # Just move the object if needed, then go on to compile the next one
-      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
-	$show "$mv $output_obj $lobj"
-	if $run $mv $output_obj $lobj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-
-      # Append the name of the PIC object to the libtool object file.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object='$objdir/$objname'
-
-EOF
-
-      # Allow error messages only from the first compilation.
-      if test "$suppress_opt" = yes; then
-        suppress_output=' >/dev/null 2>&1'
-      fi
-    else
-      # No PIC object so indicate it doesn't exist in the libtool
-      # object file.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object=none
-
-EOF
-    fi
-
-    # Only build a position-dependent object if we build old libraries.
-    if test "$build_old_libs" = yes; then
-      if test "$pic_mode" != yes; then
-	# Don't build PIC code
-	command="$base_compile $qsrcfile"
-      else
-	command="$base_compile $qsrcfile $pic_flag"
-      fi
-      if test "$compiler_c_o" = yes; then
-	command="$command -o $obj"
-      fi
-
-      # Suppress compiler output if we already did a PIC compilation.
-      command="$command$suppress_output"
-      $run $rm "$obj" "$output_obj"
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-
-      if test "$need_locks" = warn &&
-	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-
-      # Just move the object if needed
-      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
-	$show "$mv $output_obj $obj"
-	if $run $mv $output_obj $obj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object='$objname'
-
-EOF
-    else
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object=none
-
-EOF
-    fi
-
-    $run $mv "${libobj}T" "${libobj}"
-
-    # Unlock the critical section if it was locked
-    if test "$need_locks" != no; then
-      $run $rm "$lockfile"
-    fi
-
-    exit $EXIT_SUCCESS
-    ;;
-
-  # libtool link mode
-  link | relink)
-    modename="$modename: link"
-    case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-      # It is impossible to link a dll without this setting, and
-      # we shouldn't force the makefile maintainer to figure out
-      # which system we are compiling for in order to pass an extra
-      # flag for every libtool invocation.
-      # allow_undefined=no
-
-      # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll which has undefined symbols, in which case not
-      # even a static library is built.  For now, we need to specify
-      # -no-undefined on the libtool link line when we can be certain
-      # that all symbols are satisfied, otherwise we get a static library.
-      allow_undefined=yes
-      ;;
-    *)
-      allow_undefined=yes
-      ;;
-    esac
-    libtool_args="$nonopt"
-    base_compile="$nonopt $@"
-    compile_command="$nonopt"
-    finalize_command="$nonopt"
-
-    compile_rpath=
-    finalize_rpath=
-    compile_shlibpath=
-    finalize_shlibpath=
-    convenience=
-    old_convenience=
-    deplibs=
-    old_deplibs=
-    compiler_flags=
-    linker_flags=
-    dllsearchpath=
-    lib_search_path=`pwd`
-    inst_prefix_dir=
-
-    avoid_version=no
-    dlfiles=
-    dlprefiles=
-    dlself=no
-    export_dynamic=no
-    export_symbols=
-    export_symbols_regex=
-    generated=
-    libobjs=
-    ltlibs=
-    module=no
-    no_install=no
-    objs=
-    non_pic_objects=
-    notinst_path= # paths that contain not-installed libtool libraries
-    precious_files_regex=
-    prefer_static_libs=no
-    preload=no
-    prev=
-    prevarg=
-    release=
-    rpath=
-    xrpath=
-    perm_rpath=
-    temp_rpath=
-    thread_safe=no
-    vinfo=
-    vinfo_number=no
-
-    func_infer_tag $base_compile
-
-    # We need to know -static, to get the right output filenames.
-    for arg
-    do
-      case $arg in
-      -all-static | -static)
-	if test "X$arg" = "X-all-static"; then
-	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
-	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
-	  fi
-	  if test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=yes
-	else
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=built
-	fi
-	build_libtool_libs=no
-	build_old_libs=yes
-	break
-	;;
-      esac
-    done
-
-    # See if our shared archives depend on static archives.
-    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
-
-    # Go through the arguments, transforming them on the way.
-    while test "$#" -gt 0; do
-      arg="$1"
-      shift
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
-	;;
-      *) qarg=$arg ;;
-      esac
-      libtool_args="$libtool_args $qarg"
-
-      # If the previous option needs an argument, assign it.
-      if test -n "$prev"; then
-	case $prev in
-	output)
-	  compile_command="$compile_command @OUTPUT@"
-	  finalize_command="$finalize_command @OUTPUT@"
-	  ;;
-	esac
-
-	case $prev in
-	dlfiles|dlprefiles)
-	  if test "$preload" = no; then
-	    # Add the symbol object into the linking commands.
-	    compile_command="$compile_command @SYMFILE@"
-	    finalize_command="$finalize_command @SYMFILE@"
-	    preload=yes
-	  fi
-	  case $arg in
-	  *.la | *.lo) ;;  # We handle these cases below.
-	  force)
-	    if test "$dlself" = no; then
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  self)
-	    if test "$prev" = dlprefiles; then
-	      dlself=yes
-	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
-	      dlself=yes
-	    else
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  *)
-	    if test "$prev" = dlfiles; then
-	      dlfiles="$dlfiles $arg"
-	    else
-	      dlprefiles="$dlprefiles $arg"
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  esac
-	  ;;
-	expsyms)
-	  export_symbols="$arg"
-	  if test ! -f "$arg"; then
-	    $echo "$modename: symbol file \`$arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  prev=
-	  continue
-	  ;;
-	expsyms_regex)
-	  export_symbols_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	inst_prefix)
-	  inst_prefix_dir="$arg"
-	  prev=
-	  continue
-	  ;;
-	precious_regex)
-	  precious_files_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	release)
-	  release="-$arg"
-	  prev=
-	  continue
-	  ;;
-	objectlist)
-	  if test -f "$arg"; then
-	    save_arg=$arg
-	    moreargs=
-	    for fil in `cat $save_arg`
-	    do
-#	      moreargs="$moreargs $fil"
-	      arg=$fil
-	      # A libtool-controlled object.
-
-	      # Check to see that this really is a libtool object.
-	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		pic_object=
-		non_pic_object=
-
-		# Read the .lo file
-		# If there is no directory component, then add one.
-		case $arg in
-		*/* | *\\*) . $arg ;;
-		*) . ./$arg ;;
-		esac
-
-		if test -z "$pic_object" || \
-		   test -z "$non_pic_object" ||
-		   test "$pic_object" = none && \
-		   test "$non_pic_object" = none; then
-		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-		  exit $EXIT_FAILURE
-		fi
-
-		# Extract subdirectory from the argument.
-		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		if test "X$xdir" = "X$arg"; then
-		  xdir=
-		else
-		  xdir="$xdir/"
-		fi
-
-		if test "$pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  pic_object="$xdir$pic_object"
-
-		  if test "$prev" = dlfiles; then
-		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		      dlfiles="$dlfiles $pic_object"
-		      prev=
-		      continue
-		    else
-		      # If libtool objects are unsupported, then we need to preload.
-		      prev=dlprefiles
-		    fi
-		  fi
-
-		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test "$prev" = dlprefiles; then
-		    # Preload the old-style object.
-		    dlprefiles="$dlprefiles $pic_object"
-		    prev=
-		  fi
-
-		  # A PIC object.
-		  libobjs="$libobjs $pic_object"
-		  arg="$pic_object"
-		fi
-
-		# Non-PIC object.
-		if test "$non_pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  non_pic_object="$xdir$non_pic_object"
-
-		  # A standard non-PIC object
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		  if test -z "$pic_object" || test "$pic_object" = none ; then
-		    arg="$non_pic_object"
-		  fi
-		else
-		  # If the PIC object exists, use it instead.
-		  # $xdir was prepended to $pic_object above.
-		  non_pic_object="$pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      else
-		# Only an error if not doing a dry-run.
-		if test -z "$run"; then
-		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-		  exit $EXIT_FAILURE
-		else
-		  # Dry-run case.
-
-		  # Extract subdirectory from the argument.
-		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		  if test "X$xdir" = "X$arg"; then
-		    xdir=
-		  else
-		    xdir="$xdir/"
-		  fi
-
-		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-		  libobjs="$libobjs $pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      fi
-	    done
-	  else
-	    $echo "$modename: link input file \`$save_arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  arg=$save_arg
-	  prev=
-	  continue
-	  ;;
-	rpath | xrpath)
-	  # We need an absolute path.
-	  case $arg in
-	  [\\/]* | [A-Za-z]:[\\/]*) ;;
-	  *)
-	    $echo "$modename: only absolute run-paths are allowed" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	  if test "$prev" = rpath; then
-	    case "$rpath " in
-	    *" $arg "*) ;;
-	    *) rpath="$rpath $arg" ;;
-	    esac
-	  else
-	    case "$xrpath " in
-	    *" $arg "*) ;;
-	    *) xrpath="$xrpath $arg" ;;
-	    esac
-	  fi
-	  prev=
-	  continue
-	  ;;
-	xcompiler)
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
-	  continue
-	  ;;
-	xlinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $wl$qarg"
-	  prev=
-	  compile_command="$compile_command $wl$qarg"
-	  finalize_command="$finalize_command $wl$qarg"
-	  continue
-	  ;;
-	xcclinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
-	  continue
-	  ;;
-	shrext)
-  	  shrext_cmds="$arg"
-	  prev=
-	  continue
-	  ;;
-	darwin_framework|darwin_framework_skip)
-	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  prev=
-	  continue
-	  ;;
-	*)
-	  eval "$prev=\"\$arg\""
-	  prev=
-	  continue
-	  ;;
-	esac
-      fi # test -n "$prev"
-
-      prevarg="$arg"
-
-      case $arg in
-      -all-static)
-	if test -n "$link_static_flag"; then
-	  compile_command="$compile_command $link_static_flag"
-	  finalize_command="$finalize_command $link_static_flag"
-	fi
-	continue
-	;;
-
-      -allow-undefined)
-	# FIXME: remove this flag sometime in the future.
-	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
-	continue
-	;;
-
-      -avoid-version)
-	avoid_version=yes
-	continue
-	;;
-
-      -dlopen)
-	prev=dlfiles
-	continue
-	;;
-
-      -dlpreopen)
-	prev=dlprefiles
-	continue
-	;;
-
-      -export-dynamic)
-	export_dynamic=yes
-	continue
-	;;
-
-      -export-symbols | -export-symbols-regex)
-	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	  $echo "$modename: more than one -exported-symbols argument is not allowed"
-	  exit $EXIT_FAILURE
-	fi
-	if test "X$arg" = "X-export-symbols"; then
-	  prev=expsyms
-	else
-	  prev=expsyms_regex
-	fi
-	continue
-	;;
-
-      -framework|-arch|-isysroot)
-	case " $CC " in
-	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
-		prev=darwin_framework_skip ;;
-	  *) compiler_flags="$compiler_flags $arg"
-	     prev=darwin_framework ;;
-	esac
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
-
-      -inst-prefix-dir)
-	prev=inst_prefix
-	continue
-	;;
-
-      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
-      # so, if we see these flags be careful not to treat them like -L
-      -L[A-Z][A-Z]*:*)
-	case $with_gcc/$host in
-	no/*-*-irix* | /*-*-irix*)
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  ;;
-	esac
-	continue
-	;;
-
-      -L*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  absdir=`cd "$dir" && pwd`
-	  if test -z "$absdir"; then
-	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	    absdir="$dir"
-	    notinst_path="$notinst_path $dir"
-	  fi
-	  dir="$absdir"
-	  ;;
-	esac
-	case "$deplibs " in
-	*" -L$dir "*) ;;
-	*)
-	  deplibs="$deplibs -L$dir"
-	  lib_search_path="$lib_search_path $dir"
-	  ;;
-	esac
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$dir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$dir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
-	continue
-	;;
-
-      -l*)
-	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
-	    # These systems don't actually have a C or math library (as such)
-	    continue
-	    ;;
-	  *-*-os2*)
-	    # These systems don't actually have a C library (as such)
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C and math libraries are in the System framework
-	    deplibs="$deplibs -framework System"
-	    continue
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  esac
-	elif test "X$arg" = "X-lc_r"; then
-	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	   # Do not include libc_r directly, use -pthread flag.
-	   continue
-	   ;;
-	 esac
-	fi
-	deplibs="$deplibs $arg"
-	continue
-	;;
-
-      # Tru64 UNIX uses -model [arg] to determine the layout of C++
-      # classes, name mangling, and exception handling.
-      -model)
-	compile_command="$compile_command $arg"
-	compiler_flags="$compiler_flags $arg"
-	finalize_command="$finalize_command $arg"
-	prev=xcompiler
-	continue
-	;;
-
-     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
-	compiler_flags="$compiler_flags $arg"
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
-
-      -module)
-	module=yes
-	continue
-	;;
-
-      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
-      # -r[0-9][0-9]* specifies the processor on the SGI compiler
-      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
-      # +DA*, +DD* enable 64-bit mode on the HP compiler
-      # -q* pass through compiler args for the IBM compiler
-      # -m* pass through architecture-specific compiler args for GCC
-      # -m*, -t[45]*, -txscale* pass through architecture-specific
-      # compiler args for GCC
-      # -pg pass through profiling flag for GCC
-      # @file GCC response files
-      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
-      -t[45]*|-txscale*|@*)
-
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-        compile_command="$compile_command $arg"
-        finalize_command="$finalize_command $arg"
-        compiler_flags="$compiler_flags $arg"
-        continue
-        ;;
-
-      -shrext)
-	prev=shrext
-	continue
-	;;
-
-      -no-fast-install)
-	fast_install=no
-	continue
-	;;
-
-      -no-install)
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  # The PATH hackery in wrapper scripts is required on Windows
-	  # in order for the loader to find any dlls it needs.
-	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
-	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
-	  fast_install=no
-	  ;;
-	*) no_install=yes ;;
-	esac
-	continue
-	;;
-
-      -no-undefined)
-	allow_undefined=no
-	continue
-	;;
-
-      -objectlist)
-	prev=objectlist
-	continue
-	;;
-
-      -o) prev=output ;;
-
-      -precious-files-regex)
-	prev=precious_regex
-	continue
-	;;
-
-      -release)
-	prev=release
-	continue
-	;;
-
-      -rpath)
-	prev=rpath
-	continue
-	;;
-
-      -R)
-	prev=xrpath
-	continue
-	;;
-
-      -R*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  $echo "$modename: only absolute run-paths are allowed" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-	case "$xrpath " in
-	*" $dir "*) ;;
-	*) xrpath="$xrpath $dir" ;;
-	esac
-	continue
-	;;
-
-      -static)
-	# The effects of -static are defined in a previous loop.
-	# We used to do the same as -all-static on platforms that
-	# didn't have a PIC flag, but the assumption that the effects
-	# would be equivalent was wrong.  It would break on at least
-	# Digital Unix and AIX.
-	continue
-	;;
-
-      -thread-safe)
-	thread_safe=yes
-	continue
-	;;
-
-      -version-info)
-	prev=vinfo
-	continue
-	;;
-      -version-number)
-	prev=vinfo
-	vinfo_number=yes
-	continue
-	;;
-
-      -Wc,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
-
-      -Wl,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $wl$flag"
-	  linker_flags="$linker_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
-
-      -Xcompiler)
-	prev=xcompiler
-	continue
-	;;
-
-      -Xlinker)
-	prev=xlinker
-	continue
-	;;
-
-      -XCClinker)
-	prev=xcclinker
-	continue
-	;;
-
-      # Some other compiler flag.
-      -* | +*)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-
-      *.$objext)
-	# A standard object.
-	objs="$objs $arg"
-	;;
-
-      *.lo)
-	# A libtool-controlled object.
-
-	# Check to see that this really is a libtool object.
-	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  pic_object=
-	  non_pic_object=
-
-	  # Read the .lo file
-	  # If there is no directory component, then add one.
-	  case $arg in
-	  */* | *\\*) . $arg ;;
-	  *) . ./$arg ;;
-	  esac
-
-	  if test -z "$pic_object" || \
-	     test -z "$non_pic_object" ||
-	     test "$pic_object" = none && \
-	     test "$non_pic_object" = none; then
-	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-
-	  # Extract subdirectory from the argument.
-	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	  if test "X$xdir" = "X$arg"; then
-	    xdir=
- 	  else
-	    xdir="$xdir/"
-	  fi
-
-	  if test "$pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    pic_object="$xdir$pic_object"
-
-	    if test "$prev" = dlfiles; then
-	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		dlfiles="$dlfiles $pic_object"
-		prev=
-		continue
-	      else
-		# If libtool objects are unsupported, then we need to preload.
-		prev=dlprefiles
-	      fi
-	    fi
-
-	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test "$prev" = dlprefiles; then
-	      # Preload the old-style object.
-	      dlprefiles="$dlprefiles $pic_object"
-	      prev=
-	    fi
-
-	    # A PIC object.
-	    libobjs="$libobjs $pic_object"
-	    arg="$pic_object"
-	  fi
-
-	  # Non-PIC object.
-	  if test "$non_pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    non_pic_object="$xdir$non_pic_object"
-
-	    # A standard non-PIC object
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	    if test -z "$pic_object" || test "$pic_object" = none ; then
-	      arg="$non_pic_object"
-	    fi
-	  else
-	    # If the PIC object exists, use it instead.
-	    # $xdir was prepended to $pic_object above.
-	    non_pic_object="$pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	else
-	  # Only an error if not doing a dry-run.
-	  if test -z "$run"; then
-	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-	    exit $EXIT_FAILURE
-	  else
-	    # Dry-run case.
-
-	    # Extract subdirectory from the argument.
-	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	    if test "X$xdir" = "X$arg"; then
-	      xdir=
-	    else
-	      xdir="$xdir/"
-	    fi
-
-	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-	    libobjs="$libobjs $pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	fi
-	;;
-
-      *.$libext)
-	# An archive.
-	deplibs="$deplibs $arg"
-	old_deplibs="$old_deplibs $arg"
-	continue
-	;;
-
-      *.la)
-	# A libtool-controlled library.
-
-	if test "$prev" = dlfiles; then
-	  # This library was specified with -dlopen.
-	  dlfiles="$dlfiles $arg"
-	  prev=
-	elif test "$prev" = dlprefiles; then
-	  # The library was specified with -dlpreopen.
-	  dlprefiles="$dlprefiles $arg"
-	  prev=
-	else
-	  deplibs="$deplibs $arg"
-	fi
-	continue
-	;;
-
-      # Some other compiler argument.
-      *)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-      esac # arg
-
-      # Now actually substitute the argument into the commands.
-      if test -n "$arg"; then
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-      fi
-    done # argument parsing loop
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
-      eval arg=\"$export_dynamic_flag_spec\"
-      compile_command="$compile_command $arg"
-      finalize_command="$finalize_command $arg"
-    fi
-
-    oldlibs=
-    # calculate the name of the file, without its directory
-    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
-    libobjs_save="$libobjs"
-
-    if test -n "$shlibpath_var"; then
-      # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
-    else
-      shlib_search_path=
-    fi
-    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
-    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
-
-    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$output_objdir" = "X$output"; then
-      output_objdir="$objdir"
-    else
-      output_objdir="$output_objdir/$objdir"
-    fi
-    # Create the object directory.
-    if test ! -d "$output_objdir"; then
-      $show "$mkdir $output_objdir"
-      $run $mkdir $output_objdir
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
-	exit $exit_status
-      fi
-    fi
-
-    # Determine the type of output
-    case $output in
-    "")
-      $echo "$modename: you must specify an output file" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *.$libext) linkmode=oldlib ;;
-    *.lo | *.$objext) linkmode=obj ;;
-    *.la) linkmode=lib ;;
-    *) linkmode=prog ;; # Anything else should be a program.
-    esac
-
-    case $host in
-    *cygwin* | *mingw* | *pw32*)
-      # don't eliminate duplications in $postdeps and $predeps
-      duplicate_compiler_generated_deps=yes
-      ;;
-    *)
-      duplicate_compiler_generated_deps=$duplicate_deps
-      ;;
-    esac
-    specialdeplibs=
-
-    libs=
-    # Find all interdependent deplibs by searching for libraries
-    # that are linked more than once (e.g. -la -lb -la)
-    for deplib in $deplibs; do
-      if test "X$duplicate_deps" = "Xyes" ; then
-	case "$libs " in
-	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	esac
-      fi
-      libs="$libs $deplib"
-    done
-
-    if test "$linkmode" = lib; then
-      libs="$predeps $libs $compiler_lib_search_path $postdeps"
-
-      # Compute libraries that are listed more than once in $predeps
-      # $postdeps and mark them as special (i.e., whose duplicates are
-      # not to be eliminated).
-      pre_post_deps=
-      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
-	for pre_post_dep in $predeps $postdeps; do
-	  case "$pre_post_deps " in
-	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
-	  esac
-	  pre_post_deps="$pre_post_deps $pre_post_dep"
-	done
-      fi
-      pre_post_deps=
-    fi
-
-    deplibs=
-    newdependency_libs=
-    newlib_search_path=
-    need_relink=no # whether we're linking any uninstalled libtool libraries
-    notinst_deplibs= # not-installed libtool libraries
-    case $linkmode in
-    lib)
-	passes="conv link"
-	for file in $dlfiles $dlprefiles; do
-	  case $file in
-	  *.la) ;;
-	  *)
-	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	done
-	;;
-    prog)
-	compile_deplibs=
-	finalize_deplibs=
-	alldeplibs=no
-	newdlfiles=
-	newdlprefiles=
-	passes="conv scan dlopen dlpreopen link"
-	;;
-    *)  passes="conv"
-	;;
-    esac
-    for pass in $passes; do
-      if test "$linkmode,$pass" = "lib,link" ||
-	 test "$linkmode,$pass" = "prog,scan"; then
-	libs="$deplibs"
-	deplibs=
-      fi
-      if test "$linkmode" = prog; then
-	case $pass in
-	dlopen) libs="$dlfiles" ;;
-	dlpreopen) libs="$dlprefiles" ;;
-	link)
-	  libs="$deplibs %DEPLIBS%"
-	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-	  ;;
-	esac
-      fi
-      if test "$pass" = dlopen; then
-	# Collect dlpreopened libraries
-	save_deplibs="$deplibs"
-	deplibs=
-      fi
-      for deplib in $libs; do
-	lib=
-	found=no
-	case $deplib in
-	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
-	  if test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$deplib $compile_deplibs"
-	    finalize_deplibs="$deplib $finalize_deplibs"
-	  else
-	    compiler_flags="$compiler_flags $deplib"
-	  fi
-	  continue
-	  ;;
-	-l*)
-	  if test "$linkmode" != lib && test "$linkmode" != prog; then
-	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
-	    continue
-	  fi
-	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
-	  for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
-	    for search_ext in .la $std_shrext .so .a; do
-	      # Search the libtool library
-	      lib="$searchdir/lib${name}${search_ext}"
-	      if test -f "$lib"; then
-		if test "$search_ext" = ".la"; then
-		  found=yes
-		else
-		  found=no
-		fi
-		break 2
-	      fi
-	    done
-	  done
-	  if test "$found" != yes; then
-	    # deplib doesn't seem to be a libtool library
-	    if test "$linkmode,$pass" = "prog,link"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
-	  else # deplib is a libtool library
-	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
-	    # We need to do some special things here, and not later.
-	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	      case " $predeps $postdeps " in
-	      *" $deplib "*)
-		if (${SED} -e '2q' $lib |
-                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		  library_names=
-		  old_library=
-		  case $lib in
-		  */* | *\\*) . $lib ;;
-		  *) . ./$lib ;;
-		  esac
-		  for l in $old_library $library_names; do
-		    ll="$l"
-		  done
-		  if test "X$ll" = "X$old_library" ; then # only static version available
-		    found=no
-		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-		    test "X$ladir" = "X$lib" && ladir="."
-		    lib=$ladir/$old_library
-		    if test "$linkmode,$pass" = "prog,link"; then
-		      compile_deplibs="$deplib $compile_deplibs"
-		      finalize_deplibs="$deplib $finalize_deplibs"
-		    else
-		      deplibs="$deplib $deplibs"
-		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-		    fi
-		    continue
-		  fi
-		fi
-	        ;;
-	      *) ;;
-	      esac
-	    fi
-	  fi
-	  ;; # -l
-	-L*)
-	  case $linkmode in
-	  lib)
-	    deplibs="$deplib $deplibs"
-	    test "$pass" = conv && continue
-	    newdependency_libs="$deplib $newdependency_libs"
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  prog)
-	    if test "$pass" = conv; then
-	      deplibs="$deplib $deplibs"
-	      continue
-	    fi
-	    if test "$pass" = scan; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  *)
-	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
-	    ;;
-	  esac # linkmode
-	  continue
-	  ;; # -L
-	-R*)
-	  if test "$pass" = link; then
-	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
-	    # Make sure the xrpath contains only unique directories.
-	    case "$xrpath " in
-	    *" $dir "*) ;;
-	    *) xrpath="$xrpath $dir" ;;
-	    esac
-	  fi
-	  deplibs="$deplib $deplibs"
-	  continue
-	  ;;
-	*.la) lib="$deplib" ;;
-	*.$libext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	    continue
-	  fi
-	  case $linkmode in
-	  lib)
-	    valid_a_lib=no
-	    case $deplibs_check_method in
-	      match_pattern*)
-		set dummy $deplibs_check_method
-	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-		if eval $echo \"$deplib\" 2>/dev/null \
-		    | $SED 10q \
-		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		  valid_a_lib=yes
-		fi
-		;;
-	      pass_all)
-		valid_a_lib=yes
-		;;
-            esac
-	    if test "$valid_a_lib" != yes; then
-	      $echo
-	      $echo "*** Warning: Trying to link with static lib archive $deplib."
-	      $echo "*** I have the capability to make that library automatically link in when"
-	      $echo "*** you link to this library.  But I can only do this if you have a"
-	      $echo "*** shared version of the library, which you do not appear to have"
-	      $echo "*** because the file extensions .$libext of this argument makes me believe"
-	      $echo "*** that it is just a static archive that I should not used here."
-	    else
-	      $echo
-	      $echo "*** Warning: Linking the shared library $output against the"
-	      $echo "*** static library $deplib is not portable!"
-	      deplibs="$deplib $deplibs"
-	    fi
-	    continue
-	    ;;
-	  prog)
-	    if test "$pass" != link; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    continue
-	    ;;
-	  esac # linkmode
-	  ;; # *.$libext
-	*.lo | *.$objext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	  elif test "$linkmode" = prog; then
-	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
-	      # If there is no dlopen support or we're linking statically,
-	      # we need to preload.
-	      newdlprefiles="$newdlprefiles $deplib"
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      newdlfiles="$newdlfiles $deplib"
-	    fi
-	  fi
-	  continue
-	  ;;
-	%DEPLIBS%)
-	  alldeplibs=yes
-	  continue
-	  ;;
-	esac # case $deplib
-	if test "$found" = yes || test -f "$lib"; then :
-	else
-	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$ladir" = "X$lib" && ladir="."
-
-	dlname=
-	dlopen=
-	dlpreopen=
-	libdir=
-	library_names=
-	old_library=
-	# If the library was installed with an old release of libtool,
-	# it will not redefine variables installed, or shouldnotlink
-	installed=yes
-	shouldnotlink=no
-	avoidtemprpath=
-
-
-	# Read the .la file
-	case $lib in
-	*/* | *\\*) . $lib ;;
-	*) . ./$lib ;;
-	esac
-
-	if test "$linkmode,$pass" = "lib,link" ||
-	   test "$linkmode,$pass" = "prog,scan" ||
-	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
-	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
-	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
-	fi
-
-	if test "$pass" = conv; then
-	  # Only check for convenience libraries
-	  deplibs="$lib $deplibs"
-	  if test -z "$libdir"; then
-	    if test -z "$old_library"; then
-	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	      exit $EXIT_FAILURE
-	    fi
-	    # It is a libtool convenience library, so add in its objects.
-	    convenience="$convenience $ladir/$objdir/$old_library"
-	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
-	    tmp_libs=
-	    for deplib in $dependency_libs; do
-	      deplibs="$deplib $deplibs"
-              if test "X$duplicate_deps" = "Xyes" ; then
-	        case "$tmp_libs " in
-	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	        esac
-              fi
-	      tmp_libs="$tmp_libs $deplib"
-	    done
-	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
-	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  continue
-	fi # $pass = conv
-
-
-	# Get the name of the library we link against.
-	linklib=
-	for l in $old_library $library_names; do
-	  linklib="$l"
-	done
-	if test -z "$linklib"; then
-	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# This library was specified with -dlopen.
-	if test "$pass" = dlopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  if test -z "$dlname" ||
-	     test "$dlopen_support" != yes ||
-	     test "$build_libtool_libs" = no; then
-	    # If there is no dlname, no dlopen support or we're linking
-	    # statically, we need to preload.  We also need to preload any
-	    # dependent libraries so libltdl's deplib preloader doesn't
-	    # bomb out in the load deplibs phase.
-	    dlprefiles="$dlprefiles $lib $dependency_libs"
-	  else
-	    newdlfiles="$newdlfiles $lib"
-	  fi
-	  continue
-	fi # $pass = dlopen
-
-	# We need an absolute path.
-	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
-	*)
-	  abs_ladir=`cd "$ladir" && pwd`
-	  if test -z "$abs_ladir"; then
-	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
-	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
-	    abs_ladir="$ladir"
-	  fi
-	  ;;
-	esac
-	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-
-	# Find the relevant object directory and library name.
-	if test "X$installed" = Xyes; then
-	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    libdir="$abs_ladir"
-	  else
-	    dir="$libdir"
-	    absdir="$libdir"
-	  fi
-	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
-	else
-	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  else
-	    dir="$ladir/$objdir"
-	    absdir="$abs_ladir/$objdir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  fi
-	fi # $installed = yes
-	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-
-	# This library was specified with -dlpreopen.
-	if test "$pass" = dlpreopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
-	  # are required to link).
-	  if test -n "$old_library"; then
-	    newdlprefiles="$newdlprefiles $dir/$old_library"
-	  # Otherwise, use the dlname, so that lt_dlopen finds it.
-	  elif test -n "$dlname"; then
-	    newdlprefiles="$newdlprefiles $dir/$dlname"
-	  else
-	    newdlprefiles="$newdlprefiles $dir/$linklib"
-	  fi
-	fi # $pass = dlpreopen
-
-	if test -z "$libdir"; then
-	  # Link the convenience library
-	  if test "$linkmode" = lib; then
-	    deplibs="$dir/$old_library $deplibs"
-	  elif test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$dir/$old_library $compile_deplibs"
-	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
-	  else
-	    deplibs="$lib $deplibs" # used for prog,scan pass
-	  fi
-	  continue
-	fi
-
-
-	if test "$linkmode" = prog && test "$pass" != link; then
-	  newlib_search_path="$newlib_search_path $ladir"
-	  deplibs="$lib $deplibs"
-
-	  linkalldeplibs=no
-	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
-	     test "$build_libtool_libs" = no; then
-	    linkalldeplibs=yes
-	  fi
-
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    case $deplib in
-	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
-	    esac
-	    # Need to link against all dependency_libs?
-	    if test "$linkalldeplibs" = yes; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      # Need to hardcode shared library paths
-	      # or/and link against static libraries
-	      newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done # for deplib
-	  continue
-	fi # $linkmode = prog...
-
-	if test "$linkmode,$pass" = "prog,link"; then
-	  if test -n "$library_names" &&
-	     { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
-	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
-	      # Make sure the rpath contains only unique directories.
-	      case "$temp_rpath " in
-	      *" $dir "*) ;;
-	      *" $absdir "*) ;;
-	      *) temp_rpath="$temp_rpath $absdir" ;;
-	      esac
-	    fi
-
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi # $linkmode,$pass = prog,link...
-
-	  if test "$alldeplibs" = yes &&
-	     { test "$deplibs_check_method" = pass_all ||
-	       { test "$build_libtool_libs" = yes &&
-		 test -n "$library_names"; }; }; then
-	    # We only need to search for static libraries
-	    continue
-	  fi
-	fi
-
-	link_static=no # Whether the deplib will be linked statically
-	use_static_libs=$prefer_static_libs
-	if test "$use_static_libs" = built && test "$installed" = yes ; then
-	  use_static_libs=no
-	fi
-	if test -n "$library_names" &&
-	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
-	  if test "$installed" = no; then
-	    notinst_deplibs="$notinst_deplibs $lib"
-	    need_relink=yes
-	  fi
-	  # This is a shared library
-
-	  # Warn about portability, can't link against -module's on
-	  # some systems (darwin)
-	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
-	    $echo
-	    if test "$linkmode" = prog; then
-	      $echo "*** Warning: Linking the executable $output against the loadable module"
-	    else
-	      $echo "*** Warning: Linking the shared library $output against the loadable module"
-	    fi
-	    $echo "*** $linklib is not portable!"
-	  fi
-	  if test "$linkmode" = lib &&
-	     test "$hardcode_into_libs" = yes; then
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi
-
-	  if test -n "$old_archive_from_expsyms_cmds"; then
-	    # figure out the soname
-	    set dummy $library_names
-	    realname="$2"
-	    shift; shift
-	    libname=`eval \\$echo \"$libname_spec\"`
-	    # use dlname if we got it. it's perfectly good, no?
-	    if test -n "$dlname"; then
-	      soname="$dlname"
-	    elif test -n "$soname_spec"; then
-	      # bleh windows
-	      case $host in
-	      *cygwin* | mingw*)
-		major=`expr $current - $age`
-		versuffix="-$major"
-		;;
-	      esac
-	      eval soname=\"$soname_spec\"
-	    else
-	      soname="$realname"
-	    fi
-
-	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot="$soname"
-	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
-	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
-
-	    # If the library has no export list, then create one now
-	    if test -f "$output_objdir/$soname-def"; then :
-	    else
-	      $show "extracting exported symbol list from \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$extract_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
-
-	    # Create $newlib
-	    if test -f "$output_objdir/$newlib"; then :; else
-	      $show "generating import library for \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$old_archive_from_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
-	    # make sure the library variables are pointing to the new library
-	    dir=$output_objdir
-	    linklib=$newlib
-	  fi # test -n "$old_archive_from_expsyms_cmds"
-
-	  if test "$linkmode" = prog || test "$mode" != relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    lib_linked=yes
-	    case $hardcode_action in
-	    immediate | unsupported)
-	      if test "$hardcode_direct" = no; then
-		add="$dir/$linklib"
-		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
-		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
-		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir="-L$dir" ;;
-		  *-*-darwin* )
-		    # if the lib is a module then we can not link against
-		    # it, someone is ignoring the new warnings I added
-		    if /usr/bin/file -L $add 2> /dev/null |
-                      $EGREP ": [^:]* bundle" >/dev/null ; then
-		      $echo "** Warning, lib $linklib is a module, not a shared library"
-		      if test -z "$old_library" ; then
-		        $echo
-		        $echo "** And there doesn't seem to be a static archive available"
-		        $echo "** The link will probably fail, sorry"
-		      else
-		        add="$dir/$old_library"
-		      fi
-		    fi
-		esac
-	      elif test "$hardcode_minus_L" = no; then
-		case $host in
-		*-*-sunos*) add_shlibpath="$dir" ;;
-		esac
-		add_dir="-L$dir"
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = no; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    relink)
-	      if test "$hardcode_direct" = yes; then
-		add="$dir/$linklib"
-	      elif test "$hardcode_minus_L" = yes; then
-		add_dir="-L$dir"
-		# Try looking first in the location we're being installed to.
-		if test -n "$inst_prefix_dir"; then
-		  case $libdir in
-		    [\\/]*)
-		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		      ;;
-		  esac
-		fi
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = yes; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    *) lib_linked=no ;;
-	    esac
-
-	    if test "$lib_linked" != yes; then
-	      $echo "$modename: configuration error: unsupported hardcode properties"
-	      exit $EXIT_FAILURE
-	    fi
-
-	    if test -n "$add_shlibpath"; then
-	      case :$compile_shlibpath: in
-	      *":$add_shlibpath:"*) ;;
-	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
-	      esac
-	    fi
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
-	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	      if test "$hardcode_direct" != yes && \
-		 test "$hardcode_minus_L" != yes && \
-		 test "$hardcode_shlibpath_var" = yes; then
-		case :$finalize_shlibpath: in
-		*":$libdir:"*) ;;
-		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-		esac
-	      fi
-	    fi
-	  fi
-
-	  if test "$linkmode" = prog || test "$mode" = relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    # Finalize command for both is simple: just hardcode it.
-	    if test "$hardcode_direct" = yes; then
-	      add="$libdir/$linklib"
-	    elif test "$hardcode_minus_L" = yes; then
-	      add_dir="-L$libdir"
-	      add="-l$name"
-	    elif test "$hardcode_shlibpath_var" = yes; then
-	      case :$finalize_shlibpath: in
-	      *":$libdir:"*) ;;
-	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-	      esac
-	      add="-l$name"
-	    elif test "$hardcode_automatic" = yes; then
-	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
-	        add="$inst_prefix_dir$libdir/$linklib"
-	      else
-	        add="$libdir/$linklib"
-	      fi
-	    else
-	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir="-L$libdir"
-	      # Try looking first in the location we're being installed to.
-	      if test -n "$inst_prefix_dir"; then
-		case $libdir in
-		  [\\/]*)
-		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		    ;;
-		esac
-	      fi
-	      add="-l$name"
-	    fi
-
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
-	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	    fi
-	  fi
-	elif test "$linkmode" = prog; then
-	  # Here we assume that one of hardcode_direct or hardcode_minus_L
-	  # is not unsupported.  This is valid on all known static and
-	  # shared platforms.
-	  if test "$hardcode_direct" != unsupported; then
-	    test -n "$old_library" && linklib="$old_library"
-	    compile_deplibs="$dir/$linklib $compile_deplibs"
-	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
-	  else
-	    compile_deplibs="-l$name -L$dir $compile_deplibs"
-	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
-	  fi
-	elif test "$build_libtool_libs" = yes; then
-	  # Not a shared library
-	  if test "$deplibs_check_method" != pass_all; then
-	    # We're trying link a shared library against a static one
-	    # but the system doesn't support it.
-
-	    # Just print a warning and add the library to dependency_libs so
-	    # that the program can be linked against the static library.
-	    $echo
-	    $echo "*** Warning: This system can not link to static lib archive $lib."
-	    $echo "*** I have the capability to make that library automatically link in when"
-	    $echo "*** you link to this library.  But I can only do this if you have a"
-	    $echo "*** shared version of the library, which you do not appear to have."
-	    if test "$module" = yes; then
-	      $echo "*** But as you try to build a module library, libtool will still create "
-	      $echo "*** a static module, that should work as long as the dlopening application"
-	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
-	      if test -z "$global_symbol_pipe"; then
-		$echo
-		$echo "*** However, this would only work if libtool was able to extract symbol"
-		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-		$echo "*** not find such a program.  So, this module is probably useless."
-		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	      fi
-	      if test "$build_old_libs" = no; then
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  else
-	    deplibs="$dir/$old_library $deplibs"
-	    link_static=yes
-	  fi
-	fi # link shared/static library?
-
-	if test "$linkmode" = lib; then
-	  if test -n "$dependency_libs" &&
-	     { test "$hardcode_into_libs" != yes ||
-	       test "$build_old_libs" = yes ||
-	       test "$link_static" = yes; }; then
-	    # Extract -R from dependency_libs
-	    temp_deplibs=
-	    for libdir in $dependency_libs; do
-	      case $libdir in
-	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
-		   case " $xrpath " in
-		   *" $temp_xrpath "*) ;;
-		   *) xrpath="$xrpath $temp_xrpath";;
-		   esac;;
-	      *) temp_deplibs="$temp_deplibs $libdir";;
-	      esac
-	    done
-	    dependency_libs="$temp_deplibs"
-	  fi
-
-	  newlib_search_path="$newlib_search_path $absdir"
-	  # Link against this library
-	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
-	  # ... and its dependency_libs
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    newdependency_libs="$deplib $newdependency_libs"
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done
-
-	  if test "$link_all_deplibs" != no; then
-	    # Add the search paths of all dependency libraries
-	    for deplib in $dependency_libs; do
-	      case $deplib in
-	      -L*) path="$deplib" ;;
-	      *.la)
-		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
-		test "X$dir" = "X$deplib" && dir="."
-		# We need an absolute path.
-		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
-		*)
-		  absdir=`cd "$dir" && pwd`
-		  if test -z "$absdir"; then
-		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
-		    absdir="$dir"
-		  fi
-		  ;;
-		esac
-		if grep "^installed=no" $deplib > /dev/null; then
-		  path="$absdir/$objdir"
-		else
-		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		  if test -z "$libdir"; then
-		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-		    exit $EXIT_FAILURE
-		  fi
-		  if test "$absdir" != "$libdir"; then
-		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
-		  fi
-		  path="$absdir"
-		fi
-		depdepl=
-		case $host in
-		*-*-darwin*)
-		  # we do not want to link against static libs,
-		  # but need to link against shared
-		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names" ; then
-		    for tmp in $deplibrary_names ; do
-		      depdepl=$tmp
-		    done
-		    if test -f "$path/$depdepl" ; then
-		      depdepl="$path/$depdepl"
-		    fi
-		    # do not add paths which are already there
-		    case " $newlib_search_path " in
-		    *" $path "*) ;;
-		    *) newlib_search_path="$newlib_search_path $path";;
-		    esac
-		  fi
-		  path=""
-		  ;;
-		*)
-		  path="-L$path"
-		  ;;
-		esac
-		;;
-	      -l*)
-		case $host in
-		*-*-darwin*)
-		  # Again, we only want to link against shared libraries
-		  eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
-		  for tmp in $newlib_search_path ; do
-		    if test -f "$tmp/lib$tmp_libs.dylib" ; then
-		      eval depdepl="$tmp/lib$tmp_libs.dylib"
-		      break
-		    fi
-		  done
-		  path=""
-		  ;;
-		*) continue ;;
-		esac
-		;;
-	      *) continue ;;
-	      esac
-	      case " $deplibs " in
-	      *" $path "*) ;;
-	      *) deplibs="$path $deplibs" ;;
-	      esac
-	      case " $deplibs " in
-	      *" $depdepl "*) ;;
-	      *) deplibs="$depdepl $deplibs" ;;
-	      esac
-	    done
-	  fi # link_all_deplibs != no
-	fi # linkmode = lib
-      done # for deplib in $libs
-      dependency_libs="$newdependency_libs"
-      if test "$pass" = dlpreopen; then
-	# Link the dlpreopened libraries before other libraries
-	for deplib in $save_deplibs; do
-	  deplibs="$deplib $deplibs"
-	done
-      fi
-      if test "$pass" != dlopen; then
-	if test "$pass" != conv; then
-	  # Make sure lib_search_path contains only unique directories.
-	  lib_search_path=
-	  for dir in $newlib_search_path; do
-	    case "$lib_search_path " in
-	    *" $dir "*) ;;
-	    *) lib_search_path="$lib_search_path $dir" ;;
-	    esac
-	  done
-	  newlib_search_path=
-	fi
-
-	if test "$linkmode,$pass" != "prog,link"; then
-	  vars="deplibs"
-	else
-	  vars="compile_deplibs finalize_deplibs"
-	fi
-	for var in $vars dependency_libs; do
-	  # Add libraries to $var in reverse order
-	  eval tmp_libs=\"\$$var\"
-	  new_libs=
-	  for deplib in $tmp_libs; do
-	    # FIXME: Pedantically, this is the right thing to do, so
-	    #        that some nasty dependency loop isn't accidentally
-	    #        broken:
-	    #new_libs="$deplib $new_libs"
-	    # Pragmatically, this seems to cause very few problems in
-	    # practice:
-	    case $deplib in
-	    -L*) new_libs="$deplib $new_libs" ;;
-	    -R*) ;;
-	    *)
-	      # And here is the reason: when a library appears more
-	      # than once as an explicit dependence of a library, or
-	      # is implicitly linked in more than once by the
-	      # compiler, it is considered special, and multiple
-	      # occurrences thereof are not removed.  Compare this
-	      # with having the same library being listed as a
-	      # dependency of multiple other libraries: in this case,
-	      # we know (pedantically, we assume) the library does not
-	      # need to be listed more than once, so we keep only the
-	      # last copy.  This is not always right, but it is rare
-	      # enough that we require users that really mean to play
-	      # such unportable linking tricks to link the library
-	      # using -Wl,-lname, so that libtool does not consider it
-	      # for duplicate removal.
-	      case " $specialdeplibs " in
-	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
-	      *)
-		case " $new_libs " in
-		*" $deplib "*) ;;
-		*) new_libs="$deplib $new_libs" ;;
-		esac
-		;;
-	      esac
-	      ;;
-	    esac
-	  done
-	  tmp_libs=
-	  for deplib in $new_libs; do
-	    case $deplib in
-	    -L*)
-	      case " $tmp_libs " in
-	      *" $deplib "*) ;;
-	      *) tmp_libs="$tmp_libs $deplib" ;;
-	      esac
-	      ;;
-	    *) tmp_libs="$tmp_libs $deplib" ;;
-	    esac
-	  done
-	  eval $var=\"$tmp_libs\"
-	done # for var
-      fi
-      # Last step: remove runtime libs from dependency_libs
-      # (they stay in deplibs)
-      tmp_libs=
-      for i in $dependency_libs ; do
-	case " $predeps $postdeps $compiler_lib_search_path " in
-	*" $i "*)
-	  i=""
-	  ;;
-	esac
-	if test -n "$i" ; then
-	  tmp_libs="$tmp_libs $i"
-	fi
-      done
-      dependency_libs=$tmp_libs
-    done # for pass
-    if test "$linkmode" = prog; then
-      dlfiles="$newdlfiles"
-      dlprefiles="$newdlprefiles"
-    fi
-
-    case $linkmode in
-    oldlib)
-      if test -n "$deplibs"; then
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
-      fi
-
-      # Now set the variables for building old libraries.
-      build_libtool_libs=no
-      oldlibs="$output"
-      objs="$objs$old_deplibs"
-      ;;
-
-    lib)
-      # Make sure we only generate libraries of the form `libNAME.la'.
-      case $outputname in
-      lib*)
-	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-	eval shared_ext=\"$shrext_cmds\"
-	eval libname=\"$libname_spec\"
-	;;
-      *)
-	if test "$module" = no; then
-	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	if test "$need_lib_prefix" != no; then
-	  # Add the "lib" prefix for modules if required
-	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	  eval shared_ext=\"$shrext_cmds\"
-	  eval libname=\"$libname_spec\"
-	else
-	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	fi
-	;;
-      esac
-
-      if test -n "$objs"; then
-	if test "$deplibs_check_method" != pass_all; then
-	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
-	  exit $EXIT_FAILURE
-	else
-	  $echo
-	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
-	  $echo "*** objects $objs is not portable!"
-	  libobjs="$libobjs $objs"
-	fi
-      fi
-
-      if test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
-      fi
-
-      set dummy $rpath
-      if test "$#" -gt 2; then
-	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
-      fi
-      install_libdir="$2"
-
-      oldlibs=
-      if test -z "$rpath"; then
-	if test "$build_libtool_libs" = yes; then
-	  # Building a libtool convenience library.
-	  # Some compilers have problems with a `.al' extension so
-	  # convenience libraries should have the same extension an
-	  # archive normally would.
-	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
-	  build_libtool_libs=convenience
-	  build_old_libs=yes
-	fi
-
-	if test -n "$vinfo"; then
-	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
-	fi
-
-	if test -n "$release"; then
-	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
-	fi
-      else
-
-	# Parse the version information argument.
-	save_ifs="$IFS"; IFS=':'
-	set dummy $vinfo 0 0 0
-	IFS="$save_ifs"
-
-	if test -n "$8"; then
-	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# convert absolute version numbers to libtool ages
-	# this retains compatibility with .la files and attempts
-	# to make the code below a bit more comprehensible
-
-	case $vinfo_number in
-	yes)
-	  number_major="$2"
-	  number_minor="$3"
-	  number_revision="$4"
-	  #
-	  # There are really only two kinds -- those that
-	  # use the current revision as the major version
-	  # and those that subtract age and use age as
-	  # a minor version.  But, then there is irix
-	  # which has an extra 1 added just for fun
-	  #
-	  case $version_type in
-	  darwin|linux|osf|windows)
-	    current=`expr $number_major + $number_minor`
-	    age="$number_minor"
-	    revision="$number_revision"
-	    ;;
-	  freebsd-aout|freebsd-elf|sunos)
-	    current="$number_major"
-	    revision="$number_minor"
-	    age="0"
-	    ;;
-	  irix|nonstopux)
-	    current=`expr $number_major + $number_minor - 1`
-	    age="$number_minor"
-	    revision="$number_minor"
-	    ;;
-	  *)
-	    $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	    $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	  ;;
-	no)
-	  current="$2"
-	  revision="$3"
-	  age="$4"
-	  ;;
-	esac
-
-	# Check that each of the things are valid numbers.
-	case $current in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	case $revision in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	case $age in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	if test "$age" -gt "$current"; then
-	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# Calculate the version variables.
-	major=
-	versuffix=
-	verstring=
-	case $version_type in
-	none) ;;
-
-	darwin)
-	  # Like Linux, but with the current version available in
-	  # verstring for coding it into the library header
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  # Darwin ld doesn't like 0 for these options...
-	  minor_current=`expr $current + 1`
-	  verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
-	  ;;
-
-	freebsd-aout)
-	  major=".$current"
-	  versuffix=".$current.$revision";
-	  ;;
-
-	freebsd-elf)
-	  major=".$current"
-	  versuffix=".$current";
-	  ;;
-
-	irix | nonstopux)
-	  major=`expr $current - $age + 1`
-
-	  case $version_type in
-	    nonstopux) verstring_prefix=nonstopux ;;
-	    *)         verstring_prefix=sgi ;;
-	  esac
-	  verstring="$verstring_prefix$major.$revision"
-
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$revision
-	  while test "$loop" -ne 0; do
-	    iface=`expr $revision - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring_prefix$major.$iface:$verstring"
-	  done
-
-	  # Before this point, $major must not contain `.'.
-	  major=.$major
-	  versuffix="$major.$revision"
-	  ;;
-
-	linux)
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  ;;
-
-	osf)
-	  major=.`expr $current - $age`
-	  versuffix=".$current.$age.$revision"
-	  verstring="$current.$age.$revision"
-
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$age
-	  while test "$loop" -ne 0; do
-	    iface=`expr $current - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring:${iface}.0"
-	  done
-
-	  # Make executables depend on our current version.
-	  verstring="$verstring:${current}.0"
-	  ;;
-
-	sunos)
-	  major=".$current"
-	  versuffix=".$current.$revision"
-	  ;;
-
-	windows)
-	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 filesystems.
-	  major=`expr $current - $age`
-	  versuffix="-$major"
-	  ;;
-
-	*)
-	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	# Clear the version info if we defaulted, and they specified a release.
-	if test -z "$vinfo" && test -n "$release"; then
-	  major=
-	  case $version_type in
-	  darwin)
-	    # we can't check for "0.0" in archive_cmds due to quoting
-	    # problems, so we reset it completely
-	    verstring=
-	    ;;
-	  *)
-	    verstring="0.0"
-	    ;;
-	  esac
-	  if test "$need_version" = no; then
-	    versuffix=
-	  else
-	    versuffix=".0.0"
-	  fi
-	fi
-
-	# Remove version info from name if versioning should be avoided
-	if test "$avoid_version" = yes && test "$need_version" = no; then
-	  major=
-	  versuffix=
-	  verstring=""
-	fi
-
-	# Check to see if the archive will have undefined symbols.
-	if test "$allow_undefined" = yes; then
-	  if test "$allow_undefined_flag" = unsupported; then
-	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
-	    build_libtool_libs=no
-	    build_old_libs=yes
-	  fi
-	else
-	  # Don't allow undefined symbols.
-	  allow_undefined_flag="$no_undefined_flag"
-	fi
-      fi
-
-      if test "$mode" != relink; then
-	# Remove our outputs, but don't remove object files since they
-	# may have been created when compiling PIC objects.
-	removelist=
-	tempremovelist=`$echo "$output_objdir/*"`
-	for p in $tempremovelist; do
-	  case $p in
-	    *.$objext)
-	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
-	       if test "X$precious_files_regex" != "X"; then
-	         if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
-	         then
-		   continue
-		 fi
-	       fi
-	       removelist="$removelist $p"
-	       ;;
-	    *) ;;
-	  esac
-	done
-	if test -n "$removelist"; then
-	  $show "${rm}r $removelist"
-	  $run ${rm}r $removelist
-	fi
-      fi
-
-      # Now set the variables for building old libraries.
-      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-	oldlibs="$oldlibs $output_objdir/$libname.$libext"
-
-	# Transform .lo files to .o files.
-	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
-      fi
-
-      # Eliminate all temporary directories.
-      for path in $notinst_path; do
-	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
-	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
-	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
-      done
-
-      if test -n "$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	temp_xrpath=
-	for libdir in $xrpath; do
-	  temp_xrpath="$temp_xrpath -R$libdir"
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
-	  dependency_libs="$temp_xrpath $dependency_libs"
-	fi
-      fi
-
-      # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles="$dlfiles"
-      dlfiles=
-      for lib in $old_dlfiles; do
-	case " $dlprefiles $dlfiles " in
-	*" $lib "*) ;;
-	*) dlfiles="$dlfiles $lib" ;;
-	esac
-      done
-
-      # Make sure dlprefiles contains only unique files
-      old_dlprefiles="$dlprefiles"
-      dlprefiles=
-      for lib in $old_dlprefiles; do
-	case "$dlprefiles " in
-	*" $lib "*) ;;
-	*) dlprefiles="$dlprefiles $lib" ;;
-	esac
-      done
-
-      if test "$build_libtool_libs" = yes; then
-	if test -n "$rpath"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
-	    # these systems don't actually have a c library (as such)!
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C library is in the System framework
-	    deplibs="$deplibs -framework System"
-	    ;;
-	  *-*-netbsd*)
-	    # Don't link with libc until the a.out ld.so is fixed.
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    ;;
- 	  *)
-	    # Add libc to deplibs on all other systems if necessary.
-	    if test "$build_libtool_need_lc" = "yes"; then
-	      deplibs="$deplibs -lc"
-	    fi
-	    ;;
-	  esac
-	fi
-
-	# Transform deplibs into only deplibs that can be linked in shared.
-	name_save=$name
-	libname_save=$libname
-	release_save=$release
-	versuffix_save=$versuffix
-	major_save=$major
-	# I'm not sure if I'm treating the release correctly.  I think
-	# release should show up in the -l (ie -lgmp5) so we don't want to
-	# add it in twice.  Is that correct?
-	release=""
-	versuffix=""
-	major=""
-	newdeplibs=
-	droppeddeps=no
-	case $deplibs_check_method in
-	pass_all)
-	  # Don't check for shared/static.  Everything works.
-	  # This might be a little naive.  We might want to check
-	  # whether the library exists or not.  But this is on
-	  # osf3 & osf4 and I'm not really sure... Just
-	  # implementing what was already the behavior.
-	  newdeplibs=$deplibs
-	  ;;
-	test_compile)
-	  # This code stresses the "libraries are programs" paradigm to its
-	  # limits. Maybe even breaks it.  We compile a program, linking it
-	  # against the deplibs as a proxy for the library.  Then we can check
-	  # whether they linked in statically or dynamically with ldd.
-	  $rm conftest.c
-	  cat > conftest.c <<EOF
-	  int main() { return 0; }
-EOF
-	  $rm conftest
-	  $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
-	  if test "$?" -eq 0 ; then
-	    ldd_output=`ldd conftest`
-	    for i in $deplibs; do
-	      name=`expr $i : '-l\(.*\)'`
-	      # If $name is empty we are operating on a -L argument.
-              if test "$name" != "" && test "$name" -ne "0"; then
-		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		  case " $predeps $postdeps " in
-		  *" $i "*)
-		    newdeplibs="$newdeplibs $i"
-		    i=""
-		    ;;
-		  esac
-	        fi
-		if test -n "$i" ; then
-		  libname=`eval \\$echo \"$libname_spec\"`
-		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		  set dummy $deplib_matches
-		  deplib_match=$2
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		    newdeplibs="$newdeplibs $i"
-		  else
-		    droppeddeps=yes
-		    $echo
-		    $echo "*** Warning: dynamic linker does not accept needed library $i."
-		    $echo "*** I have the capability to make that library automatically link in when"
-		    $echo "*** you link to this library.  But I can only do this if you have a"
-		    $echo "*** shared version of the library, which I believe you do not have"
-		    $echo "*** because a test_compile did reveal that the linker did not use it for"
-		    $echo "*** its dynamic dependency list that programs get resolved with at runtime."
-		  fi
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
-	  else
-	    # Error occurred in the first compile.  Let's try to salvage
-	    # the situation: Compile a separate program for each library.
-	    for i in $deplibs; do
-	      name=`expr $i : '-l\(.*\)'`
-	      # If $name is empty we are operating on a -L argument.
-              if test "$name" != "" && test "$name" != "0"; then
-		$rm conftest
-		$LTCC $LTCFLAGS -o conftest conftest.c $i
-		# Did it work?
-		if test "$?" -eq 0 ; then
-		  ldd_output=`ldd conftest`
-		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		    case " $predeps $postdeps " in
-		    *" $i "*)
-		      newdeplibs="$newdeplibs $i"
-		      i=""
-		      ;;
-		    esac
-		  fi
-		  if test -n "$i" ; then
-		    libname=`eval \\$echo \"$libname_spec\"`
-		    deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		    set dummy $deplib_matches
-		    deplib_match=$2
-		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		      newdeplibs="$newdeplibs $i"
-		    else
-		      droppeddeps=yes
-		      $echo
-		      $echo "*** Warning: dynamic linker does not accept needed library $i."
-		      $echo "*** I have the capability to make that library automatically link in when"
-		      $echo "*** you link to this library.  But I can only do this if you have a"
-		      $echo "*** shared version of the library, which you do not appear to have"
-		      $echo "*** because a test_compile did reveal that the linker did not use this one"
-		      $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
-		    fi
-		  fi
-		else
-		  droppeddeps=yes
-		  $echo
-		  $echo "*** Warning!  Library $i is needed by this library but I was not able to"
-		  $echo "***  make it link in!  You will probably need to install it or some"
-		  $echo "*** library that it depends on before this library will be fully"
-		  $echo "*** functional.  Installing it before continuing would be even better."
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
-	  fi
-	  ;;
-	file_magic*)
-	  set dummy $deplibs_check_method
-	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-	  for a_deplib in $deplibs; do
-	    name=`expr $a_deplib : '-l\(.*\)'`
-	    # If $name is empty we are operating on a -L argument.
-            if test "$name" != "" && test  "$name" != "0"; then
-	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		case " $predeps $postdeps " in
-		*" $a_deplib "*)
-		  newdeplibs="$newdeplibs $a_deplib"
-		  a_deplib=""
-		  ;;
-		esac
-	      fi
-	      if test -n "$a_deplib" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		  for potent_lib in $potential_libs; do
-		      # Follow soft links.
-		      if ls -lLd "$potent_lib" 2>/dev/null \
-			 | grep " -> " >/dev/null; then
-			continue
-		      fi
-		      # The statement above tries to avoid entering an
-		      # endless loop below, in case of cyclic links.
-		      # We might still enter an endless loop, since a link
-		      # loop can be closed while we follow links,
-		      # but so what?
-		      potlib="$potent_lib"
-		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
-			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
-			esac
-		      done
-		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
-			 | ${SED} 10q \
-			 | $EGREP "$file_magic_regex" > /dev/null; then
-			newdeplibs="$newdeplibs $a_deplib"
-			a_deplib=""
-			break 2
-		      fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a file magic. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	match_pattern*)
-	  set dummy $deplibs_check_method
-	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-	  for a_deplib in $deplibs; do
-	    name=`expr $a_deplib : '-l\(.*\)'`
-	    # If $name is empty we are operating on a -L argument.
-	    if test -n "$name" && test "$name" != "0"; then
-	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		case " $predeps $postdeps " in
-		*" $a_deplib "*)
-		  newdeplibs="$newdeplibs $a_deplib"
-		  a_deplib=""
-		  ;;
-		esac
-	      fi
-	      if test -n "$a_deplib" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		  for potent_lib in $potential_libs; do
-		    potlib="$potent_lib" # see symlink-check above in file_magic test
-		    if eval $echo \"$potent_lib\" 2>/dev/null \
-		        | ${SED} 10q \
-		        | $EGREP "$match_pattern_regex" > /dev/null; then
-		      newdeplibs="$newdeplibs $a_deplib"
-		      a_deplib=""
-		      break 2
-		    fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a regex pattern. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	none | unknown | *)
-	  newdeplibs=""
-	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
-	    -e 's/ -[LR][^ ]*//g'`
-	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	    for i in $predeps $postdeps ; do
-	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
-	    done
-	  fi
-	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
-	    | grep . >/dev/null; then
-	    $echo
-	    if test "X$deplibs_check_method" = "Xnone"; then
-	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
-	    else
-	      $echo "*** Warning: inter-library dependencies are not known to be supported."
-	    fi
-	    $echo "*** All declared inter-library dependencies are being dropped."
-	    droppeddeps=yes
-	  fi
-	  ;;
-	esac
-	versuffix=$versuffix_save
-	major=$major_save
-	release=$release_save
-	libname=$libname_save
-	name=$name_save
-
-	case $host in
-	*-*-rhapsody* | *-*-darwin1.[012])
-	  # On Rhapsody replace the C library is the System framework
-	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	  ;;
-	esac
-
-	if test "$droppeddeps" = yes; then
-	  if test "$module" = yes; then
-	    $echo
-	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
-	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
-	    $echo "*** a static module, that should work as long as the dlopening"
-	    $echo "*** application is linked with the -dlopen flag."
-	    if test -z "$global_symbol_pipe"; then
-	      $echo
-	      $echo "*** However, this would only work if libtool was able to extract symbol"
-	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-	      $echo "*** not find such a program.  So, this module is probably useless."
-	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	    fi
-	    if test "$build_old_libs" = no; then
-	      oldlibs="$output_objdir/$libname.$libext"
-	      build_libtool_libs=module
-	      build_old_libs=yes
-	    else
-	      build_libtool_libs=no
-	    fi
-	  else
-	    $echo "*** The inter-library dependencies that have been dropped here will be"
-	    $echo "*** automatically added whenever a program is linked with this library"
-	    $echo "*** or is declared to -dlopen it."
-
-	    if test "$allow_undefined" = no; then
-	      $echo
-	      $echo "*** Since this library must not contain undefined symbols,"
-	      $echo "*** because either the platform does not support them or"
-	      $echo "*** it was explicitly requested with -no-undefined,"
-	      $echo "*** libtool will only create a static version of it."
-	      if test "$build_old_libs" = no; then
-		oldlibs="$output_objdir/$libname.$libext"
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  fi
-	fi
-	# Done checking deplibs!
-	deplibs=$newdeplibs
-      fi
-
-
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      deplibs="$new_libs"
-
-
-      # All the library-specific variables (install_libdir is set above).
-      library_names=
-      old_library=
-      dlname=
-
-      # Test again, we may have decided not to build it any more
-      if test "$build_libtool_libs" = yes; then
-	if test "$hardcode_into_libs" = yes; then
-	  # Hardcode the library paths
-	  hardcode_libdirs=
-	  dep_rpath=
-	  rpath="$finalize_rpath"
-	  test "$mode" != relink && rpath="$compile_rpath$rpath"
-	  for libdir in $rpath; do
-	    if test -n "$hardcode_libdir_flag_spec"; then
-	      if test -n "$hardcode_libdir_separator"; then
-		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs="$libdir"
-		else
-		  # Just accumulate the unique libdirs.
-		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		    ;;
-		  *)
-		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		    ;;
-		  esac
-		fi
-	      else
-		eval flag=\"$hardcode_libdir_flag_spec\"
-		dep_rpath="$dep_rpath $flag"
-	      fi
-	    elif test -n "$runpath_var"; then
-	      case "$perm_rpath " in
-	      *" $libdir "*) ;;
-	      *) perm_rpath="$perm_rpath $libdir" ;;
-	      esac
-	    fi
-	  done
-	  # Substitute the hardcoded libdirs into the rpath.
-	  if test -n "$hardcode_libdir_separator" &&
-	     test -n "$hardcode_libdirs"; then
-	    libdir="$hardcode_libdirs"
-	    if test -n "$hardcode_libdir_flag_spec_ld"; then
-	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
-	    else
-	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-	    fi
-	  fi
-	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
-	    # We should set the runpath_var.
-	    rpath=
-	    for dir in $perm_rpath; do
-	      rpath="$rpath$dir:"
-	    done
-	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
-	  fi
-	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
-	fi
-
-	shlibpath="$finalize_shlibpath"
-	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
-	if test -n "$shlibpath"; then
-	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
-	fi
-
-	# Get the real and link names of the library.
-	eval shared_ext=\"$shrext_cmds\"
-	eval library_names=\"$library_names_spec\"
-	set dummy $library_names
-	realname="$2"
-	shift; shift
-
-	if test -n "$soname_spec"; then
-	  eval soname=\"$soname_spec\"
-	else
-	  soname="$realname"
-	fi
-	if test -z "$dlname"; then
-	  dlname=$soname
-	fi
-
-	lib="$output_objdir/$realname"
-	linknames=
-	for link
-	do
-	  linknames="$linknames $link"
-	done
-
-	# Use standard objects if they are pic
-	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-
-	# Prepare the list of exported symbols
-	if test -z "$export_symbols"; then
-	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    cmds=$export_symbols_cmds
-	    save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      eval cmd=\"$cmd\"
-	      if len=`expr "X$cmd" : ".*"` &&
-	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	        $show "$cmd"
-	        $run eval "$cmd" || exit $?
-	        skipped_export=false
-	      else
-	        # The command line is too long to execute in one step.
-	        $show "using reloadable object file for export list..."
-	        skipped_export=:
-		# Break out early, otherwise skipped_export may be
-		# set to false by a later but shorter cmd.
-		break
-	      fi
-	    done
-	    IFS="$save_ifs"
-	    if test -n "$export_symbols_regex"; then
-	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
-	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
-	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
-	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
-	    fi
-	  fi
-	fi
-
-	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
-	fi
-
-	tmp_deplibs=
-	for test_deplib in $deplibs; do
-		case " $convenience " in
-		*" $test_deplib "*) ;;
-		*)
-			tmp_deplibs="$tmp_deplibs $test_deplib"
-			;;
-		esac
-	done
-	deplibs="$tmp_deplibs"
-
-	if test -n "$convenience"; then
-	  if test -n "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  else
-	    gentop="$output_objdir/${outputname}x"
-	    generated="$generated $gentop"
-
-	    func_extract_archives $gentop $convenience
-	    libobjs="$libobjs $func_extract_archives_result"
-	  fi
-	fi
-	
-	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
-	  eval flag=\"$thread_safe_flag_spec\"
-	  linker_flags="$linker_flags $flag"
-	fi
-
-	# Make a backup of the uninstalled library when relinking
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
-	fi
-
-	# Do each of the archive commands.
-	if test "$module" = yes && test -n "$module_cmds" ; then
-	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
-	    eval test_cmds=\"$module_expsym_cmds\"
-	    cmds=$module_expsym_cmds
-	  else
-	    eval test_cmds=\"$module_cmds\"
-	    cmds=$module_cmds
-	  fi
-	else
-	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	  eval test_cmds=\"$archive_expsym_cmds\"
-	  cmds=$archive_expsym_cmds
-	else
-	  eval test_cmds=\"$archive_cmds\"
-	  cmds=$archive_cmds
-	  fi
-	fi
-
-	if test "X$skipped_export" != "X:" &&
-	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	  :
-	else
-	  # The command line is too long to link in one step, link piecewise.
-	  $echo "creating reloadable object files..."
-
-	  # Save the value of $output and $libobjs because we want to
-	  # use them later.  If we have whole_archive_flag_spec, we
-	  # want to use save_libobjs as it was before
-	  # whole_archive_flag_spec was expanded, because we can't
-	  # assume the linker understands whole_archive_flag_spec.
-	  # This may have to be revisited, in case too many
-	  # convenience libraries get linked in and end up exceeding
-	  # the spec.
-	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	  fi
-	  save_output=$output
-	  output_la=`$echo "X$output" | $Xsed -e "$basename"`
-
-	  # Clear the reloadable object creation command queue and
-	  # initialize k to one.
-	  test_cmds=
-	  concat_cmds=
-	  objlist=
-	  delfiles=
-	  last_robj=
-	  k=1
-	  output=$output_objdir/$output_la-${k}.$objext
-	  # Loop over the list of objects to be linked.
-	  for obj in $save_libobjs
-	  do
-	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
-	    if test "X$objlist" = X ||
-	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-		 test "$len" -le "$max_cmd_len"; }; then
-	      objlist="$objlist $obj"
-	    else
-	      # The command $test_cmds is almost too long, add a
-	      # command to the queue.
-	      if test "$k" -eq 1 ; then
-		# The first file doesn't have a previous command to add.
-		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
-	      else
-		# All subsequent reloadable object files will link in
-		# the last one created.
-		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
-	      fi
-	      last_robj=$output_objdir/$output_la-${k}.$objext
-	      k=`expr $k + 1`
-	      output=$output_objdir/$output_la-${k}.$objext
-	      objlist=$obj
-	      len=1
-	    fi
-	  done
-	  # Handle the remaining objects by creating one last
-	  # reloadable object file.  All subsequent reloadable object
-	  # files will link in the last one created.
-	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
-
-	  if ${skipped_export-false}; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    libobjs=$output
-	    # Append the command to create the export file.
-	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
-          fi
-
-	  # Set up a command to remove the reloadable object files
-	  # after they are used.
-	  i=0
-	  while test "$i" -lt "$k"
-	  do
-	    i=`expr $i + 1`
-	    delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
-	  done
-
-	  $echo "creating a temporary reloadable object file: $output"
-
-	  # Loop through the commands generated above and execute them.
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $concat_cmds; do
-	    IFS="$save_ifs"
-	    $show "$cmd"
-	    $run eval "$cmd" || exit $?
-	  done
-	  IFS="$save_ifs"
-
-	  libobjs=$output
-	  # Restore the value of output.
-	  output=$save_output
-
-	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  fi
-	  # Expand the library linking commands again to reset the
-	  # value of $libobjs for piecewise linking.
-
-	  # Do each of the archive commands.
-	  if test "$module" = yes && test -n "$module_cmds" ; then
-	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
-	      cmds=$module_expsym_cmds
-	    else
-	      cmds=$module_cmds
-	    fi
-	  else
-	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	    cmds=$archive_expsym_cmds
-	  else
-	    cmds=$archive_cmds
-	    fi
-	  fi
-
-	  # Append the command to remove the reloadable object files
-	  # to the just-reset $cmds.
-	  eval cmds=\"\$cmds~\$rm $delfiles\"
-	fi
-	save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  eval cmd=\"$cmd\"
-	  $show "$cmd"
-	  $run eval "$cmd" || {
-	    lt_exit=$?
-
-	    # Restore the uninstalled library and exit
-	    if test "$mode" = relink; then
-	      $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
-	    fi
-
-	    exit $lt_exit
-	  }
-	done
-	IFS="$save_ifs"
-
-	# Restore the uninstalled library and exit
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
-
-	  if test -n "$convenience"; then
-	    if test -z "$whole_archive_flag_spec"; then
-	      $show "${rm}r $gentop"
-	      $run ${rm}r "$gentop"
-	    fi
-	  fi
-
-	  exit $EXIT_SUCCESS
-	fi
-
-	# Create links to the real library.
-	for linkname in $linknames; do
-	  if test "$realname" != "$linkname"; then
-	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
-	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
-	  fi
-	done
-
-	# If -module or -export-dynamic was specified, set the dlname.
-	if test "$module" = yes || test "$export_dynamic" = yes; then
-	  # On all known operating systems, these are identical.
-	  dlname="$soname"
-	fi
-      fi
-      ;;
-
-    obj)
-      if test -n "$deplibs"; then
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
-      fi
-
-      case $output in
-      *.lo)
-	if test -n "$objs$old_deplibs"; then
-	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	libobj="$output"
-	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
-	;;
-      *)
-	libobj=
-	obj="$output"
-	;;
-      esac
-
-      # Delete the old objects.
-      $run $rm $obj $libobj
-
-      # Objects from convenience libraries.  This assumes
-      # single-version convenience libraries.  Whenever we create
-      # different ones for PIC/non-PIC, this we'll have to duplicate
-      # the extraction.
-      reload_conv_objs=
-      gentop=
-      # reload_cmds runs $LD directly, so let us get rid of
-      # -Wl from whole_archive_flag_spec
-      wl=
-
-      if test -n "$convenience"; then
-	if test -n "$whole_archive_flag_spec"; then
-	  eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
-	else
-	  gentop="$output_objdir/${obj}x"
-	  generated="$generated $gentop"
-
-	  func_extract_archives $gentop $convenience
-	  reload_conv_objs="$reload_objs $func_extract_archives_result"
-	fi
-      fi
-
-      # Create the old-style object.
-      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
-
-      output="$obj"
-      cmds=$reload_cmds
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	eval cmd=\"$cmd\"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-
-      # Exit if we aren't doing a library object file.
-      if test -z "$libobj"; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
-
-	exit $EXIT_SUCCESS
-      fi
-
-      if test "$build_libtool_libs" != yes; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
-
-	# Create an invalid libtool object if no PIC, so that we don't
-	# accidentally link it into a program.
-	# $show "echo timestamp > $libobj"
-	# $run eval "echo timestamp > $libobj" || exit $?
-	exit $EXIT_SUCCESS
-      fi
-
-      if test -n "$pic_flag" || test "$pic_mode" != default; then
-	# Only do commands if we really have different PIC objects.
-	reload_objs="$libobjs $reload_conv_objs"
-	output="$libobj"
-	cmds=$reload_cmds
-	save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  eval cmd=\"$cmd\"
-	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
-	done
-	IFS="$save_ifs"
-      fi
-
-      if test -n "$gentop"; then
-	$show "${rm}r $gentop"
-	$run ${rm}r $gentop
-      fi
-
-      exit $EXIT_SUCCESS
-      ;;
-
-    prog)
-      case $host in
-	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
-      esac
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
-      fi
-
-      if test "$preload" = yes; then
-	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
-	   test "$dlopen_self_static" = unknown; then
-	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
-	fi
-      fi
-
-      case $host in
-      *-*-rhapsody* | *-*-darwin1.[012])
-	# On Rhapsody replace the C library is the System framework
-	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	;;
-      esac
-
-      case $host in
-      *darwin*)
-        # Don't allow lazy linking, it breaks C++ global constructors
-        if test "$tagname" = CXX ; then
-        compile_command="$compile_command ${wl}-bind_at_load"
-        finalize_command="$finalize_command ${wl}-bind_at_load"
-        fi
-        ;;
-      esac
-
-
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $compile_deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $compile_deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      compile_deplibs="$new_libs"
-
-
-      compile_command="$compile_command $compile_deplibs"
-      finalize_command="$finalize_command $finalize_deplibs"
-
-      if test -n "$rpath$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	for libdir in $rpath $xrpath; do
-	  # This is the magic to use -rpath.
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-      fi
-
-      # Now hardcode the library paths
-      rpath=
-      hardcode_libdirs=
-      for libdir in $compile_rpath $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) perm_rpath="$perm_rpath $libdir" ;;
-	  esac
-	fi
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$libdir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$libdir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      compile_rpath="$rpath"
-
-      rpath=
-      hardcode_libdirs=
-      for libdir in $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$finalize_perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
-	  esac
-	fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      finalize_rpath="$rpath"
-
-      if test -n "$libobjs" && test "$build_old_libs" = yes; then
-	# Transform all the library objects into standard objects.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-      fi
-
-      dlsyms=
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	  dlsyms="${outputname}S.c"
-	else
-	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
-	fi
-      fi
-
-      if test -n "$dlsyms"; then
-	case $dlsyms in
-	"") ;;
-	*.c)
-	  # Discover the nlist of each of the dlfiles.
-	  nlist="$output_objdir/${outputname}.nm"
-
-	  $show "$rm $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
-
-	  # Parse the name list into a source file.
-	  $show "creating $output_objdir/$dlsyms"
-
-	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
-
-/* External symbol declarations for the compiler. */\
-"
-
-	  if test "$dlself" = yes; then
-	    $show "generating symbol list for \`$output'"
-
-	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
-
-	    # Add our own program objects to the symbol list.
-	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	    for arg in $progfiles; do
-	      $show "extracting global C symbols from \`$arg'"
-	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	    done
-
-	    if test -n "$exclude_expsyms"; then
-	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
-
-	    if test -n "$export_symbols_regex"; then
-	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
-
-	    # Prepare the list of exported symbols
-	    if test -z "$export_symbols"; then
-	      export_symbols="$output_objdir/$outputname.exp"
-	      $run $rm $export_symbols
-	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    else
-	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
-	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
-	      $run eval 'mv "$nlist"T "$nlist"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    fi
-	  fi
-
-	  for arg in $dlprefiles; do
-	    $show "extracting global C symbols from \`$arg'"
-	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
-	    $run eval '$echo ": $name " >> "$nlist"'
-	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	  done
-
-	  if test -z "$run"; then
-	    # Make sure we have at least an empty file.
-	    test -f "$nlist" || : > "$nlist"
-
-	    if test -n "$exclude_expsyms"; then
-	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
-	      $mv "$nlist"T "$nlist"
-	    fi
-
-	    # Try sorting and uniquifying the output.
-	    if grep -v "^: " < "$nlist" |
-		if sort -k 3 </dev/null >/dev/null 2>&1; then
-		  sort -k 3
-		else
-		  sort +2
-		fi |
-		uniq > "$nlist"S; then
-	      :
-	    else
-	      grep -v "^: " < "$nlist" > "$nlist"S
-	    fi
-
-	    if test -f "$nlist"S; then
-	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
-	    else
-	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
-	    fi
-
-	    $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-"
-
-	    case $host in
-	    *cygwin* | *mingw* )
-	  $echo >> "$output_objdir/$dlsyms" "\
-/* DATA imports from DLLs on WIN32 can't be const, because
-   runtime relocations are performed -- see ld's documentation
-   on pseudo-relocs */
-struct {
-"
-	      ;;
-	    * )
-	  $echo >> "$output_objdir/$dlsyms" "\
-const struct {
-"
-	      ;;
-	    esac
-
-
-	  $echo >> "$output_objdir/$dlsyms" "\
-  const char *name;
-  lt_ptr address;
-}
-lt_preloaded_symbols[] =
-{\
-"
-
-	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
-
-	    $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
-  return lt_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
-	  fi
-
-	  pic_flag_for_symtable=
-	  case $host in
-	  # compiling the symbol table file with pic_flag works around
-	  # a FreeBSD bug that causes programs to crash when -lm is
-	  # linked before any other PIC object.  But we must not use
-	  # pic_flag when linking with -static.  The problem exists in
-	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
-	    esac;;
-	  *-*-hpux*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag";;
-	    esac
-	  esac
-
-	  # Now compile the dynamic symbol file.
-	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
-
-	  # Clean up the generated files.
-	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
-
-	  # Transform the symbol file into the correct name.
-          case $host in
-          *cygwin* | *mingw* )
-            if test -f "$output_objdir/${outputname}.def" ; then
-              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
-              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
-            else
-              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-             fi
-            ;;
-          * )
-            compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-            finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-            ;;
-          esac
-	  ;;
-	*)
-	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-      else
-	# We keep going just in case the user didn't refer to
-	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
-	# really was required.
-
-	# Nullify the symbol file.
-	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
-	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
-      fi
-
-      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
-	# Replace the output file specification.
-	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-	link_command="$compile_command$compile_rpath"
-
-	# We have no uninstalled library dependencies, so finalize right now.
-	$show "$link_command"
-	$run eval "$link_command"
-	exit_status=$?
-
-	# Delete the generated files.
-	if test -n "$dlsyms"; then
-	  $show "$rm $output_objdir/${outputname}S.${objext}"
-	  $run $rm "$output_objdir/${outputname}S.${objext}"
-	fi
-
-	exit $exit_status
-      fi
-
-      if test -n "$shlibpath_var"; then
-	# We should set the shlibpath_var
-	rpath=
-	for dir in $temp_rpath; do
-	  case $dir in
-	  [\\/]* | [A-Za-z]:[\\/]*)
-	    # Absolute path.
-	    rpath="$rpath$dir:"
-	    ;;
-	  *)
-	    # Relative path: add a thisdir entry.
-	    rpath="$rpath\$thisdir/$dir:"
-	    ;;
-	  esac
-	done
-	temp_rpath="$rpath"
-      fi
-
-      if test -n "$compile_shlibpath$finalize_shlibpath"; then
-	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
-      fi
-      if test -n "$finalize_shlibpath"; then
-	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
-      fi
-
-      compile_var=
-      finalize_var=
-      if test -n "$runpath_var"; then
-	if test -n "$perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-	if test -n "$finalize_perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $finalize_perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-      fi
-
-      if test "$no_install" = yes; then
-	# We don't need to create a wrapper script.
-	link_command="$compile_var$compile_command$compile_rpath"
-	# Replace the output file specification.
-	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-	# Delete the old output file.
-	$run $rm $output
-	# Link the executable and exit
-	$show "$link_command"
-	$run eval "$link_command" || exit $?
-	exit $EXIT_SUCCESS
-      fi
-
-      if test "$hardcode_action" = relink; then
-	# Fast installation is not supported
-	link_command="$compile_var$compile_command$compile_rpath"
-	relink_command="$finalize_var$finalize_command$finalize_rpath"
-
-	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
-	$echo "$modename: \`$output' will be relinked during installation" 1>&2
-      else
-	if test "$fast_install" != no; then
-	  link_command="$finalize_var$compile_command$finalize_rpath"
-	  if test "$fast_install" = yes; then
-	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
-	  else
-	    # fast_install is set to needless
-	    relink_command=
-	  fi
-	else
-	  link_command="$compile_var$compile_command$compile_rpath"
-	  relink_command="$finalize_var$finalize_command$finalize_rpath"
-	fi
-      fi
-
-      # Replace the output file specification.
-      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-
-      # Delete the old output files.
-      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
-      $show "$link_command"
-      $run eval "$link_command" || exit $?
-
-      # Now create the wrapper script.
-      $show "creating $output"
-
-      # Quote the relink command for shipping.
-      if test -n "$relink_command"; then
-	# Preserve any variables that may affect compiler behavior
-	for var in $variables_saved_for_relink; do
-	  if eval test -z \"\${$var+set}\"; then
-	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-	  elif eval var_value=\$$var; test -z "$var_value"; then
-	    relink_command="$var=; export $var; $relink_command"
-	  else
-	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
-	  fi
-	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Quote $echo for shipping.
-      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
-	case $progpath in
-	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
-	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
-	esac
-	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Only actually do things if our run command is non-null.
-      if test -z "$run"; then
-	# win32 will think the script is a binary if it has
-	# a .exe suffix, so we strip it off here.
-	case $output in
-	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
-	esac
-	# test for cygwin because mv fails w/o .exe extensions
-	case $host in
-	  *cygwin*)
-	    exeext=.exe
-	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
-	  *) exeext= ;;
-	esac
-	case $host in
-	  *cygwin* | *mingw* )
-            output_name=`basename $output`
-            output_path=`dirname $output`
-            cwrappersource="$output_path/$objdir/lt-$output_name.c"
-            cwrapper="$output_path/$output_name.exe"
-            $rm $cwrappersource $cwrapper
-            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
-
-	    cat > $cwrappersource <<EOF
-
-/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
-   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-
-   The $output program cannot be directly executed until all the libtool
-   libraries that it depends on are installed.
-
-   This wrapper executable should never be moved out of the build directory.
-   If it is, it will not operate correctly.
-
-   Currently, it simply execs the wrapper *script* "/bin/sh $output",
-   but could eventually absorb all of the scripts functionality and
-   exec $objdir/$outputname directly.
-*/
-EOF
-	    cat >> $cwrappersource<<"EOF"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/stat.h>
-
-#if defined(PATH_MAX)
-# define LT_PATHMAX PATH_MAX
-#elif defined(MAXPATHLEN)
-# define LT_PATHMAX MAXPATHLEN
-#else
-# define LT_PATHMAX 1024
-#endif
-
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-# define PATH_SEPARATOR ':'
-#endif
-
-#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
-  defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# ifndef DIR_SEPARATOR_2
-#  define DIR_SEPARATOR_2 '\\'
-# endif
-# ifndef PATH_SEPARATOR_2
-#  define PATH_SEPARATOR_2 ';'
-# endif
-#endif
-
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(ch) \
-        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
-
-#ifndef PATH_SEPARATOR_2
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
-#else /* PATH_SEPARATOR_2 */
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
-#endif /* PATH_SEPARATOR_2 */
-
-#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
-#define XFREE(stale) do { \
-  if (stale) { free ((void *) stale); stale = 0; } \
-} while (0)
-
-/* -DDEBUG is fairly common in CFLAGS.  */
-#undef DEBUG
-#if defined DEBUGWRAPPER
-# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
-#else
-# define DEBUG(format, ...)
-#endif
-
-const char *program_name = NULL;
-
-void * xmalloc (size_t num);
-char * xstrdup (const char *string);
-const char * base_name (const char *name);
-char * find_executable(const char *wrapper);
-int    check_executable(const char *path);
-char * strendzap(char *str, const char *pat);
-void lt_fatal (const char *message, ...);
-
-int
-main (int argc, char *argv[])
-{
-  char **newargz;
-  int i;
-
-  program_name = (char *) xstrdup (base_name (argv[0]));
-  DEBUG("(main) argv[0]      : %s\n",argv[0]);
-  DEBUG("(main) program_name : %s\n",program_name);
-  newargz = XMALLOC(char *, argc+2);
-EOF
-
-            cat >> $cwrappersource <<EOF
-  newargz[0] = (char *) xstrdup("$SHELL");
-EOF
-
-            cat >> $cwrappersource <<"EOF"
-  newargz[1] = find_executable(argv[0]);
-  if (newargz[1] == NULL)
-    lt_fatal("Couldn't find %s", argv[0]);
-  DEBUG("(main) found exe at : %s\n",newargz[1]);
-  /* we know the script has the same name, without the .exe */
-  /* so make sure newargz[1] doesn't end in .exe */
-  strendzap(newargz[1],".exe");
-  for (i = 1; i < argc; i++)
-    newargz[i+1] = xstrdup(argv[i]);
-  newargz[argc+1] = NULL;
-
-  for (i=0; i<argc+1; i++)
-  {
-    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
-    ;
-  }
-
-EOF
-
-            case $host_os in
-              mingw*)
-                cat >> $cwrappersource <<EOF
-  execv("$SHELL",(char const **)newargz);
-EOF
-              ;;
-              *)
-                cat >> $cwrappersource <<EOF
-  execv("$SHELL",newargz);
-EOF
-              ;;
-            esac
-
-            cat >> $cwrappersource <<"EOF"
-  return 127;
-}
-
-void *
-xmalloc (size_t num)
-{
-  void * p = (void *) malloc (num);
-  if (!p)
-    lt_fatal ("Memory exhausted");
-
-  return p;
-}
-
-char *
-xstrdup (const char *string)
-{
-  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
-;
-}
-
-const char *
-base_name (const char *name)
-{
-  const char *base;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  /* Skip over the disk name in MSDOS pathnames. */
-  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
-    name += 2;
-#endif
-
-  for (base = name; *name; name++)
-    if (IS_DIR_SEPARATOR (*name))
-      base = name + 1;
-  return base;
-}
-
-int
-check_executable(const char * path)
-{
-  struct stat st;
-
-  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
-  if ((!path) || (!*path))
-    return 0;
-
-  if ((stat (path, &st) >= 0) &&
-      (
-        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
-#if defined (S_IXOTH)
-       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
-#endif
-#if defined (S_IXGRP)
-       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
-#endif
-       ((st.st_mode & S_IXUSR) == S_IXUSR))
-      )
-    return 1;
-  else
-    return 0;
-}
-
-/* Searches for the full path of the wrapper.  Returns
-   newly allocated full path name if found, NULL otherwise */
-char *
-find_executable (const char* wrapper)
-{
-  int has_slash = 0;
-  const char* p;
-  const char* p_next;
-  /* static buffer for getcwd */
-  char tmp[LT_PATHMAX + 1];
-  int tmp_len;
-  char* concat_name;
-
-  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
-
-  if ((wrapper == NULL) || (*wrapper == '\0'))
-    return NULL;
-
-  /* Absolute path? */
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
-  {
-    concat_name = xstrdup (wrapper);
-    if (check_executable(concat_name))
-      return concat_name;
-    XFREE(concat_name);
-  }
-  else
-  {
-#endif
-    if (IS_DIR_SEPARATOR (wrapper[0]))
-    {
-      concat_name = xstrdup (wrapper);
-      if (check_executable(concat_name))
-        return concat_name;
-      XFREE(concat_name);
-    }
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  }
-#endif
-
-  for (p = wrapper; *p; p++)
-    if (*p == '/')
-    {
-      has_slash = 1;
-      break;
-    }
-  if (!has_slash)
-  {
-    /* no slashes; search PATH */
-    const char* path = getenv ("PATH");
-    if (path != NULL)
-    {
-      for (p = path; *p; p = p_next)
-      {
-        const char* q;
-        size_t p_len;
-        for (q = p; *q; q++)
-          if (IS_PATH_SEPARATOR(*q))
-            break;
-        p_len = q - p;
-        p_next = (*q == '\0' ? q : q + 1);
-        if (p_len == 0)
-        {
-          /* empty path: current directory */
-          if (getcwd (tmp, LT_PATHMAX) == NULL)
-            lt_fatal ("getcwd failed");
-          tmp_len = strlen(tmp);
-          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, tmp, tmp_len);
-          concat_name[tmp_len] = '/';
-          strcpy (concat_name + tmp_len + 1, wrapper);
-        }
-        else
-        {
-          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, p, p_len);
-          concat_name[p_len] = '/';
-          strcpy (concat_name + p_len + 1, wrapper);
-        }
-        if (check_executable(concat_name))
-          return concat_name;
-        XFREE(concat_name);
-      }
-    }
-    /* not found in PATH; assume curdir */
-  }
-  /* Relative path | not found in path: prepend cwd */
-  if (getcwd (tmp, LT_PATHMAX) == NULL)
-    lt_fatal ("getcwd failed");
-  tmp_len = strlen(tmp);
-  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-  memcpy (concat_name, tmp, tmp_len);
-  concat_name[tmp_len] = '/';
-  strcpy (concat_name + tmp_len + 1, wrapper);
-
-  if (check_executable(concat_name))
-    return concat_name;
-  XFREE(concat_name);
-  return NULL;
-}
-
-char *
-strendzap(char *str, const char *pat)
-{
-  size_t len, patlen;
-
-  assert(str != NULL);
-  assert(pat != NULL);
-
-  len = strlen(str);
-  patlen = strlen(pat);
-
-  if (patlen <= len)
-  {
-    str += len - patlen;
-    if (strcmp(str, pat) == 0)
-      *str = '\0';
-  }
-  return str;
-}
-
-static void
-lt_error_core (int exit_status, const char * mode,
-          const char * message, va_list ap)
-{
-  fprintf (stderr, "%s: %s: ", program_name, mode);
-  vfprintf (stderr, message, ap);
-  fprintf (stderr, ".\n");
-
-  if (exit_status >= 0)
-    exit (exit_status);
-}
-
-void
-lt_fatal (const char *message, ...)
-{
-  va_list ap;
-  va_start (ap, message);
-  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
-  va_end (ap);
-}
-EOF
-          # we should really use a build-platform specific compiler
-          # here, but OTOH, the wrappers (shell script and this C one)
-          # are only useful if you want to execute the "real" binary.
-          # Since the "real" binary is built for $host, then this
-          # wrapper might as well be built for $host, too.
-          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
-          ;;
-        esac
-        $rm $output
-        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
-
-	$echo > $output "\
-#! $SHELL
-
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-relink_command=\"$relink_command\"
-
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
-  # install mode needs the following variable:
-  notinst_deplibs='$notinst_deplibs'
-else
-  # When we are sourced in execute mode, \$file and \$echo are already set.
-  if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    echo=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$echo works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$echo will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
-"
-	$echo >> $output "\
-
-  # Find the directory that this script lives in.
-  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
-  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
-
-  # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
-  while test -n \"\$file\"; do
-    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
-
-    # If there was a directory component, then change thisdir.
-    if test \"x\$destdir\" != \"x\$file\"; then
-      case \"\$destdir\" in
-      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
-      *) thisdir=\"\$thisdir/\$destdir\" ;;
-      esac
-    fi
-
-    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
-  done
-
-  # Try to get the absolute directory name.
-  absdir=\`cd \"\$thisdir\" && pwd\`
-  test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
-
-	if test "$fast_install" = yes; then
-	  $echo >> $output "\
-  program=lt-'$outputname'$exeext
-  progdir=\"\$thisdir/$objdir\"
-
-  if test ! -f \"\$progdir/\$program\" || \\
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
-       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
-
-    file=\"\$\$-\$program\"
-
-    if test ! -d \"\$progdir\"; then
-      $mkdir \"\$progdir\"
-    else
-      $rm \"\$progdir/\$file\"
-    fi"
-
-	  $echo >> $output "\
-
-    # relink executable if necessary
-    if test -n \"\$relink_command\"; then
-      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
-      else
-	$echo \"\$relink_command_output\" >&2
-	$rm \"\$progdir/\$file\"
-	exit $EXIT_FAILURE
-      fi
-    fi
-
-    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
-    { $rm \"\$progdir/\$program\";
-      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
-    $rm \"\$progdir/\$file\"
-  fi"
-	else
-	  $echo >> $output "\
-  program='$outputname'
-  progdir=\"\$thisdir/$objdir\"
-"
-	fi
-
-	$echo >> $output "\
-
-  if test -f \"\$progdir/\$program\"; then"
-
-	# Export our shlibpath_var if we have one.
-	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
-	  $echo >> $output "\
-    # Add our own library path to $shlibpath_var
-    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
-
-    # Some systems cannot cope with colon-terminated $shlibpath_var
-    # The second colon is a workaround for a bug in BeOS R4 sed
-    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
-
-    export $shlibpath_var
-"
-	fi
-
-	# fixup the dll searchpath if we need to.
-	if test -n "$dllsearchpath"; then
-	  $echo >> $output "\
-    # Add the dll search path components to the executable PATH
-    PATH=$dllsearchpath:\$PATH
-"
-	fi
-
-	$echo >> $output "\
-    if test \"\$libtool_execute_magic\" != \"$magic\"; then
-      # Run the actual program with our arguments.
-"
-	case $host in
-	# Backslashes separate directories on plain windows
-	*-*-mingw | *-*-os2*)
-	  $echo >> $output "\
-      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
-	  ;;
-
-	*)
-	  $echo >> $output "\
-      exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
-	  ;;
-	esac
-	$echo >> $output "\
-      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
-      exit $EXIT_FAILURE
-    fi
-  else
-    # The program doesn't exist.
-    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
-    \$echo \"This script is just a wrapper for \$program.\" 1>&2
-    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
-    exit $EXIT_FAILURE
-  fi
-fi\
-"
-	chmod +x $output
-      fi
-      exit $EXIT_SUCCESS
-      ;;
-    esac
-
-    # See if we need to build an old-fashioned archive.
-    for oldlib in $oldlibs; do
-
-      if test "$build_libtool_libs" = convenience; then
-	oldobjs="$libobjs_save"
-	addlibs="$convenience"
-	build_libtool_libs=no
-      else
-	if test "$build_libtool_libs" = module; then
-	  oldobjs="$libobjs_save"
-	  build_libtool_libs=no
-	else
-	  oldobjs="$old_deplibs $non_pic_objects"
-	fi
-	addlibs="$old_convenience"
-      fi
-
-      if test -n "$addlibs"; then
-	gentop="$output_objdir/${outputname}x"
-	generated="$generated $gentop"
-
-	func_extract_archives $gentop $addlibs
-	oldobjs="$oldobjs $func_extract_archives_result"
-      fi
-
-      # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
-       cmds=$old_archive_from_new_cmds
-      else
-	# POSIX demands no paths to be encoded in archives.  We have
-	# to avoid creating archives with duplicate basenames if we
-	# might have to extract them afterwards, e.g., when creating a
-	# static archive out of a convenience library, or when linking
-	# the entirety of a libtool archive into another (currently
-	# not supported by libtool).
-	if (for obj in $oldobjs
-	    do
-	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
-	    done | sort | sort -uc >/dev/null 2>&1); then
-	  :
-	else
-	  $echo "copying selected object files to avoid basename conflicts..."
-
-	  if test -z "$gentop"; then
-	    gentop="$output_objdir/${outputname}x"
-	    generated="$generated $gentop"
-
-	    $show "${rm}r $gentop"
-	    $run ${rm}r "$gentop"
-	    $show "$mkdir $gentop"
-	    $run $mkdir "$gentop"
-	    exit_status=$?
-	    if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
-	      exit $exit_status
-	    fi
-	  fi
-
-	  save_oldobjs=$oldobjs
-	  oldobjs=
-	  counter=1
-	  for obj in $save_oldobjs
-	  do
-	    objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-	    case " $oldobjs " in
-	    " ") oldobjs=$obj ;;
-	    *[\ /]"$objbase "*)
-	      while :; do
-		# Make sure we don't pick an alternate name that also
-		# overlaps.
-		newobj=lt$counter-$objbase
-		counter=`expr $counter + 1`
-		case " $oldobjs " in
-		*[\ /]"$newobj "*) ;;
-		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
-		esac
-	      done
-	      $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
-	      $run ln "$obj" "$gentop/$newobj" ||
-	      $run cp "$obj" "$gentop/$newobj"
-	      oldobjs="$oldobjs $gentop/$newobj"
-	      ;;
-	    *) oldobjs="$oldobjs $obj" ;;
-	    esac
-	  done
-	fi
-
-	eval cmds=\"$old_archive_cmds\"
-
-	if len=`expr "X$cmds" : ".*"` &&
-	     test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	  cmds=$old_archive_cmds
-	else
-	  # the command line is too long to link in one step, link in parts
-	  $echo "using piecewise archive linking..."
-	  save_RANLIB=$RANLIB
-	  RANLIB=:
-	  objlist=
-	  concat_cmds=
-	  save_oldobjs=$oldobjs
-
-	  # Is there a better way of finding the last object in the list?
-	  for obj in $save_oldobjs
-	  do
-	    last_oldobj=$obj
-	  done
-	  for obj in $save_oldobjs
-	  do
-	    oldobjs="$objlist $obj"
-	    objlist="$objlist $obj"
-	    eval test_cmds=\"$old_archive_cmds\"
-	    if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-	       test "$len" -le "$max_cmd_len"; then
-	      :
-	    else
-	      # the above command should be used before it gets too long
-	      oldobjs=$objlist
-	      if test "$obj" = "$last_oldobj" ; then
-	        RANLIB=$save_RANLIB
-	      fi
-	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
-	      objlist=
-	    fi
-	  done
-	  RANLIB=$save_RANLIB
-	  oldobjs=$objlist
-	  if test "X$oldobjs" = "X" ; then
-	    eval cmds=\"\$concat_cmds\"
-	  else
-	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
-	  fi
-	fi
-      fi
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-        eval cmd=\"$cmd\"
-	IFS="$save_ifs"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$generated"; then
-      $show "${rm}r$generated"
-      $run ${rm}r$generated
-    fi
-
-    # Now create the libtool archive.
-    case $output in
-    *.la)
-      old_library=
-      test "$build_old_libs" = yes && old_library="$libname.$libext"
-      $show "creating $output"
-
-      # Preserve any variables that may affect compiler behavior
-      for var in $variables_saved_for_relink; do
-	if eval test -z \"\${$var+set}\"; then
-	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-	elif eval var_value=\$$var; test -z "$var_value"; then
-	  relink_command="$var=; export $var; $relink_command"
-	else
-	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
-	fi
-      done
-      # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-      if test "$hardcode_automatic" = yes ; then
-	relink_command=
-      fi
-
-
-      # Only create the output if not a dry run.
-      if test -z "$run"; then
-	for installed in no yes; do
-	  if test "$installed" = yes; then
-	    if test -z "$install_libdir"; then
-	      break
-	    fi
-	    output="$output_objdir/$outputname"i
-	    # Replace all uninstalled libtool libraries with the installed ones
-	    newdependency_libs=
-	    for deplib in $dependency_libs; do
-	      case $deplib in
-	      *.la)
-		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
-		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		if test -z "$libdir"; then
-		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-		  exit $EXIT_FAILURE
-		fi
-		newdependency_libs="$newdependency_libs $libdir/$name"
-		;;
-	      *) newdependency_libs="$newdependency_libs $deplib" ;;
-	      esac
-	    done
-	    dependency_libs="$newdependency_libs"
-	    newdlfiles=
-	    for lib in $dlfiles; do
-	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-	      if test -z "$libdir"; then
-		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-		exit $EXIT_FAILURE
-	      fi
-	      newdlfiles="$newdlfiles $libdir/$name"
-	    done
-	    dlfiles="$newdlfiles"
-	    newdlprefiles=
-	    for lib in $dlprefiles; do
-	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
-	      if test -z "$libdir"; then
-		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-		exit $EXIT_FAILURE
-	      fi
-	      newdlprefiles="$newdlprefiles $libdir/$name"
-	    done
-	    dlprefiles="$newdlprefiles"
-	  else
-	    newdlfiles=
-	    for lib in $dlfiles; do
-	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
-		*) abs=`pwd`"/$lib" ;;
-	      esac
-	      newdlfiles="$newdlfiles $abs"
-	    done
-	    dlfiles="$newdlfiles"
-	    newdlprefiles=
-	    for lib in $dlprefiles; do
-	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
-		*) abs=`pwd`"/$lib" ;;
-	      esac
-	      newdlprefiles="$newdlprefiles $abs"
-	    done
-	    dlprefiles="$newdlprefiles"
-	  fi
-	  $rm $output
-	  # place dlname in correct position for cygwin
-	  tdlname=$dlname
-	  case $host,$output,$installed,$module,$dlname in
-	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
-	  esac
-	  $echo > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='$tdlname'
-
-# Names of this library.
-library_names='$library_names'
-
-# The name of the static archive.
-old_library='$old_library'
-
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
-
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
-
-# Is this an already installed library?
-installed=$installed
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=$module
-
-# Files to dlopen/dlpreopen
-dlopen='$dlfiles'
-dlpreopen='$dlprefiles'
-
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'"
-	  if test "$installed" = no && test "$need_relink" = yes; then
-	    $echo >> $output "\
-relink_command=\"$relink_command\""
-	  fi
-	done
-      fi
-
-      # Do a symbolic link so that the libtool archive can be found in
-      # LD_LIBRARY_PATH before the program is installed.
-      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
-      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
-      ;;
-    esac
-    exit $EXIT_SUCCESS
-    ;;
-
-  # libtool install mode
-  install)
-    modename="$modename: install"
-
-    # There may be an optional sh(1) argument at the beginning of
-    # install_prog (especially on Windows NT).
-    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
-       # Allow the use of GNU shtool's install command.
-       $echo "X$nonopt" | grep shtool > /dev/null; then
-      # Aesthetically quote it.
-      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	arg="\"$arg\""
-	;;
-      esac
-      install_prog="$arg "
-      arg="$1"
-      shift
-    else
-      install_prog=
-      arg=$nonopt
-    fi
-
-    # The real first argument should be the name of the installation program.
-    # Aesthetically quote it.
-    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-    case $arg in
-    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-      arg="\"$arg\""
-      ;;
-    esac
-    install_prog="$install_prog$arg"
-
-    # We need to accept at least all the BSD install flags.
-    dest=
-    files=
-    opts=
-    prev=
-    install_type=
-    isdir=no
-    stripme=
-    for arg
-    do
-      if test -n "$dest"; then
-	files="$files $dest"
-	dest=$arg
-	continue
-      fi
-
-      case $arg in
-      -d) isdir=yes ;;
-      -f) 
-      	case " $install_prog " in
-	*[\\\ /]cp\ *) ;;
-	*) prev=$arg ;;
-	esac
-	;;
-      -g | -m | -o) prev=$arg ;;
-      -s)
-	stripme=" -s"
-	continue
-	;;
-      -*)
-	;;
-      *)
-	# If the previous option needed an argument, then skip it.
-	if test -n "$prev"; then
-	  prev=
-	else
-	  dest=$arg
-	  continue
-	fi
-	;;
-      esac
-
-      # Aesthetically quote the argument.
-      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	arg="\"$arg\""
-	;;
-      esac
-      install_prog="$install_prog $arg"
-    done
-
-    if test -z "$install_prog"; then
-      $echo "$modename: you must specify an install program" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prev' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    if test -z "$files"; then
-      if test -z "$dest"; then
-	$echo "$modename: no file or destination specified" 1>&2
-      else
-	$echo "$modename: you must specify a destination" 1>&2
-      fi
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    # Strip any trailing slash from the destination.
-    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
-
-    # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=yes
-    if test "$isdir" = yes; then
-      destdir="$dest"
-      destname=
-    else
-      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
-      test "X$destdir" = "X$dest" && destdir=.
-      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
-
-      # Not a directory, so check to see that there is only one file specified.
-      set dummy $files
-      if test "$#" -gt 2; then
-	$echo "$modename: \`$dest' is not a directory" 1>&2
-	$echo "$help" 1>&2
-	exit $EXIT_FAILURE
-      fi
-    fi
-    case $destdir in
-    [\\/]* | [A-Za-z]:[\\/]*) ;;
-    *)
-      for file in $files; do
-	case $file in
-	*.lo) ;;
-	*)
-	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-      done
-      ;;
-    esac
-
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
-
-    staticlibs=
-    future_libdirs=
-    current_libdirs=
-    for file in $files; do
-
-      # Do each installation.
-      case $file in
-      *.$libext)
-	# Do the static libraries later.
-	staticlibs="$staticlibs $file"
-	;;
-
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	library_names=
-	old_library=
-	relink_command=
-	# If there is no directory component, then add one.
-	case $file in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
-
-	# Add the libdir to current_libdirs if it is the destination.
-	if test "X$destdir" = "X$libdir"; then
-	  case "$current_libdirs " in
-	  *" $libdir "*) ;;
-	  *) current_libdirs="$current_libdirs $libdir" ;;
-	  esac
-	else
-	  # Note the libdir as a future libdir.
-	  case "$future_libdirs " in
-	  *" $libdir "*) ;;
-	  *) future_libdirs="$future_libdirs $libdir" ;;
-	  esac
-	fi
-
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
-	test "X$dir" = "X$file/" && dir=
-	dir="$dir$objdir"
-
-	if test -n "$relink_command"; then
-	  # Determine the prefix the user has applied to our future dir.
-	  inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
-
-	  # Don't allow the user to place us outside of our expected
-	  # location b/c this prevents finding dependent libraries that
-	  # are installed to the same prefix.
-	  # At present, this check doesn't affect windows .dll's that
-	  # are installed into $libdir/../bin (currently, that works fine)
-	  # but it's something to keep an eye on.
-	  if test "$inst_prefix_dir" = "$destdir"; then
-	    $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-
-	  if test -n "$inst_prefix_dir"; then
-	    # Stick the inst_prefix_dir data into the link command.
-	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
-	  else
-	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
-	  fi
-
-	  $echo "$modename: warning: relinking \`$file'" 1>&2
-	  $show "$relink_command"
-	  if $run eval "$relink_command"; then :
-	  else
-	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	fi
-
-	# See the names of the shared library.
-	set dummy $library_names
-	if test -n "$2"; then
-	  realname="$2"
-	  shift
-	  shift
-
-	  srcname="$realname"
-	  test -n "$relink_command" && srcname="$realname"T
-
-	  # Install the shared library and build the symlinks.
-	  $show "$install_prog $dir/$srcname $destdir/$realname"
-	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
-	  if test -n "$stripme" && test -n "$striplib"; then
-	    $show "$striplib $destdir/$realname"
-	    $run eval "$striplib $destdir/$realname" || exit $?
-	  fi
-
-	  if test "$#" -gt 0; then
-	    # Delete the old symlinks, and create new ones.
-	    # Try `ln -sf' first, because the `ln' binary might depend on
-	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
-	    # so we also need to try rm && ln -s.
-	    for linkname
-	    do
-	      if test "$linkname" != "$realname"; then
-                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
-                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
-	      fi
-	    done
-	  fi
-
-	  # Do each command in the postinstall commands.
-	  lib="$destdir/$realname"
-	  cmds=$postinstall_cmds
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    eval cmd=\"$cmd\"
-	    $show "$cmd"
-	    $run eval "$cmd" || {
-	      lt_exit=$?
-
-	      # Restore the uninstalled library and exit
-	      if test "$mode" = relink; then
-		$run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
-	      fi
-
-	      exit $lt_exit
-	    }
-	  done
-	  IFS="$save_ifs"
-	fi
-
-	# Install the pseudo-library for information purposes.
-	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	instname="$dir/$name"i
-	$show "$install_prog $instname $destdir/$name"
-	$run eval "$install_prog $instname $destdir/$name" || exit $?
-
-	# Maybe install the static library, too.
-	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
-	;;
-
-      *.lo)
-	# Install (i.e. copy) a libtool object.
-
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
-	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
-	fi
-
-	# Deduce the name of the destination old-style object file.
-	case $destfile in
-	*.lo)
-	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
-	  ;;
-	*.$objext)
-	  staticdest="$destfile"
-	  destfile=
-	  ;;
-	*)
-	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-
-	# Install the libtool object if requested.
-	if test -n "$destfile"; then
-	  $show "$install_prog $file $destfile"
-	  $run eval "$install_prog $file $destfile" || exit $?
-	fi
-
-	# Install the old object if enabled.
-	if test "$build_old_libs" = yes; then
-	  # Deduce the name of the old-style object file.
-	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
-
-	  $show "$install_prog $staticobj $staticdest"
-	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
-	fi
-	exit $EXIT_SUCCESS
-	;;
-
-      *)
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
-	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
-	fi
-
-	# If the file is missing, and there is a .exe on the end, strip it
-	# because it is most likely a libtool script we actually want to
-	# install
-	stripped_ext=""
-	case $file in
-	  *.exe)
-	    if test ! -f "$file"; then
-	      file=`$echo $file|${SED} 's,.exe$,,'`
-	      stripped_ext=".exe"
-	    fi
-	    ;;
-	esac
-
-	# Do a test to see if this is really a libtool program.
-	case $host in
-	*cygwin*|*mingw*)
-	    wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
-	    ;;
-	*)
-	    wrapper=$file
-	    ;;
-	esac
-	if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
-	  notinst_deplibs=
-	  relink_command=
-
-	  # Note that it is not necessary on cygwin/mingw to append a dot to
-	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
-	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-	  # `FILE.' does not work on cygwin managed mounts.
-	  #
-	  # If there is no directory component, then add one.
-	  case $wrapper in
-	  */* | *\\*) . ${wrapper} ;;
-	  *) . ./${wrapper} ;;
-	  esac
-
-	  # Check the variables that should have been set.
-	  if test -z "$notinst_deplibs"; then
-	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-
-	  finalize=yes
-	  for lib in $notinst_deplibs; do
-	    # Check to see that each library is installed.
-	    libdir=
-	    if test -f "$lib"; then
-	      # If there is no directory component, then add one.
-	      case $lib in
-	      */* | *\\*) . $lib ;;
-	      *) . ./$lib ;;
-	      esac
-	    fi
-	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
-	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
-	      finalize=no
-	    fi
-	  done
-
-	  relink_command=
-	  # Note that it is not necessary on cygwin/mingw to append a dot to
-	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
-	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-	  # `FILE.' does not work on cygwin managed mounts.
-	  #
-	  # If there is no directory component, then add one.
-	  case $wrapper in
-	  */* | *\\*) . ${wrapper} ;;
-	  *) . ./${wrapper} ;;
-	  esac
-
-	  outputname=
-	  if test "$fast_install" = no && test -n "$relink_command"; then
-	    if test "$finalize" = yes && test -z "$run"; then
-	      tmpdir=`func_mktempdir`
-	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
-	      outputname="$tmpdir/$file"
-	      # Replace the output file specification.
-	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
-
-	      $show "$relink_command"
-	      if $run eval "$relink_command"; then :
-	      else
-		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-		${rm}r "$tmpdir"
-		continue
-	      fi
-	      file="$outputname"
-	    else
-	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
-	    fi
-	  else
-	    # Install the binary that we compiled earlier.
-	    file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
-	  fi
-	fi
-
-	# remove .exe since cygwin /usr/bin/install will append another
-	# one anyway 
-	case $install_prog,$host in
-	*/usr/bin/install*,*cygwin*)
-	  case $file:$destfile in
-	  *.exe:*.exe)
-	    # this is ok
-	    ;;
-	  *.exe:*)
-	    destfile=$destfile.exe
-	    ;;
-	  *:*.exe)
-	    destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
-	    ;;
-	  esac
-	  ;;
-	esac
-	$show "$install_prog$stripme $file $destfile"
-	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
-	test -n "$outputname" && ${rm}r "$tmpdir"
-	;;
-      esac
-    done
-
-    for file in $staticlibs; do
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-
-      # Set up the ranlib parameters.
-      oldlib="$destdir/$name"
-
-      $show "$install_prog $file $oldlib"
-      $run eval "$install_prog \$file \$oldlib" || exit $?
-
-      if test -n "$stripme" && test -n "$old_striplib"; then
-	$show "$old_striplib $oldlib"
-	$run eval "$old_striplib $oldlib" || exit $?
-      fi
-
-      # Do each command in the postinstall commands.
-      cmds=$old_postinstall_cmds
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	eval cmd=\"$cmd\"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$future_libdirs"; then
-      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
-    fi
-
-    if test -n "$current_libdirs"; then
-      # Maybe just do a dry run.
-      test -n "$run" && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
-    else
-      exit $EXIT_SUCCESS
-    fi
-    ;;
-
-  # libtool finish mode
-  finish)
-    modename="$modename: finish"
-    libdirs="$nonopt"
-    admincmds=
-
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
-      for dir
-      do
-	libdirs="$libdirs $dir"
-      done
-
-      for libdir in $libdirs; do
-	if test -n "$finish_cmds"; then
-	  # Do each command in the finish commands.
-	  cmds=$finish_cmds
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    eval cmd=\"$cmd\"
-	    $show "$cmd"
-	    $run eval "$cmd" || admincmds="$admincmds
-       $cmd"
-	  done
-	  IFS="$save_ifs"
-	fi
-	if test -n "$finish_eval"; then
-	  # Do the single finish_eval.
-	  eval cmds=\"$finish_eval\"
-	  $run eval "$cmds" || admincmds="$admincmds
-       $cmds"
-	fi
-      done
-    fi
-
-    # Exit here if they wanted silent mode.
-    test "$show" = : && exit $EXIT_SUCCESS
-
-    $echo "X----------------------------------------------------------------------" | $Xsed
-    $echo "Libraries have been installed in:"
-    for libdir in $libdirs; do
-      $echo "   $libdir"
-    done
-    $echo
-    $echo "If you ever happen to want to link against installed libraries"
-    $echo "in a given directory, LIBDIR, you must either use libtool, and"
-    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
-    $echo "flag during linking and do at least one of the following:"
-    if test -n "$shlibpath_var"; then
-      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
-      $echo "     during execution"
-    fi
-    if test -n "$runpath_var"; then
-      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
-      $echo "     during linking"
-    fi
-    if test -n "$hardcode_libdir_flag_spec"; then
-      libdir=LIBDIR
-      eval flag=\"$hardcode_libdir_flag_spec\"
-
-      $echo "   - use the \`$flag' linker flag"
-    fi
-    if test -n "$admincmds"; then
-      $echo "   - have your system administrator run these commands:$admincmds"
-    fi
-    if test -f /etc/ld.so.conf; then
-      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
-    fi
-    $echo
-    $echo "See any operating system documentation about shared libraries for"
-    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
-    $echo "X----------------------------------------------------------------------" | $Xsed
-    exit $EXIT_SUCCESS
-    ;;
-
-  # libtool execute mode
-  execute)
-    modename="$modename: execute"
-
-    # The first argument is the command name.
-    cmd="$nonopt"
-    if test -z "$cmd"; then
-      $echo "$modename: you must specify a COMMAND" 1>&2
-      $echo "$help"
-      exit $EXIT_FAILURE
-    fi
-
-    # Handle -dlopen flags immediately.
-    for file in $execute_dlfiles; do
-      if test ! -f "$file"; then
-	$echo "$modename: \`$file' is not a file" 1>&2
-	$echo "$help" 1>&2
-	exit $EXIT_FAILURE
-      fi
-
-      dir=
-      case $file in
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-
-	# Read the libtool library.
-	dlname=
-	library_names=
-
-	# If there is no directory component, then add one.
-	case $file in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
-
-	# Skip this library if it cannot be dlopened.
-	if test -z "$dlname"; then
-	  # Warn if it was a shared library.
-	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
-	  continue
-	fi
-
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
-
-	if test -f "$dir/$objdir/$dlname"; then
-	  dir="$dir/$objdir"
-	else
-	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	;;
-
-      *.lo)
-	# Just add the directory containing the .lo file.
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
-	;;
-
-      *)
-	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
-	continue
-	;;
-      esac
-
-      # Get the absolute pathname.
-      absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir="$absdir"
-
-      # Now add the directory to shlibpath_var.
-      if eval "test -z \"\$$shlibpath_var\""; then
-	eval "$shlibpath_var=\"\$dir\""
-      else
-	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
-      fi
-    done
-
-    # This variable tells wrapper scripts just to set shlibpath_var
-    # rather than running their programs.
-    libtool_execute_magic="$magic"
-
-    # Check if any of the arguments is a wrapper script.
-    args=
-    for file
-    do
-      case $file in
-      -*) ;;
-      *)
-	# Do a test to see if this is really a libtool program.
-	if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  # If there is no directory component, then add one.
-	  case $file in
-	  */* | *\\*) . $file ;;
-	  *) . ./$file ;;
-	  esac
-
-	  # Transform arg to wrapped name.
-	  file="$progdir/$program"
-	fi
-	;;
-      esac
-      # Quote arguments (to preserve shell metacharacters).
-      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
-      args="$args \"$file\""
-    done
-
-    if test -z "$run"; then
-      if test -n "$shlibpath_var"; then
-	# Export the shlibpath_var.
-	eval "export $shlibpath_var"
-      fi
-
-      # Restore saved environment variables
-      if test "${save_LC_ALL+set}" = set; then
-	LC_ALL="$save_LC_ALL"; export LC_ALL
-      fi
-      if test "${save_LANG+set}" = set; then
-	LANG="$save_LANG"; export LANG
-      fi
-
-      # Now prepare to actually exec the command.
-      exec_cmd="\$cmd$args"
-    else
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
-	$echo "export $shlibpath_var"
-      fi
-      $echo "$cmd$args"
-      exit $EXIT_SUCCESS
-    fi
-    ;;
-
-  # libtool clean and uninstall mode
-  clean | uninstall)
-    modename="$modename: $mode"
-    rm="$nonopt"
-    files=
-    rmforce=
-    exit_status=0
-
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
-
-    for arg
-    do
-      case $arg in
-      -f) rm="$rm $arg"; rmforce=yes ;;
-      -*) rm="$rm $arg" ;;
-      *) files="$files $arg" ;;
-      esac
-    done
-
-    if test -z "$rm"; then
-      $echo "$modename: you must specify an RM program" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
-
-    rmdirs=
-
-    origobjdir="$objdir"
-    for file in $files; do
-      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-      if test "X$dir" = "X$file"; then
-	dir=.
-	objdir="$origobjdir"
-      else
-	objdir="$dir/$origobjdir"
-      fi
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-      test "$mode" = uninstall && objdir="$dir"
-
-      # Remember objdir for removal later, being careful to avoid duplicates
-      if test "$mode" = clean; then
-	case " $rmdirs " in
-	  *" $objdir "*) ;;
-	  *) rmdirs="$rmdirs $objdir" ;;
-	esac
-      fi
-
-      # Don't error if the file doesn't exist and rm -f was used.
-      if (test -L "$file") >/dev/null 2>&1 \
-	|| (test -h "$file") >/dev/null 2>&1 \
-	|| test -f "$file"; then
-	:
-      elif test -d "$file"; then
-	exit_status=1
-	continue
-      elif test "$rmforce" = yes; then
-	continue
-      fi
-
-      rmfiles="$file"
-
-      case $name in
-      *.la)
-	# Possibly a libtool archive, so verify it.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  . $dir/$name
-
-	  # Delete the libtool libraries and symlinks.
-	  for n in $library_names; do
-	    rmfiles="$rmfiles $objdir/$n"
-	  done
-	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
-
-	  case "$mode" in
-	  clean)
-	    case "  $library_names " in
-	    # "  " in the beginning catches empty $dlname
-	    *" $dlname "*) ;;
-	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
-	    esac
-	     test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
-	    ;;
-	  uninstall)
-	    if test -n "$library_names"; then
-	      # Do each command in the postuninstall commands.
-	      cmds=$postuninstall_cmds
-	      save_ifs="$IFS"; IFS='~'
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd"
-		if test "$?" -ne 0 && test "$rmforce" != yes; then
-		  exit_status=1
-		fi
-	      done
-	      IFS="$save_ifs"
-	    fi
-
-	    if test -n "$old_library"; then
-	      # Do each command in the old_postuninstall commands.
-	      cmds=$old_postuninstall_cmds
-	      save_ifs="$IFS"; IFS='~'
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd"
-		if test "$?" -ne 0 && test "$rmforce" != yes; then
-		  exit_status=1
-		fi
-	      done
-	      IFS="$save_ifs"
-	    fi
-	    # FIXME: should reinstall the best remaining shared library.
-	    ;;
-	  esac
-	fi
-	;;
-
-      *.lo)
-	# Possibly a libtool object, so verify it.
-	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-
-	  # Read the .lo file
-	  . $dir/$name
-
-	  # Add PIC object to the list of files to remove.
-	  if test -n "$pic_object" \
-	     && test "$pic_object" != none; then
-	    rmfiles="$rmfiles $dir/$pic_object"
-	  fi
-
-	  # Add non-PIC object to the list of files to remove.
-	  if test -n "$non_pic_object" \
-	     && test "$non_pic_object" != none; then
-	    rmfiles="$rmfiles $dir/$non_pic_object"
-	  fi
-	fi
-	;;
-
-      *)
-	if test "$mode" = clean ; then
-	  noexename=$name
-	  case $file in
-	  *.exe)
-	    file=`$echo $file|${SED} 's,.exe$,,'`
-	    noexename=`$echo $name|${SED} 's,.exe$,,'`
-	    # $file with .exe has already been added to rmfiles,
-	    # add $file without .exe
-	    rmfiles="$rmfiles $file"
-	    ;;
-	  esac
-	  # Do a test to see if this is a libtool program.
-	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	    relink_command=
-	    . $dir/$noexename
-
-	    # note $name still contains .exe if it was in $file originally
-	    # as does the version of $file that was added into $rmfiles
-	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
-	    if test "$fast_install" = yes && test -n "$relink_command"; then
-	      rmfiles="$rmfiles $objdir/lt-$name"
-	    fi
-	    if test "X$noexename" != "X$name" ; then
-	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
-	    fi
-	  fi
-	fi
-	;;
-      esac
-      $show "$rm $rmfiles"
-      $run $rm $rmfiles || exit_status=1
-    done
-    objdir="$origobjdir"
-
-    # Try to remove the ${objdir}s in the directories where we deleted files
-    for dir in $rmdirs; do
-      if test -d "$dir"; then
-	$show "rmdir $dir"
-	$run rmdir $dir >/dev/null 2>&1
-      fi
-    done
-
-    exit $exit_status
-    ;;
-
-  "")
-    $echo "$modename: you must specify a MODE" 1>&2
-    $echo "$generic_help" 1>&2
-    exit $EXIT_FAILURE
-    ;;
-  esac
-
-  if test -z "$exec_cmd"; then
-    $echo "$modename: invalid operation mode \`$mode'" 1>&2
-    $echo "$generic_help" 1>&2
-    exit $EXIT_FAILURE
-  fi
-fi # test -z "$show_help"
-
-if test -n "$exec_cmd"; then
-  eval exec $exec_cmd
-  exit $EXIT_FAILURE
-fi
-
-# We need to display help for each of the modes.
-case $mode in
-"") $echo \
-"Usage: $modename [OPTION]... [MODE-ARG]...
-
-Provide generalized library-building support services.
-
-    --config          show all configuration variables
-    --debug           enable verbose shell tracing
--n, --dry-run         display commands without modifying any files
-    --features        display basic configuration information and exit
-    --finish          same as \`--mode=finish'
-    --help            display this help message and exit
-    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
-    --quiet           same as \`--silent'
-    --silent          don't print informational messages
-    --tag=TAG         use configuration variables from tag TAG
-    --version         print version information
-
-MODE must be one of the following:
-
-      clean           remove files from the build directory
-      compile         compile a source file into a libtool object
-      execute         automatically set library path, then run a program
-      finish          complete the installation of libtool libraries
-      install         install libraries or executables
-      link            create a library or an executable
-      uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE.
-
-Report bugs to <bug-libtool@gnu.org>."
-  exit $EXIT_SUCCESS
-  ;;
-
-clean)
-  $echo \
-"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
-
-Remove files from the build directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, object or program, all the files associated
-with it are deleted. Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-compile)
-  $echo \
-"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
-  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
-  -prefer-pic       try to building PIC objects only
-  -prefer-non-pic   try to building non-PIC objects only
-  -static           always build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
-  ;;
-
-execute)
-  $echo \
-"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
-  -dlopen FILE      add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
-  ;;
-
-finish)
-  $echo \
-"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges.  Use
-the \`--dry-run' option if you just want to see what would be executed."
-  ;;
-
-install)
-  $echo \
-"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command.  The first component should be
-either the \`install' or \`cp' program.
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
-  ;;
-
-link)
-  $echo \
-"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
-  -all-static       do not do any dynamic linking at all
-  -avoid-version    do not add a version suffix if possible
-  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
-  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
-  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-  -export-symbols SYMFILE
-		    try to export only the symbols listed in SYMFILE
-  -export-symbols-regex REGEX
-		    try to export only the symbols matching REGEX
-  -LLIBDIR          search LIBDIR for required installed libraries
-  -lNAME            OUTPUT-FILE requires the installed library libNAME
-  -module           build a library that can dlopened
-  -no-fast-install  disable the fast-install mode
-  -no-install       link a not-installable executable
-  -no-undefined     declare that a library does not refer to external symbols
-  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -objectlist FILE  Use a list of object files found in FILE to specify objects
-  -precious-files-regex REGEX
-                    don't remove output files matching REGEX
-  -release RELEASE  specify package release information
-  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
-  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
-  -static           do not do any dynamic linking of libtool libraries
-  -version-info CURRENT[:REVISION[:AGE]]
-		    specify library version info [each variable defaults to 0]
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename.  Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
-  ;;
-
-uninstall)
-  $echo \
-"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
-
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-*)
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$help" 1>&2
-  exit $EXIT_FAILURE
-  ;;
-esac
-
-$echo
-$echo "Try \`$modename --help' for more information about other modes."
-
-exit $?
-
-# The TAGs below are defined such that we never get into a situation
-# in which we disable both kinds of libraries.  Given conflicting
-# choices, we go for a static library, that is the most portable,
-# since we can't tell whether shared libraries were disabled because
-# the user asked for that or because the platform doesn't support
-# them.  This is particularly important on AIX, because we don't
-# support having both static and shared libraries enabled at the same
-# time on that platform, so we default to a shared-only configuration.
-# If a disable-shared tag is given, we'll fallback to a static-only
-# configuration.  But we'll never go from static-only to shared-only.
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-disable_libs=shared
-# ### END LIBTOOL TAG CONFIG: disable-shared
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-static
-disable_libs=static
-# ### END LIBTOOL TAG CONFIG: disable-static
-
-# Local Variables:
-# mode:shell-script
-# sh-indentation:2
-# End:
diff -Naur usbip-0.1.4/src/Makefile.am trunk/src/Makefile.am
--- usbip-0.1.4/src/Makefile.am	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/Makefile.am	2007-05-18 11:10:08.000000000 +0200
@@ -1,3 +1,8 @@
 SUBDIRS = lib cmd
 includedir=@includedir@/usbip
+include_HEADERS = lib/usbip.h lib/usbip_common.h lib/vhci_driver.h lib/stub_driver.h
 
+if INSTALL_USBIDS
+pkgdata_DATA = usb.ids
+EXTRA_DIST = $(pkgdata_DATA)
+endif
diff -Naur usbip-0.1.4/src/NEWS trunk/src/NEWS
--- usbip-0.1.4/src/NEWS	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/NEWS	2007-05-18 11:10:08.000000000 +0200
@@ -1,5 +1,20 @@
 # vim:tw=78:ts=4:expandtab:ai:sw=4
-# $Id: NEWS 208 2006-11-12 15:22:24Z taka-hir $
+# $Id: NEWS 243 2007-02-06 12:50:03Z taka-hir $
+
+usbip-0.1.5
+    - Fix: "make dist" works.
+    - Cleanup: use autoreconf instead.
+    - Cleanup: change vhci_driver as a global value in libusbip.
+    - Cleanup: change stub_driver as a global value in libusbip.
+    - Cleanup: trim unused spaces.
+    - Add: version info in configure.ac
+    - Fix: auto detection of "glib-2.0 >= 2.6.0"
+    - Add: mailing list information in README
+    - Cleanup: use daemon(3), instead.
+    - Add: usb.ids 
+    - setsockopt in userland
+    - Add: 2.6.20 support?
+    - Fix: use spin_lock_init() instead of SPIN_...
 
 usbip-0.1.4
     - Fix: compile error & warning fix for 2.6.19
diff -Naur usbip-0.1.4/src/README trunk/src/README
--- usbip-0.1.4/src/README	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/README	2007-05-18 11:10:08.000000000 +0200
@@ -2,7 +2,7 @@
 #
 # README for usbip-utils
 #
-# Copyright (C) 2005-2006 Takahiro Hirofuchi <taka-hir@is.naist.jp>
+# Copyright (C) 2005-2007 Takahiro Hirofuchi <taka-hir@is.naist.jp>
 
 
 [Note]
@@ -17,24 +17,18 @@
     - libwrap0-dev
         tcp wrapper library
 
-    - hwdata
-        /usr/share/hwdata/usb.ids
-
     - usbip device drivers
         For mainline kernels, it is included under usbip-utils/drivers/.
 
     - gcc >= 4.0
 
-    - libglib2.0-dev
+    - libglib2.0-dev >= 2.6.0
 
     - libtool, automake-1.9, autoconf >= 2.5.0, pkg-config
 
 [Install]
     0. Skip here if you see a configure script.
-        $ aclocal
-        $ autoheader
-        $ automake-1.9 -a -c -f
-        $ autoconf
+        $ ./autogen.sh
 
     1. Compile & install.
         $ ./configure
diff -Naur usbip-0.1.4/src/setup trunk/src/setup
--- usbip-0.1.4/src/setup	2007-05-18 11:10:10.000000000 +0200
+++ trunk/src/setup	1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-#!/bin/sh -x
-
-aclocal
-autoheader
-automake-1.9 -acf
-autoconf
diff -Naur usbip-0.1.4/src/usb.ids trunk/src/usb.ids
--- usbip-0.1.4/src/usb.ids	1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/usb.ids	2007-05-18 11:10:08.000000000 +0200
@@ -0,0 +1,5971 @@
+#
+#	List of USB ID's
+#
+#	Maintained by Vojtech Pavlik <vojtech@suse.cz>
+#	If you have any new entries, send them to the maintainer.
+#	Send entries as patches (diff -u old new).
+#	The latest version can be obtained from
+#		http://www.linux-usb.org/usb.ids
+#
+# $Id: usb.ids,v 1.230 2006/12/12 21:43:04 dbrownell Exp $
+#
+
+# Vendors, devices and interfaces. Please keep sorted.
+
+# Syntax:
+# vendor  vendor_name
+#	device  device_name				<-- single tab
+#		interface  interface_name		<-- two tabs
+
+0001  Fry's Electronics
+0002  Ingram
+0003  Club Mac
+0004  Nebraska Furniture Mart
+0386  LTS
+	0001  PSX for USB Converter
+03e8  EndPoints, Inc.
+	0004  SE401 WebCam
+	0008  101 Ethernet [klsi]
+03e9  Thesys Microelectronics
+03ea  Data Broadcasting Corp.
+03eb  Atmel Corp.
+	2002  Mass Storage Device
+	2015  at90usbkey sample firmware (HID keyboard)
+	2018  at90usbkey sample firmware (CDC ACM)
+	2019  stk525 sample firmware (microphone)
+	201c  at90usbkey sample firmware (HID mouse)
+	201d  at90usbkey sample firmware (HID generic)
+	2022  at90usbkey sample firmware (composite device)
+	2103  JTAG ICE mkII
+	2104  AVR ISP mkII
+	2107  AVR Dragon
+	2ffb  at90usb AVR DFU bootloader
+	2ffd  at89c5130/c5131 DFU bootloader
+	2fff  at89c5132/c51snd1c DFU bootloader
+	3301  at43301 4-port Hub
+	3312  4-port Hub
+	5601  at76c510 Prism-II 802.11b Access Point
+	5603  Cisco 7920 WiFi IP Phone
+	6124  at91sam SAMBA bootloader
+	7603  at76c503a D-Link DWL-120 802.11b Adapter
+	7605  at76c503a 802.11b Adapter
+	7606  at76c505 802.11b Adapter
+	7611  at76c510 rfmd2948 802.11b Access Point
+03ec  Iwatsu America, Inc.
+03ed  Mitel Corp.
+03ee  Mitsumi
+	0000  CD-R/RW Drive
+	641f  WIF-0402C Bluetooth Adapter
+	6440  WML-C52APR Bluetooth Adapter
+	6901  SmartDisk FDD
+03f0  Hewlett-Packard
+	0004  DeskJet 895c
+	0101  ScanJet 4100c
+	0102  PhotoSmart S20
+	0104  DeskJet 880c/970c
+	0105  ScanJet 4200c
+	0107  CD-Writer Plus
+	010c  Multimedia Keyboard Hub
+	0111  G55xi Printer/Scanner/Copier
+	011c  hn210w 802.11b Adapter
+	0121  HP49g+ Calculator
+	0201  ScanJet 6200c
+	0202  PhotoSmart S20
+	0204  DeskJet 815c
+	0205  ScanJet 3300c
+	0207  CD-Writer Plus 8200e
+	020c  Multimedia Keyboard
+	0304  DeskJet 810c/812c
+	0305  ScanJet 4300c
+	0311  OfficeJet G85xi
+	0317  LaserJet 1200
+	0401  ScanJet 5200c
+	0404  DeskJet 830c/832c
+	0405  ScanJet 3400cse
+	0504  DeskJet 885c
+	0505  ScanJet 2100c
+	050c  5219 Wireless Keyboard
+	0517  LaserJet 1000
+	0601  ScanJet 6300c
+	0604  DeskJet 840c
+	0605  ScanJet 2200c
+	0701  ScanJet 5300c/5370c
+	0704  DeskJet 825c
+	0705  ScanJet 4400c
+	0712  DeskJet 1180c
+	0801  ScanJet 7400c
+	0804  DeskJet 816c
+	0901  ScanJet 2300c
+	0904  DeskJet 845c
+	1004  DeskJet 970c/970cse
+	1005  ScanJet 5400c
+	1016  Jornada 548 / iPAQ HW6515 Pocket PC 
+	1104  DeskJet 959c
+	1105  ScanJet 5470c
+	1116  Jornada 568 Pocket PC
+	1151  750xi Printer/Scanner/Copier
+	1204  DeskJet 930c
+	1305  ScanJet 4570c
+	1317  LaserJet 1005
+	1405  Scanjet 3670
+	1504  DeskJet 920c
+	1604  DeskJet 940c
+	1904  DeskJet 3820
+	1c17  Color LaserJet 2550l
+	1e11  PSC-950
+	2002  Hub
+	2004  DeskJet 640c
+	2005  ScanJet 3570c
+	2104  DeskJet 630c
+	2205  ScanJet 3500c
+	2304  DeskJet 656c
+	2305  ScanJet 3970c
+	2811  PSC-2100
+	2d11  OfficeJet 6110
+	3102  PhotoSmart P1100 Printer w/ Card Reader
+	3104  DeskJet 960c
+	3304  DeskJet 990c
+	3404  DeskJet 6122
+	3504  DeskJet 6127c
+	3c02  PhotoSmart 7350
+	3d11  OfficeJet 4215
+	3f11  PSC-1315/PSC-1317
+	4002  PhotoSmart 720 / PhotoSmart 935 (storage)
+	4102  PhotoSmart 618
+	4202  PhotoSmart 812
+	4302  PhotoSmart 850 (ptp)
+	4402  PhotoSmart 935 (ptp)
+	5004  DeskJet 995c
+	6004  DeskJet 5550
+	6104  DeskJet 5650c
+	6202  PhotoSmart 215
+	6204  DeskJet 5150c
+	6302  PhotoSmart 318/612
+	6402  PhotoSmart 715 (ptp)
+	6502  PhotoSmart 120 (ptp)
+	6602  PhotoSmart 320
+	6702  PhotoSmart 720 (ptp)
+	6802  PhotoSmart 620 (ptp)
+	6a02  PhotoSmart 735 (ptp)
+	7004  DeskJet 3320c
+	7104  DeskJet 3420c
+	7202  PhotoSmart 43x (ptp)
+	7204  DeskJet 36xx
+	7304  DeskJet 35xx
+	a004  DeskJet 5850c
+	bef4  NEC Picty760
+	efbe  NEC Picty900
+	f0be  NEC Picty920
+	f1be  NEC Picty800
+03f1  Genoa Technology
+03f2  Oak Technology, Inc.
+03f3  Adaptec, Inc.
+03f4  Diebold, Inc.
+03f5  Siemens Electromechanical
+03f8  Epson Imaging Technology Center
+03f9  KeyTronic Corp.
+03fb  OPTi, Inc.
+03fc  Elitegroup Computer Systems
+03fd  Xilinx, Inc.
+03fe  Farallon Comunications
+0400  National Semiconductor Corp.
+	0807  Bluetooth Dongle
+	1000  Mustek BearPaw 1200 Scanner
+	1001  Mustek BearPaw 2400 Scanner
+0401  National Registry, Inc.
+0402  ALi Corp.
+	5462  M5462 IDE Controller
+	5603  USB 2.0 Q-tec Webcam 300
+	5621  USB 2.0 Storage Device
+	5632  USB 2.0 Host-to-Host Link
+	5637  M5637 IDE Controller
+0403  Future Technology Devices International, Ltd
+	0000  H4SMK 7 Port Hub
+	6001  8-bit FIFO
+	8040  4 Port Hub
+	8070  7 Port Hub
+	8370  7 Port Hub
+	8371  PS/2 Keyboard And Mouse
+	8372  FT8U100AX Serial Port
+	ea90  Eclo 1-Wire Adapter
+	f208  Papenmeier Braille-Display
+	fd48  ShipModul MiniPlex-4xUSB NMEA Multiplexer
+	ff08  ToolHouse LoopBack Adapter
+0404  NCR Corp.
+	0310 K590 Printer, Self-Service
+	0311 7167 Printer, Receipt/Slip
+	0312 7197 Printer Receipt
+	0320 5932-USB Keyboard
+	0321 5953-USB Dynakey
+	0322 5932-USB Enhanced Keyboard
+	0323 5932-USB Enhanced Keyboard, Flash-Recovery/Download
+	0324 5953-USB Enhanced Dynakey
+	0325 5953-USB Enhanced Dynakey Flash-Recovery/Download
+	0328 K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages)
+	0329 K018: USB-MSR JIS 2-Track MSR: POS Standard
+	032a K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode
+	032b K016/K018: USB-MSR Flash-Recovery/Download
+0405  Synopsys, Inc.
+0406  Fujitsu-ICL Computers
+0407  Fujitsu Personal Systems, Inc.
+0408  Quanta Computer, Inc.
+0409  NEC Corp.
+	0012  ATerm IT75DSU ISDN TA
+	0014  Japanese Keyboard
+	0027  MultiSync Monitor
+	0058  HighSpeed Hub
+	0059  HighSpeed Hub
+	006a  Conceptronic USB Harddisk Box
+	011d  e228 Mobile Phone
+	55aa  Hub
+	55ab  Hub [iMac/iTouch kbd]
+	efbe  P!cty 900 [HP DJ]
+	f0be  P!cty 920 [HP DJ 812c]
+040a  Kodak Co.
+	0001  DVC-323
+	0002  DVC-325
+	0100  DC-220
+	0110  DC-260
+	0111  DC-265
+	0112  DC-290
+	0120  DC-240
+	0121  DC-240 (PTP firmware)
+	0130  DC-280
+	0131  DC-5000
+	0132  DC-3400
+	0140  DC-4800
+	0160  DC4800
+	0170  DX3900
+	0300  EZ-200
+	0400  MC3
+	0500  DX3500
+	0510  DX3600
+	0525  DX3215
+	0530  DX3700
+	0535  EasyShare CX4230 Camera
+	0540  LS420
+	0550  DX4900
+	0555  DX4330
+	0560  CX4200
+	0565  CX4210
+	0566  CX4300
+	0568  LS443
+	0569  LS663
+	0570  DX6340
+	0571  CX6330
+	0572  DX6440
+	0573  CX6230
+	0574  CX6200
+	0575  DX6490
+	0576  DX4530
+	057c  CX7530
+	057f  DX7590
+	5010  Wireless Adapter
+040b  Weltrend Semiconductor
+	6510  Weltrend Bar Code Reader
+	6520  XBOX Xploder
+040c  VTech Computers, Ltd
+040d  VIA Technologies, Inc.
+040e  MCCI
+040f  Echo Speech Corp.
+0411  MelCo., Inc.
+	0001  LUA-TX Ethernet [pegasus]
+	0016  WLI-USB-S11 802.11b Adapter
+	0027  WLI-USB-KS11G 802.11b Adapter
+0412  Award Software International
+0413  Leadtek Research, Inc.
+	6025  WinFast DTV Dongle (cold state)
+	6026  WinFast DTV Dongle (warm state)
+	6f00  WinFast DTV Dongle (STK7700P based)
+0414  Giga-Byte Technology Co., Ltd
+0416  Winbond Electronics Corp.
+	0961  AVL Flash Card Reader
+	5518  4-Port Hub
+	551a  PC Sync Keypad
+	551b  PC Async Keypad
+	551c  Sync Tenkey
+	551d  Async Tenkey
+	551e  Keyboard
+	551f  Keyboard w/ Sys and Media
+	5521  Keyboard
+	7723  SD Card Reader
+	6481  16-bit Scanner
+0417  Symbios Logic
+0418  AST Research
+0419  Samsung Info. Systems America, Inc.
+	0001  IrDA Remote Controller
+	3001  Xerox P1202 Laser Printer
+	8002  SyncMaster 757DFX HID Device
+041a  Phoenix Technologies, Ltd
+041b  d'TV
+041d  S3, Inc.
+041e  Creative Technology, Ltd
+	1002  Nomad II
+	1003  Blaster GamePad Cobra
+	1050  GamePad Cobra
+	3010  SoundBlaster MP3+
+	3020  SoundBlaster Audigy 2 NX
+	4003  VideoBlaster WebCam Go Plus [W9967CF]
+	4004  Nomad II MG
+	4005  WebCam Blaster Go ES
+	400a  PC-Cam 300
+	400b  PC-Cam 600
+	400c  WebCam 5 [pwc]
+	400d  WebCam PD1001
+	4011  WebCam PRO eX
+	4013  PC-Cam 750
+	4015  CardCam Value
+	4017  WebCam Mobile
+	4018  WebCam Vista
+	401c  WebCam NX [PD1110]
+	401d  WebCam NX Ultra
+	401e  WebCam NX Pro
+	401f  Webcam Notebook
+	4036  Webcam Live!/Live! Pro
+	403a  WebCam NX Pro 2
+	403c  WebCam Live! Ultra
+	403d  WebCam Notebook Ultra
+	4100  Nomad Jukebox 2
+	4101  Nomad Jukebox 3
+	4106  Nomad MuVo
+	4108  Nomad Jukebox Zen
+	4109  Nomad Jukebox Zen NX
+	410b  Nomad Jukebox Zen USB 2.0
+	410c  Nomad MuVo NX
+	4110  Nomad Jukebox Zen Xtra
+	4111  Dell Digital Jukebox
+	4116  MuVo^2
+	4117  Nomad MuVo TX
+	411b  Zen Touch
+	411d  Zen
+	411e  Zen Micro
+	4123  Zen Portable Media Center
+	4126  Dell DJ (2nd gen)
+	4127  Dell DJ
+	412b  MuVo N200 with FM radio
+	4134  Zen Neeon
+	4136  Zen Sleek
+	4139  Zen Nano Plus
+	413c  Zen MicroPhoto
+041f  LCS Telegraphics
+0420  Chips and Technologies
+0421  Nokia Mobile Phones
+	0401  6650 GSM Phone
+	0405  9500 GSM Communicator
+	040b  N-Gage GSM Phone
+	040f  6230 GSM Phone
+	0410  6630 Imaging Smartphone
+	0415  9300 GSM Smartphone
+	0418  E-70 (PC-Suite mode)
+	041a  9500 GSM Communicator (RNDIS)
+	041b  9300 GSM Smartphone (RNDIS)
+	0429  6230i Camera Phone
+	0435  E-70 (IP Passthrough/RNDIS mode)
+	0800  Connectivity Cable DKU-5
+0422  ADI Systems, Inc.
+0423  Computer Access Technology Corp.
+	000a  NetMate Ethernet
+	000c  NetMate2 Ethernet
+	000d  USB Chief Analyzer
+	1237  Andromeda Hub
+0424  Standard Microsystems Corp.
+	20fc  6-in-1 Card Reader
+	223a  8-in-1 Card Reader
+0425  Motorola Semiconductors HK, Ltd
+	0101  G-Tech Wireless Mouse & Keyboard
+0426  Integrated Device Technology, Inc.
+0427  Motorola Electronics Taiwan, Ltd
+0428  Advanced Gravis Computer Tech, Ltd
+	4001  GamePad Pro
+0429  Cirrus Logic
+042a  Ericsson Austrian, AG
+042b  Intel Corp.
+042c  Innovative Semiconductors, Inc.
+042d  Micronics
+042e  Acer, Inc.
+042f  Molex, Inc.
+0430  Sun Microsystems, Inc.
+	0005  Type 6 Keyboard
+	0100  3-button Mouse
+0431  Itac Systems, Inc.
+0432  Unisys Corp.
+0433  Alps Electric, Inc.
+	1101  IBM Game Controller
+0434  Samsung Info. Systems America, Inc.
+0435  Hyundai Electronics America
+0436  Taugagreining HF
+0437  Framatome Connectors USA
+0438  Advanced Micro Devices, Inc.
+0439  Voice Technologies Group
+043d  Lexmark International, Inc.
+	0002  Optra E310 Printer
+	0009  Optra S2450 Printer
+	000c  Optra E312 Printer
+	0017  Z32 printer
+	0018  Z52 Printer
+	001a  Z65 Printer
+	001c  Kodak Personal Picture Maker 200 Printer
+	001f  Kodak Personal Picture Maker 200 Card Reader
+	0020  Z51 Printer
+	0021  Z33 Printer
+	002d  X70/X73 Scan/Print/Copy
+	003d  X83 Scan/Print/Copy
+	0057  Z35 Printer
+	0060  X74/X75 Scanner
+	0061  X74 Hub
+	0069  X74/X75 Printer
+	0072  X6170 Printer
+043e  LG Electronics USA, Inc.
+	42bd  Flatron 795FT Plus Monitor
+	4a4d  Flatron 915FT Plus Monitor
+	7001  MF-PD100 Soul Digital MP3 Player
+	8484  LPC-U30 Webcam II
+	8585  LPC-UC35 Webcam
+043f  RadiSys Corp.
+0440  Eizo Nanao Corp.
+0441  Winbond Systems Lab.
+	1456  Hub
+0442  Ericsson, Inc.
+0443  Gateway, Inc.
+0445  Lucent Technologies, Inc.
+0446  NMB Technologies Corp.
+0447  Momentum Microsystems
+044a  Shamrock Tech. Co., Ltd
+044b  WSI
+044c  CCL/ITRI
+044d  Siemens Nixdorf AG
+044e  Alps Electric Co., Ltd
+	2002  MD-5500 Printer
+	3001  UGTZ4 Bluetooth
+044f  ThrustMaster, Inc.
+	0400  HOTAS Cougar
+	a0a3  Fusion Digital GamePad
+	b203  360 Modena Pro Wheel
+	b300  Firestorm Dual Power
+	b304  Firestorm Dual Power
+0450  DFI, Inc.
+0451  Texas Instruments, Inc.
+	1428  Hub
+	1446  TUSB2040/2070 Hub
+	2036  TUSB2036 Hub
+	2046  TUSB2046 Hub
+	2077  TUSB2077 Hub
+	3410  TUSB3410 Microcontroller
+	5409  Frontier Labs NEX IA+ Digital Audio Player
+	6000  AU5 ADSL Modem (pre-reenum)
+	6001  AU5 ADSL Modem
+	e001  GraphLink
+	e004  TI-89 Titanium Calculator
+	e008  TI-84 Plus Silver Calculator
+0452  Mitsubishi Electronics America, Inc.
+	0050  Diamond Pro 900u CRT Monitor
+	0051  Integrated Hub
+0453  CMD Technology
+0454  Vobis Microcomputer AG
+0455  Telematics International, Inc.
+0456  Analog Devices, Inc.
+0457  Silicon Integrated Systems Corp.
+	0150  Super Talent 1GB Flash Drive
+	0151  Super Flash 1GB Flash Drive
+0458  KYE Systems Corp. (Mouse Systems)
+	0001  Mouse
+	0002  Genius NetMouse Pro
+	0003  Genius NetScroll+
+	000e  VideoCAM Web
+	001a  Genius WebScroll+
+	004c  Slimstar Pro Keyboard
+	0100  EasyPen Tablet
+	0101  CueCat
+	1003  Genius VideoCam
+	1004  Flight2000 F-23 Joystick
+	100a  Aashima Technology Trust Sight Fighter Vibration Feedback Joystick
+	2001  ColorPage-Vivid Pro Scanner
+	2007  ColorPage-HR6 V2 Scanner
+	2008  ColorPage-HR6 V2 Scanner
+	2009  ColorPage-HR6A Scanner
+	2011  ColorPage-Vivid3x Scanner
+	2013  ColorPage-HR7 Scanner
+	2015  ColorPage-HR7LE Scanner
+	2016  ColorPage-HR6X Scanner
+	301d  Genius MaxFire MiniPad
+	7004  VideoCAM Express
+	7007  VideoCAM Web
+	7012  WebCAM USB2.0
+0459  Adobe Systems, Inc.
+045a  SONICblue, Inc.
+	0b4a  SupraMax 2890 56K Modem [Lucent Atlas]
+	0b68  SupraMax 56K Modem
+	5210  Rio Karma Music Player
+	5220  Rio Nitrus MP3 Player
+045b  Hitachi, Ltd
+045d  Nortel Networks, Ltd
+045e  Microsoft Corp.
+	0007  SideWinder Game Pad
+	0008  SideWinder Precision Pro
+	0009  IntelliMouse
+	000b  Natural Keyboard Elite
+	0014  Digital Sound System 80
+	001a  SideWinder Precision Racing Wheel
+	001b  SideWinder Force Feedback 2 Joystick
+	001d  Natural Keyboard Pro
+	001e  IntelliMouse Explorer
+	0023  Trackball Optical
+	0024  Trackball Explorer
+	0025  IntelliEye Mouse
+	0026  SideWinder GamePad Pro
+	0027  SideWinder PnP GamePad
+	0028  SideWinder Dual Strike
+	0029  IntelliMouse Optical
+	002b  Internet Keyboard Pro
+	0033  Sidewinder Strategic Commander
+	0034  SideWinder Force Feedback Wheel
+	0038  SideWinder Precision 2
+	0039  IntelliMouse Optical
+	003b  SideWinder Game Voice
+	003c  SideWinder Joystick
+	0040  Wheel Mouse Optical
+	0047  IntelliMouse Explorer 3.0
+	0059  Wireless IntelliMouse Explorer
+	006e  MN510 802.11b Adapter
+	007d  Notebook Optical Mouse
+	007e  Wireless Transceiver for Bluetooth
+	0083  Basic Optical Mouse
+	008a  Wireless Keyboard and Mouse
+	008c  Wireless Intellimouse Explorer 2.0
+	00b9  Wireless Optical Mouse 3.0
+	00bd  Fingerprint Reader
+	0284  Xbox DVD Playback Kit
+	0288  Xbox Controller S Hub
+	0289  Xbox Controller S
+0460  Ace Cad Enterprise Co., Ltd
+0461  Primax Electronics, Ltd
+	0300  G2-300 Scanner
+	0301  G2E-300 Scanner
+	0302  G2-300 #2 Scanner
+	0303  G2E-300 #2 Scanner
+	0340  Colorado 9600 Scanner
+	0341  Colorado 600u Scanner
+	0345  Visioneer 6200 Scanner
+	0346  Memorex Maxx 6136u Scanner
+	0347  Primascan Colorado 2600u/Visioneer 4400 Scanner
+	0360  Colorado 19200 Scanner
+	0361  Colorado 1200u Scanner
+	0364  LG Electronics Scanworks 600U Scanner
+	0371  Visioneer Onetouch 8920 Scanner
+	0377  Medion MD 5345 Scanner
+	037b  Medion MD 6190 Scanner
+	0380  G2-600 Scanner
+	0381  ReadyScan 636i Scanner
+	0382  G2-600 #2 Scanner
+	0383  G2E-600 Scanner
+	0813  IBM UltraPort Camera
+	0815  Micro Innovations WebCam
+	0819  Fujifilm IX-30 Camera [webcam mode]
+	081a  Fujifilm IX-30 Camera [storage mode]
+	081c  Elitegroup ECS-C11 Camera
+	081d  Elitegroup ECS-C11 Storage
+	4d01  Comfort Keyboard
+	4d02  Mouse-in-a-Box
+	4d03  Kensington Mouse-in-a-box
+	4d04  Mouse
+0463  MGE UPS Systems
+	0001  UPS
+	ffff  UPS
+0464  AMP/Tycoelectronics Corp.
+0467  AT&T Paradyne
+0468  Wieson Technologies Co., Ltd
+046a  Cherry GmbH
+	0001  My3000 Keyboard
+	0003  My3000 Hub
+	0005  XX33 SmartCard Reader Keyboard
+	0023  Cymotion Master Linux Keyboard
+046b  American Megatrends, Inc.
+046c  Toshiba Corp., Digital Media Equipment
+046d  Logitech, Inc.
+	0203  M2452 Keyboard
+	0301  M4848 Mouse
+	0401  HP PageScan
+	0402  NEC PageScan
+	040f  Logitech/Storm PageScan
+	0801  QuickCam Home
+	0810  QuickCam Pro
+	0840  QuickCam Express
+	0850  QuickCam Web
+	0870  QuickCam Express
+	0890  QuickCam Traveler
+	08a0  QuickCam IM
+	08a2  Labtec WebCam Pro
+	08b0  QuickCam 3000 Pro [pwc]
+	08b1  QuickCam Notebook Pro
+	08b2  QuickCam Pro 4000
+	08b3  QuickCam Zoom
+	08b4  QuickCam Zoom
+	08da  QuickCam Messanger
+	08f0  QuickCam Messenger
+	0900  ClickSmart 310
+	0901  ClickSmart 510
+	0903  ClickSmart 820
+	0905  ClickSmart 820
+	0920  QuickCam Express
+	0921  Labtec WebCam
+	0928  Quickcam Express
+	092a  QuickCam for Notebooks
+	0950  Pocket Camera
+	0960  ClickSmart 420
+	0970  Pocket750
+	c000  N43 [Pilot Mouse]
+	c001  N48/M-BB48 [FirstMouse Plus]
+	c002  M-BA47 [MouseMan Plus]
+	c004  WingMan Gaming Mouse
+	c00b  MouseMan Wheel
+	c00c  Optical Wheel Mouse
+	c00e  M-BJ69 Optical Wheel Mouse
+	c012  Optical Mouse
+	c016  M-UV69a Optical Wheel Mouse
+	c01b  MX310 Optical Mouse
+	c01e  MX518 Optical Mouse
+	c025  MX500 Optical Mouse
+	c030  iFeel Mouse
+	c032  MouseMan iFeel
+	c03e  Premium Optical Wheel Mouse
+	c202  WingMan Formula
+	c207  WingMan Extreme Digital 3D
+	c208  WingMan Gamepad Extreme
+	c209  WingMan Gamepad
+	c20a  WingMan RumblePad
+	c20c  WingMan Precision
+	c211  iTouch Cordless Reciever
+	c216  Dual Action Gamepad
+	c281  WingMan Force
+	c283  WingMan Force 3D
+	c285  WingMan Strike Force 3D
+	c291  WingMan Formula Force
+	c293  WingMan Formula Force GP
+	c295  Momo Force Steering Wheel
+	c2a0  Wingman Force Feedback Mouse
+	c303  iTouch Keyboard
+	c308  Internet Navigator Keyboard
+	c309  Internet Keyboard
+	c401  TrackMan Marble Wheel
+	c402  Marble Mouse (2-button)
+	c404  TrackMan Wheel
+	c408  Marble Mouse (4-button)
+	c501  Cordless Mouse Receiver
+	c503  Cordless Mouse+Keyboard Receiver
+	c504  Cordless Mouse+Keyboard Receiver
+	c505  Cordless Mouse+Keyboard Receiver
+	c506  MX-700 Cordless Mouse Receiver
+	c50b  Cordless Desktop Optical
+	c50e  MX-1000 Cordless Mouse Receiver
+	d001  QuickCam Pro
+046e  Behavior Tech. Computer Corp.
+	6782  BTC 7932 mouse+keyboard
+046f  Crystal Semiconductor
+0471  Philips
+	0101  DSS350 Digital Speaker System
+	0104  DSS330 Digital Speaker System [uda1321]
+	0201  Hub
+	0222  Creative Nomad Jukebox
+	0302  PCA645VC WebCam [pwc]
+	0303  PCA646VC WebCam [pwc]
+	0304  Askey VC010 WebCam [pwc]
+	0307  PCVC675K WebCam [pwc]
+	0308  PCVC680K WebCam [pwc]
+	030c  PCVC690K WebCam [pwc]
+	0310  PCVC730K WebCam [pwc]
+	0311  PCVC740K ToUcam Pro [pwc]
+	0312  PCVC750K WebCam [pwc]
+	0471  Digital Speaker System
+	0601  OVU1020 IR Dongle (Kbd+Mouse)
+	0701  150P1 TFT Display
+	0811  JR24 CDRW
+	1120  Creative Rhomba MP3 player
+	1801  Diva MP3 player
+0472  Chicony Electronics Co., Ltd
+	0065  PFU-65 Keyboard
+0473  Sanyo Information Business Co., Ltd
+0474  Sanyo Electric Co., Ltd
+	0701  SCP-4900 Cellphone
+0475  Relisys/Teco Information System
+0476  AESP
+0477  Seagate Technology, Inc.
+0478  Connectix Corp.
+	0001  QuickCam
+	0002  QuickClip
+0479  Advanced Peripheral Laboratories
+047a  Semtech Corp.
+047b  Silitek Corp.
+	0002  Keyboard and Mouse
+	0101  BlueTooth Keyboard and Mouse
+	020b  SK-3105 SmartCard Reader
+	1002  HP ScanJet 4300c Parallel Port
+047c  Dell Computer Corp.
+047d  Kensington
+	1003  Orbit TrackBall
+	1005  TurboBall
+	1009  Orbit TrackBall for Mac
+	101f  PocketMouse Pro
+	2010  Wireless Presentation Remote
+	4005  Gravis Eliminator GamePad Pro
+	4006  Gravis Eliminator AfterShock
+	4008  Gravis Destroyer TiltPad
+	5002  VideoCam CABO II
+	5003  VideoCam
+047e  Agere Systems, Inc. (Lucent)
+	1001  USS720 Parallel Port
+	f101  Atlas Modem
+047f  Plantronics, Inc.
+0480  Toshiba America Info. Systems, Inc.
+0481  Zenith Data Systems
+0482  Kyocera Corp.
+	000e  FS-1020D Printer
+0483  SGS Thomson Microelectronics
+	1307  Cytronix 6in1 card reader
+	163d  Cool Icam Digi-MP3
+	2016  Fingerprint Reader
+	2017  Biometric Smart Card Reader
+	7554  56k SoftModem
+0484  Specialix
+0485  Nokia Monitors
+0486  ASUS Computers, Inc.
+0487  Stewart Connector
+0488  Cirque Corp.
+0489  Foxconn / Hon Hai
+	0502  SmartMedia Card Reader Firmware Loader
+	0503  SmartMedia Card Reader
+048a  S-MOS Systems, Inc.
+048c  Alps Electric Ireland, Ltd
+048d  Integrated Technology Express, Inc.
+048f  Eicon Tech.
+0490  United Microelectronics Corp.
+0491  Capetronic
+0492  Samsung SemiConductor, Inc.
+0493  MAG Technology Co., Ltd
+0495  ESS Technology, Inc.
+0496  Micron Electronics
+0497  Smile International
+0498  Capetronic (Kaohsiung) Corp.
+0499  Yamaha Corp.
+	6001  CRW2200UX Lightspeed 2 External CD-RW Drive
+049a  Gandalf Technologies, Ltd
+049b  Curtis Computer Products
+049c  Acer Advanced Labs, Inc.
+	0002  Keyboard (???)
+049d  VLSI Technology
+049f  Compaq Computer Corp.
+	0003  iPAQ PocketPC
+	000e  Internet Keyboard
+	0018  PA-1/PA-2 MP3 Player
+	001a  S4 100 Scanner
+	0021  S200 Scanner
+	0033  801.11b Adapter [orinoco]
+	0051  KU-0133 Easy Access Interner Keyboard
+	505a  Linux-USB "CDC Subset" Device, or Itsy (experimental)
+	8511  iPAQ Networking 10/100 Ethernet [pegasus2]
+04a0  Digital Equipment Corp.
+04a1  SystemSoft Corp.
+04a2  FirePower Systems
+04a3  Trident Microsystems, Inc.
+04a4  Hitachi, Ltd
+04a5  Acer Peripherals Inc. (now BenQ Corp.)
+	0001  Keyboard
+	12a6  AcerScan C310U
+	1a20  Prisa 310U
+	1a2a  Prisa 620U
+	2022  Prisa 320U/340U
+	2040  Prisa 620UT
+	2060  Prisa 620U+/640U
+	207e  Prisa 640BU
+	20b0  S2W 3300U/4300U
+	20be  Prisa 640BT
+	20c0  Prisa 1240UT
+	20de  S2W 4300U+
+	20fc  Benq 5000
+	20fe  SW2 5300U
+	3003  Benq WebCam
+	3008  Benq 1500
+	300a  Benq 3410
+	300c  Benq 1016
+	9213  Kbd Hub
+04a6  Nokia Display Products
+04a7  Visioneer
+	0211  OneTouch 7600 Scanner
+	0221  OneTouch 5300 Scanner
+	0224  OneTouch 4800 USB/Microtek Scanport 3000
+	0226  OneTouch 5300 USB
+	0231  6100 Scanner
+	0311  6200 EPP/USB Scanner
+	0321  OneTouch 8100 EPP/USB Scanner
+	0331  OneTouch 8600 EPP/USB Scanner
+04a8  Multivideo Labs, Inc.
+04a9  Canon, Inc.
+	1051  BJC-3000 Color Printer
+	1056  BJC-2110 Color Printer
+	105b  S600 Printer
+	105d  S450 Printer
+	1062  S500 Printer
+	1064  S300 Printer
+	106b  S520 Printer
+	106d  S750 Printer
+	1072  I850 Printer
+	1073  I550 Printer
+	1074  S330 Printer
+	1094  PIXMA iP3000x Printer
+	2201  CanoScan FB320U
+	2202  CanoScan FB620U
+	2204  CanoScan FB630U
+	2205  CanoScan FB1210U
+	2206  CanoScan N650U/N656U
+	2207  CanoScan 1220U
+	2208  CanoScan D660U
+	220a  CanoScan D2400UF
+	220b  CanoScan D646U
+	220c  CanoScan D1250U2
+	220d  CanoScan N670U/N676U/LiDE 20
+	220e  CanoScan N1240U/LiDE 30
+	220f  CanoScan 8000F
+	2210  CanoScan 9900F
+	2212  CanoScan 5000F
+	2213  LiDE 50/LiDE 35
+	2215  CanoScan 3000/3000F/3000ex
+	2216  CanoScan 3200F
+	2217  CanoScan 5200F
+	221e  CanoScan 8400F
+	2611  SmartBase MPC400
+	262b  LaserShot LBP-1120 Printer
+	3041  PowerShot S10
+	3042  CanoScan FS4000US Film Scanner
+	3043  PowerShot S20
+	3044  EOS D30
+	3045  PowerShot S100
+	3046  IXY Digital
+	3047  Digital IXUS
+	3048  PowerShot G1
+	3049  PowerShot Pro90 IS
+	304b  IXY Digital 300
+	304c  PowerShot S300
+	304d  Digital IXUS 300
+	304e  PowerShot A20
+	304f  PowerShot A10
+	3051  PowerShot S110
+	3052  Digital IXUS V
+	3055  PowerShot G2
+	3056  PowerShot S40
+	3057  PowerShot S30
+	3058  PowerShot A40
+	3059  PowerShot A30
+	305b  ZR45MC Digital Camcorder
+	3060  EOS D60
+	3061  PowerShot A100
+	3062  PowerShot A200
+	3065  PowerShot S200
+	3066  Digital IXUS 330
+	3067  MV550i Digital Video Camera
+	3069  PowerShot G3
+	306b  MVX2i Digital Video Camera
+	306c  PowerShot S45
+	306d  PowerShot S45 PtP Mode
+	306f  PowerShot G3 (ptp)
+	3070  PowerShot S230
+	3071  PowerShot S230 (ptp)
+	3072  PowerShot SD100 / Digital IXUS 2 (ptp)
+	3073  PowerShot A70 (ptp)
+	3074  PowerShot A60 (ptp)
+	3075  IXUS 400 Camera
+	3076  PowerShot A300
+	3077  PowerShot S50
+	3078  ZR70MC Digital Camcorder
+	307b  MV630i Difital Video Camera
+	307f  Optura 20
+	3081  Optura 10
+	3083  EOS 10D
+	3084  EOS 300D / EOS Digital Rebel
+	3085  PowerShot G5
+	3099  EOS 300D (ptp)
+	309a  PowerShot A80
+	309b  Digital IXUS (ptp)
+	309c  PowerShot S1 IS
+	30b4  PowerShot S500
+	30b5  PowerShot A75
+	30b9  Powershot A85
+	30ba  PowerShot S410 Digital Elph
+	30bb  PowerShot A95
+	30bf  Digital IXUS 40
+	30eb  EOS 20D
+	30ec  EOS 20D (ptp)
+	30ee  EOS 350D
+	30ef  EOS 350D (ptp)
+	3138  PowerShot A710 IS
+04aa  DaeWoo Telecom, Ltd
+04ab  Chromatic Research
+04ac  Micro Audiometrics Corp.
+04ad  Dooin Electronics
+04af  Winnov L.P.
+04b0  Nikon Corp.
+	0102  Coolpix 990
+	0103  Coolpix 880
+	0104  Coolpix 995
+	0106  Coolpix 775
+	0107  Coolpix 5000
+	0108  Coolpix 2500
+	0109  Coolpix 2500 (ptp)
+	010a  Coolpix 4500
+	010b  Coolpix 4500 (ptp)
+	010d  Coolpix 5700 (ptp)
+	010e  Coolpix 4300 (storage)
+	010f  Coolpix 4300 (ptp)
+	0111  Coolpix 3500 (ptp)
+	0112  Coolpix 885 (ptp)
+	0113  Coolpix 5000 (ptp)
+	0114  Coolpix 3100 (storage)
+	0115  Coolpix 3100 (ptp)
+	0117  Coolpix 2100 (ptp)
+	0119  Coolpix 5400 (ptp)
+	011d  Coolpix 3700 (ptp)
+	012c  Coolpix 4100 (storage)
+	0136  Coolpix 7900 (storage)
+	0137  Coolpix 7900 (ptp)
+	0202  Coolpix SQ (ptp)
+	0205  Coolpix 5200 (storage)
+	0206  Coolpix 5200 (ptp)
+	0301  Coolpix 2000 (storage)
+	0302  Coolpix 2000 (ptp)
+	0402  DSC D100 (ptp)
+	4000  Coolscan LS 40 ED
+04b1  Pan International
+04b3  IBM Corp.
+	3004  Media Access Pro Keyboard
+	3016  UltraNav Keyboard Hub
+	3018  UltraNav Keyboard
+	3100  NetVista Mouse
+	3103  ScrollPoint Pro Mouse
+	3107  ThinkPad 800dpi Optical Travel Mouse
+	3108  800dpi Optical Mouse w/ Scroll Point
+	3109  Optical ScrollPoint Pro Mouse
+	310b  Red Wheel Mouse
+	4427  Portable CD ROM
+	4525  Double sided CRT
+	4550  NVRAM (128 KB)
+	4554  Cash Drawer
+	4580  Hub w/ NVRAM
+	4581  4800-2xx Hub w/ Cash Drawer
+	4604  Keyboard w/ Card Reader
+	4671  4820 LCD w/ MSR/KB
+04b4  Cypress Semiconductor Corp.
+	0000  Dacal DC-101 CD Library
+	0001  Mouse
+	0002  CY7C63x0x Thermometer
+	1002  CY7C63001 R100 FM Radio
+	5500  HID->COM RS232 Adapter
+	6560  CY7C65640 USB-2.0 "TetraHub"
+	6830  USB-2.0 IDE Adapter
+	7417  Wireless PC Lock
+	8613  CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
+	d5d5  CY7C63x0x Zoltrix Z-Boxer GamePad
+	f000  CY30700 Licorice evaluation board
+04b5  ROHM LSI Systems USA, LLC
+04b6  Hint Corp.
+04b7  Compal Electronics, Inc.
+04b8  Seiko Epson Corp.
+	0001  Stylus Color 740 / Photo 750
+	0002  ISD Smart Cable for Mac
+	0003  ISD Smart Cable
+	0005  Stylus Printer
+	0101  Perfection 636
+	0102  GT-2200
+	0103  Perfection 610
+	0104  Perfection 1200
+	0105  StylusScan 2000
+	0106  Stylus Scan 2500
+	0107  Expression 1600U
+	0109  Expression 1640 XL
+	010a  Perfection 1640SU
+	010b  Perfection 1240
+	010c  Perfection 640
+	010e  Perfection 1680
+	010f  Perfection 1250
+	0110  Perfection 1650
+	0112  Perfection 2450
+	0114  Perfection 660
+	011b  Perfection 2400 Photo
+	011c  Perfection 3200
+	011d  Perfection 1260 Photo
+	011e  Perfection 1660 Photo
+	011f  Perfection 1670
+	0202  Receipt Printer M129C
+	0601  Stylus Photo 875DC Card Reader
+	0602  Stylus Photo 895 Card Reader
+	0801  Stylus CX5200
+	0802  Stylus CX3200
+04b9  Rainbow Technologies, Inc.
+	1000  iKey 1000 Token
+	1001  iKey 1200 Token
+	1200  iKey 2000 Token
+	1202  iKey 2032 Token
+	1300  iKey 3000 Token
+04ba  Toucan Systems, Ltd
+04bb  I-O Data Device, Inc.
+	0904  ET/TX Ethernet [pegasus]
+	0913  ET/TX-S Ethernet [pegasus2]
+	0922  IOData AirPort WN-B11/USBS 802.11b
+04bd  Toshiba Electronics Taiwan Corp.
+04be  Telia Research AB
+04bf  TDK Corp.
+	0100  MediaReader CF
+04c1  U.S. Robotics (3Com)
+	0082  OfficeConnect Analog Modem
+	008f  Pro ISDN TA
+	009d  HomeConnect WebCam [vicam]
+	3021  56k Voice FaxModem Pro
+04c2  Methode Electronics Far East PTE, Ltd
+04c3  Maxi Switch, Inc.
+04c4  Lockheed Martin Energy Research
+04c5  Fujitsu, Ltd
+	1029  fi-4010c Scanner
+	1041  fi-4120c Scanner
+	1042  fi-4220c Scanner
+04c6  Toshiba America Electronic Components
+04c7  Micro Macro Technologies
+04c8  Konica Corp.
+	0720  Digital Color Camera
+	0721  e-miniD Camera
+	0723  KD-200Z Camera
+	0726  KD-310Z Camera
+04ca  Lite-On Technology Corp.
+04cb  Fuji Photo Film Co., Ltd
+	0100  FinePix 1300 / 1400 / 4700 Zoom digital camera
+	0103  FinePix NX-700 printer
+	0104  FinePix A101/2600 Zoom (PC-Cam Mode)
+	0108  FinePix F601 Zoom (Disk mode)
+	0109  FinePix F601 Zoom (PC-Cam mode)
+	010a  FinePix S602 Zoom (Disk mode)
+	010b  FinePix S602 Zoom (PC-Cam mode)
+	0114  FinePix F401 Zoom (Disk mode)
+	0115  FinePix F401 Zoom (PC-Cam mode)
+	0116  FinePix A203 (Disk mode)
+	0117  FinePix A203 (PC-Cam mode)
+	011a  FinePix S304/3800 (Disk mode)
+	011b  FinePix S304/3800 (PC-Cam mode)
+	011c  FinePix 2650 (Disk mode)
+	012c  FinePix S7000 Zoom (Disk mode)
+	0130  Finepix S5000 Camera (Disk mode)
+	0131  Finepix S5000 Camera (PC-Cam mode)
+	0177  Finepix F10 Camera (Disk mode)
+	0179  Finepix F10 Camera (PTP mode)
+04cc  Philips Semiconductors
+	1122  Hub
+	1521  USB 2.0 Hub
+	8116  Camera
+04cd  Tatung Co. Of America
+04ce  ScanLogic Corp.
+	0002  SL11R-IDE IDE Bridge
+04cf  Myson Century, Inc.
+	8818  Fast 3.5" External Storage
+04d0  Digi International
+04d1  ITT Canon
+04d2  Altec Lansing Technologies
+	0311  ADA-310 Speakers
+	ff05  ADA-305 Speakers
+04d3  VidUS, Inc.
+04d4  LSI Logic, Inc.
+04d5  Forte Technologies, Inc.
+04d6  Mentor Graphics
+04d7  Oki Semiconductor
+04d8  Microchip Technology, Inc.
+	8000  In-Circuit Debugger
+04d9  Holtek Semiconductor, Inc.
+04da  Panasonic (Matsushita)
+	2372  Lumix DMC-FZ10 Camera
+04db  Hypertec Pty, Ltd
+04dc  Huan Hsin Holdings, Ltd
+04dd  Sharp Corp.
+	7004  VE-CG40U Digital Still Camera
+	7005  VE-CG30 Digital Still Camera
+	7007  VL-Z7S Digital Camcorder
+	8004  Zaurus SL-5000D/SL-5500 PDA
+	8005  Zaurus A-300
+	8006  Zaurus SL-B500/SL-5600 PDA
+	8007  Zaurus C-700 PDA
+	9014  IM-DR80 Portable NetMD Player
+	9031  Zaurus C-750/C-760/C-860/SL-C3000 PDA
+	9032  Zaurus SL-6000
+	9050  Zaurus C-860 PDA
+04de  MindShare, Inc.
+04df  Interlink Electronics
+04e1  Iiyama North America, Inc.
+	0201  Monitor Hub
+04e2  Exar Corp.
+04e3  Zilog, Inc.
+04e4  ACC Microelectronics
+04e5  Promise Technology
+04e6  SCM Microsystems, Inc.
+	0001  E-USB ATA Bridge
+	0002  eUSCSI SCSI Bridge
+	0003  eUSB SmartMedia Card Reader
+	0005  eUSB SmartMedia/CompactFlash Card Reader
+	0006  eUSB SmartMedia Card Reader
+	0007  Hifd
+	0101  eUSB ATA Bridge
+	0325  eUSB ORCA Quad Reader
+	0500  Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard
+	1010  USBAT-2 CompactFlash Card Reader
+	5111  SCR331-DI SmartCard Reader
+	5113  SCR333 SmartCard Reader
+	5115  SCR335 SmartCard Reader
+	5116  SCR331-LC1 SmartCard Reader
+	e001  SCR331 SmartCard Reader
+	e003  SPR532 PinPad SmartCard Reader
+04e7  Elo TouchSystems
+	0001  TouchScreen
+04e8  Samsung Electronics Co., Ltd
+	0110  Connect3D Flash Drive
+	0111  Connect3D Flash Drive
+	1003  MP3 Player and Recorder
+	300c  ML-1210 Printer
+	324c  ML-1740 Printer
+	3260  CLP-510 Color Laser Printer
+	5a03  Yepp MP3 Player
+	6601  Z100 Mobile Phone
+04e9  PC-Tel, Inc.
+04ea  Brooktree Corp.
+04eb  Northstar Systems, Inc.
+04ec  Tokyo Electron Device, Ltd
+04ed  Annabooks
+04ef  Pacific Electronic International, Inc.
+04f0  Daewoo Electronics Co., Ltd
+04f1  Victor Company of Japan, Ltd
+	0001  GC-QX3 Digital Still Camera
+	0004  GR-DVL815U Digital Video Camera
+	0009  GR-DX25EK Digital Video Camera
+	000a  GR-D72 Digital Video Camera
+04f2  Chicony Electronics Co., Ltd
+	0001  KU-8933 Keyboard
+	0002  NT68P81 Keyboard
+	0110  KU-2971 Keyboard
+	0112  KU-8933 Keyboard with PS/2 Mouse port
+	0116  KU-2971 German Keyboard
+04f3  Elan Microelectronics Corp.
+04f4  Harting Elektronik, Inc.
+04f5  Fujitsu-ICL Systems, Inc.
+04f6  Norand Corp.
+04f7  Newnex Technology Corp.
+04f8  FuturePlus Systems
+04f9  Brother Industries, Ltd
+	0002  HL-1050 Laser Printer
+	0006  HL-1240 Laser Printer
+	0007  HL-1250 Laser Printer
+	0008  HL-1270 Laser Printer
+	000d  HL-1440 Laser Printer
+	010f  MFC 5100C
+	0111  MFC 6800
+	2004  PT-2300/2310 p-Touch Laber Printer
+04fa  Dallas Semiconductor
+	2490  DS1490F 2-in-1 Fob, 1-Wire adapter
+	4201  DS4201 Audio DAC
+04fb  Biostar Microtech International Corp.
+04fc  Sunplus Technology Co., Ltd
+	0003  CM1092 Optical Scroller Mouse
+	0561  Flexcam 100
+	504a  SPCA504a Digital Camera
+	504b  Aiptek, 1.3 mega PockerCam
+	7333  Finet Technology Palmpix DC-85
+04fd  Soliton Systems, K.K.
+04fe  PFU, Ltd
+04ff  E-CMOS Corp.
+0500  Siam United Hi-Tech
+0501  Fujikura DDK, Ltd
+0502  Acer, Inc.
+	d001  Divio NW801/DVC-V6+ Digital Camera
+0503  Hitachi America, Ltd
+0504  Hayes Microcomputer Products
+0506  3Com Corp.
+	00a0  3CREB96 Bluetooth Adapter
+	03e8  3C19250 Ethernet [klsi]
+	0a11  3CRWE254G72 802.11g Adapter
+	00df  3Com Home Connect lite
+	4601  3C460B 10/100 Ethernet Adapter
+	f002  3CP4218 ADSL Modem (pre-init)
+	f003  3CP4218 ADSL Modem
+	f100  3CP4218 ADSL Modem (pre-init)
+0507  Hosiden Corp.
+	0011  Konami ParaParaParadise Controller
+0508  Clarion Co., Ltd
+0509  Aztech Systems, Ltd
+050a  Cinch Connectors
+050b  Cable System International
+050c  InnoMedia, Inc.
+050d  Belkin Components
+	0103  F5U103 Serial Adapter [etek]
+	0108  F1DE108B KVM
+	0109  F5U109/F5U409 PDA Adapter
+	0115  SCSI Adapter
+	0121  F5D5050 100Mbps Ethernet
+	0208  USBView II Video Adapter [nt1004]
+	0224  F5U224 USB 2.0 4-Port Hub
+	0234  F5U234 USB 2.0 4-Port Hub
+	0803  Nostromo 1745 GamePad
+	0805  Nostromo N50 GamePad
+	1203  F5U120-PC Serial Port
+	7050  F5D7050 ver 1000 WiFi
+050e  Neon Technology, Inc.
+050f  KC Technology, Inc.
+	0003  KC82C160S Hub
+	0180  KC-180 IrDA Dongle
+	0190  KC2190 USB Host-to-Host cable
+0510  Sejin Electron, Inc.
+0511  N'Able (DataBook) Technologies, Inc.
+0512  Hualon Microelectronics Corp.
+0513  digital-X, Inc.
+0514  FCI Electronics
+0515  ACTC
+0516  Longwell Electronics
+0517  Butterfly Communications
+0518  EzKEY Corp.
+0519  Star Micronics Co., Ltd
+	c002  Xlive Bluetooth XBM-100S MP3 Player
+051a  WYSE Technology
+051b  Silicon Graphics
+051c  Shuttle, Inc.
+051d  American Power Conversion
+	0002  Back-UPS Pro 500/1000/1500
+051e  Scientific Atlanta, Inc.
+051f  IO Systems (Elite Electronics), Inc.
+0520  Taiwan Semiconductor Manufacturing Co.
+0521  Airborn Connectors
+0522  Advanced Connectek, Inc.
+0523  ATEN GmbH
+0524  Sola Electronics
+0525  Netchip Technology, Inc.
+	1080  NET1080 USB-USB Bridge
+	a4a0  Linux-USB "Gadget Zero"
+	a4a1  Linux-USB Ethernet Gadget
+	a4a2  Linux-USB Ethernet/RNDIS Gadget
+	a4a3  Linux-USB user-mode isochronous source/sink
+	a4a4  Linux-USB user-mode bulk source/sink
+	a4a5  Linux-USB File Storage Gadget
+	a4a6  Linux-USB Serial Gadget
+	a4a7  Linux-USB Serial Gadget (CDC ACM mode)
+0526  Temic MHS S.A.
+0527  ALTRA
+0528  ATI Technologies, Inc.
+	7561  TV Wonder
+0529  Aladdin Knowledge Systems
+	0001  HASP v0.06
+	030b  eToken R1 v3.1.3.x
+	0313  eToken R1 v3.2.3.x
+	031b  eToken R1 v3.3.3.x
+	0323  eToken R1 v3.4.3.x
+	0412  eToken R2 v2.2.4.x
+	041a  eToken R2 v2.2.4.x
+	0422  eToken R2 v2.4.4.x
+	042a  eToken R2 v2.5.4.x
+	050c  eToken Pro v4.1.5.x
+	0514  eToken Pro v4.2.5.4
+052a  Crescent Heart Software
+052b  Tekom Technologies, Inc.
+	1513  Aosta CX100 WebCam
+	1514  Aosta CX100 WebCam Storage
+052c  Canon Information Systems, Inc.
+052d  Avid Electronics Corp.
+052e  Standard Microsystems Corp.
+052f  Unicore Software, Inc.
+0530  American Microsystems, Inc.
+0531  Wacom Technology Corp.
+0532  Systech Corp.
+0533  Alcatel Mobile Phones
+0534  Motorola, Inc.
+0535  LIH TZU Electric Co., Ltd
+0536  Hand Held Products (Welch Allyn, Inc.)
+0537  Inventec Corp.
+0538  Caldera International, Inc. (SCO)
+0539  Shyh Shiun Terminals Co., Ltd
+053a  Preh Werke GmbH & Co. KG
+053b  Global Village Communication
+053c  Institut of Microelectronic & Mechatronic Systems
+053d  Silicon Architect
+053e  Mobility Electronics
+053f  Synopsys, Inc.
+0540  UniAccess AB
+	0101  Panache Surf ISDN TA
+0541  Sirf Technology, Inc.
+0543  ViewSonic Corp.
+	00fe  G773 Monitor Hub
+	00ff  P815 Monitor Hub
+	4153  ViewSonic G773 Control (?)
+0544  Cristie Electronics, Ltd
+0545  Xirlink, Inc.
+	8002  IBM NetCamera
+	800c  Veo StingRay
+	8080  IBM C-It WebCam
+	810a  Veo Advanced Connect WebCam
+0546  Polaroid Corp.
+	1bed  PDC 1320 Camera
+0547  Anchor Chips, Inc.
+	2131  AN2131 EZUSB Microcontroller
+	2235  AN2235 EZUSB-FX Microcontroller
+	2720  AN2720 USB-USB Bridge
+	2727  Xircom PGUNET USB-USB Bridge
+	2810  Cypress USB ATAPI Bridge
+	9999  AN2131 uninitialized (?)
+0548  Tyan Computer Corp.
+	1005  EZ Cart II GameBoy Flash Programmer
+0549  Pixera Corp.
+054a  Fujitsu Microelectronics, Inc.
+054b  New Media Corp.
+054c  Sony Corp.
+	0010  DSC-S30/S70/S75/F505V/F505/FD92 Cybershot/Mavica Digital Camera
+	0023  CD Writer
+	0024  Mavica CD-1000 Camera
+	0025  NW-MS7 Walkman MemoryStick Reader
+	002d  MSAC-US1 MemoryStick Reader
+	002e  Sony HandyCam MemoryStick Reader
+	0032  MemoryStick MSC-U01 Reader
+	0038  Clie PEG-S300/D PalmOS PDA
+	004e  DSC-xxx (ptp)
+	0058  Clie PEG-N7x0C PalmOS PDA Mass Storage
+	0066  Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial
+	0069  Memorystick MSC-U03 Reader
+	006d  Clie PEG-T425 PDA Mass Storage
+	008b  Micro Vault 64M Mass Storage
+	0099  Clie NR70 PDA Mass Storage
+	009a  Clie NR70 PDA Serial
+	00c0  Handycam DCR-30
+	00c8  MZ-N710 Minidisc Walkman
+	00ca  MZ-DN430 Minidisc Walkman
+	00cb  MSAC-US20 Memory Stick Reader
+	0105  Micro Vault Hub
+	0107  VCC-U01 Visual Communication Camera
+	0144  Clie PEG-TH55 PDA
+	014c  Aiwa AM-NX9 Net MD Music Recorder MDLP
+	014d  Memory Stick Reader/Writer
+	0169  Clie PEG-TJ35 PDA Serial
+	016a  Clie PEG-TJ35 PDA Mass Storage
+	01c3  NW-E55 Network Walkman
+	01d0  DVD+RW External Drive DRU-700A
+	023b  DVD+RW External Drive DRU-800UL
+054d  Try Corp.
+054e  Proside Corp.
+054f  WYSE Technology Taiwan
+0550  Fuji Xerox Co., Ltd
+0551  CompuTrend Systems, Inc.
+0552  Philips Monitors
+0553  STMicroelectronics Imaging Division (VLSI Vision)
+	0002  CPiA WebCam
+	0151  Digital Blue QX5 Microscope
+	0202  Aiptek PenCam 1
+0554  Dictaphone Corp.
+0555  ANAM S&T Co., Ltd
+0556  Asahi Kasei Microsystems Co., Ltd
+	0001  AK5370 I/F A/D Converter
+0557  ATEN International Co., Ltd
+	2001  UC-1284 Printer Port
+	2002  10Mbps Ethernet [klsi]
+	2004  UC-100KM PS/2 Mouse and Keyboard adapter
+	2006  UC-1284B Printer Port
+	2007  UC-110T 100Mbps Ethernet [pegasus]
+	2008  UC-232A Serial Port [pl2303]
+	2202  CS124U Miniview II KVM Switch
+	2600  IDE Bridge
+	4000  DSB-650 10Mbps Ethernet [klsi]
+0558  Truevision, Inc.
+0559  Cadence Design Systems, Inc.
+055a  Kenwood USA
+055b  KnowledgeTek, Inc.
+055c  Proton Electronic Ind.
+055d  Samsung Electro-Mechanics Co.
+	9000  AnyCam [pwc]
+	9001  MPC-C30 AnyCam Premium for Notebooks [pwc]
+055e  CTX Opto-Electronics Corp.
+055f  Mustek Systems, Inc.
+	0001  ScanExpress 1200 CU
+	0002  ScanExpress 600 CU
+	0003  ScanExpress 1200 USB
+	0006  ScanExpress 1200 UB
+	0007  ScanExpress 1200 USB Plus
+	0008  ScanExpress 1200 CU Plus
+	0010  BearPaw 1200F
+	0210  ScanExpress A3 USB
+	0218  BearPaw 2400 TA
+	0219  BearPaw 2400 TA Plus
+	021a  BearPaw 2448 TA Plus
+	021c  BearPaw 1200 CU Plus
+	021d  BearPaw 2400 CU Plus
+	021e  BearPaw 1200 TA/CS
+	0400  BearPaw 2400 TA Pro
+	0401  P 3600 A3 Pro
+	0873  ScanExpress 600 USB
+	1000  BearPaw 4800 TA Pro
+	a350  gSmart 350
+	a800  MDC 800 Camera
+	b500  MDC 3000 Camera
+	c200  gSmart 300
+	c220  gSmart mini
+	c360  Mustek DV 4000
+	c420  gSmart mini 2
+	c440  Mustek DV 3000
+	c520  gSmart mini 3
+	c530  Mustek Gsmart LCD 2
+	c650  Mustek MDC5500Z
+	d001  WCam 300
+0560  Interface Corp.
+0561  Oasis Design, Inc.
+0562  Telex Communications, Inc.
+	0001  Enhanced Microphone
+0563  Immersion Corp.
+0564  Chinon Industries, Inc.
+0565  Peracom Networks, Inc.
+	0001  Serial Port [etek]
+	0002  Enet Ethernet [klsi]
+	0003  @Home Networks Ethernet [klsi]
+	0005  Enet2 Ethernet [klsi]
+0566  Monterey International Corp.
+0567  Xyratex International, Ltd
+0568  Quartz Ingenierie
+0569  SegaSoft
+056a  Wacom Co., Ltd
+	0000  PenPartner
+	0010  Graphire
+	0011  Graphire 2
+	0020  Intuos 4x5
+	0021  Intuos 6x8
+	0022  Intuos 9x12
+	0023  Intuos 12x12
+	0024  Intuos 12x18
+	0031  PL500
+	0042  Intuos 2 6x8
+	0043  Intuos 2
+056b  Decicon, Inc.
+056c  eTEK Labs
+	8007  Kwik232 Serial Port
+	8101  KwikLink USB-USB Bridge
+056d  EIZO Corp.
+	0000  Hub
+	0001  Monitor
+056e  Elecom Co., Ltd
+	0002  29UO Mouse
+	4002  Laneed 100Mbps Ethernet LD-USB/TX [pegasus]
+056f  Korea Data Systems Co., Ltd
+0570  Epson America
+0571  Interex, Inc.
+	0002  echoFX InterView Lite
+0572  Conexant Systems (Rockwell), Inc.
+	0001  Ezcam II WebCam
+	0002  Ezcam II WebCam
+	0040  Wondereye CP-115 WebCam
+	1232  V.90 modem
+	cafe  AccessRunner ADSL Modem
+	cb00  E-Tech ADSL Modem v2
+	cb01  GeekADSL Promax Q31 ADSL Modem
+0573  Zoran Co. Personal Media Division (Nogatech)
+	0003  USBGear USBG-V1
+	0400  D-Link V100
+	2000  X10 va10a Wireless Camera
+	2101  Zoran Co. PMD (Nogatech) AV-grabber Manhattan
+	2d00  Osprey 50
+	2d01  Hauppauge USB-Live Model 600
+	4100  USB-TV FM (NTSC)
+	4110  PNY USB-TV (NTSC) FM
+	4450  PixelView PlayTv-USB PRO (PAL) FM
+	4550  ZTV ZT-721 2.4GHz USB A/V Receiver
+	4d00  Hauppauge WinTV-USB USA
+	4d01  Hauppauge WinTV-USB
+	4d02  Hauppauge WinTV-USB UK
+	4d03  Hauppauge WinTV-USB France
+	4d10  Hauppauge WinTV-USB with FM USA radio
+	4d11  Hauppauge WinTV-USB (PAL) with FM radio
+	4d12  Hauppauge WinTV-USB UK with FM Radio
+	4d20  Hauppauge WinTV-USB II (PAL) with FM radio
+	4d21  Hauppauge WinTV-USB II (PAL)
+	4d22  Hauppauge WinTV-USB II (PAL) Model 566
+	4d23  Hauppauge WinTV-USB France 4D23
+	4d25  Hauppauge WinTV-USB Model 40209 rev B234
+	4d26  Hauppauge WinTV-USB Model 40209 rev B243
+	4d27  Hauppauge WinTV-USB Model 40204 Rev B281
+	4d28  Hauppauge WinTV-USB Model 40204 rev B283
+	4d29  Hauppauge WinTV-USB Model 40205 rev B298
+	4d2a  Hauppague WinTV-USB Model 602 Rev B285
+	4d2b  Hauppague WinTV-USB Model 602 Rev B282
+	4d30  Hauppauge WinTV-USB FM Model 40211 Rev B123
+	4d31  Hauppauge WinTV-USB III (PAL) with FM radio Model 568
+	4d32  Hauppauge WinTV-USB III (PAL) FM Model 573
+	4d35  Hauppauge WinTV-USB III (PAL) FM Model 597
+	4d37  Hauppauge WinTV-USB Model 40219 rev E189
+0574  City University of Hong Kong
+0575  Philips Creative Display Solutions
+0576  BAFO/Quality Computer Accessories
+0577  ELSA
+0578  Intrinsix Corp.
+0579  GVC Corp.
+057a  Samsung Electronics America
+057b  Y-E Data, Inc.
+	0000  FlashBuster-U Floppy
+	0001  Tri-Media Reader Floppy
+	0006  Tri-Media Reader Card Reader
+	0010  Memory Stick Reader Writer
+	0020  HEXA Media Drive 6-in-1 Card Reader Writer
+	0030  Memory Card Viewer (TV)
+057c  AVM GmbH
+	2800  ISDN-Connector TA
+	3800  BlueFRITZ! Bluetooth Stick
+	3d00  Fritz!Box
+057d  Shark Multimedia, Inc.
+057e  Nintendo Co., Ltd
+057f  QuickShot, Ltd
+0580  Denron, Inc.
+0581  Racal Data Group
+0582  Roland Corp.
+	0002  MPU64 Midi Interface
+	0003  Sound Canvas SC-8850
+	0005  Edirol UM-2 MIDI Adapter
+	0011  Edirol UA-5 Sound Capture
+	002d  VX-2020 Synthesizer
+0583  Padix Co., Ltd (Rockfire)
+	2030  RM-203 USB Nest [mode 1]
+	2031  RM-203 USB Nest [mode 2]
+	2032  RM-203 USB Nest [mode 3]
+	2033  RM-203 USB Nest [mode 4]
+	2050  PX-205 PSX Bridge
+	3050  QF-305u Gamepad
+	688f  QF-688uv Windstorm Pro Joystick
+	7070  QF-707u Bazooka Joystick
+0584  RATOC System, Inc.
+0585  FlashPoint Technology, Inc.
+0586  ZyXEL Communications Corp.
+	1000  Omni NET Modem / ISDN TA
+0587  America Kotobuki Electronics Industries, Inc.
+0588  Sapien Design
+0589  Victron
+058a  Nohau Corp.
+058b  Infineon Technologies
+058c  In Focus Systems
+058d  Micrel Semiconductor
+058e  Tripath Technology, Inc.
+058f  Alcor Micro Corp.
+	2802  Monterey Keyboard
+	5492  Hub
+	6232  Hi-Speed 16-in-1 Flash Card Reader/Writer
+	9213  MacAlly Kbd Hub
+	9215  AU9814 Hub
+	9254  Hub
+	9330  SD Reader
+	9380  Flash drive
+	9382  Acer/Sweex Flash drive
+	9410  Keyboard
+	9472  Keyboard Hub
+0590  Omron Corp.
+	0004  Cable Modem
+0591  Questra Consulting
+0592  Powerware Corp.
+0593  Incite
+0594  Princeton Graphic Systems
+0595  Zoran Microelectronics, Ltd
+0596  MicroTouch Systems, Inc.
+	0001  Touchscreen
+0597  Trisignal Communications
+0598  Niigata Canotec Co., Inc.
+0599  Brilliance Semiconductor, Inc.
+059a  Spectrum Signal Processing, Inc.
+059b  Iomega Corp.
+	0001  Zip 100 (Type 1)
+	000b  Zip 100 (Type 2)
+	0030  Zip 250 (Ver 1)
+	0031  Zip 100 (Type 3)
+	0032  Zip 250 (Ver 2)
+	0040  SCSI Bridge
+	0050  Zip CD 650 Writer
+	0053  CDRW55292EXT CD-RW External Drive
+	006d  HipZip MP3 Player
+	015d  Super DVD Writer
+	1052  DVD+RW External Drive
+059c  A-Trend Technology Co., Ltd
+059d  Advanced Input Devices
+059e  Intelligent Instrumentation
+059f  LaCie, Ltd
+	0211  PocketDrive
+	0212  PocketDrive
+	a601  HardDrive
+05a0  Vetronix Corp.
+05a1  USC Corp.
+05a2  Fuji Film Microdevices Co., Ltd
+05a3  ARC International
+05a4  Ortek Technology, Inc.
+	9731  MCK-600W Keyboard
+05a5  Sampo Technology Corp.
+05a6  Cisco Systems, Inc.
+05a7  Bose Corp.
+05a8  Spacetec IMC Corp.
+05a9  OmniVision Technologies, Inc.
+	0511  OV511 WebCam
+	0518  OV518 WebCam
+	a511  OV511+ WebCam
+05aa  Utilux South China, Ltd
+05ab  In-System Design
+	0002  Parallel Port
+	0031  ATA Bridge
+	0060  USB 2.0 ATA Bridge
+	0200  USS725 ATA Bridge
+	0202  ATA Bridge
+	081a  ATA Bridge
+	0cda  ATA Bridge for CD-R/RW
+05ac  Apple Computer, Inc.
+	0201  iMac Keyboard [ALPS M2452]
+	0202  Apple Keyboard [ALPS]
+	0205  Apple Extended Keyboard [Mitsumi]
+	0206  Apple Extended Keyboard [Mitsumi]
+	020e  Apple Internal Keyboard/Trackpad
+	020f  Apple Internal Keyboard/Trackpad
+	0301  iMac Mouse [Mitsumi/Logitech]
+	0302  Apple Optical Mouse [Fujitsu]
+	1001  Apple Keyboard Hub [ALPS]
+	1002  Apple Extended Keyboard Hub [Mitsumi]
+	1101  Speakers
+	1201  3G iPod
+	1300  iPod Shuffle
+	8202  HCF V.90 Data/Fax Modem
+	8203  Bluetooth HCI
+05ad  Y.C. Cable U.S.A., Inc.
+05ae  Synopsys, Inc.
+05af  Jing-Mold Enterprise Co., Ltd
+05b0  Fountain Technologies, Inc.
+05b1  First International Computer, Inc.
+05b4  LG Semicon Co., Ltd
+	4857  M-Any DAH-210
+	6001  Digisette DUO-MP3 AR-100
+05b5  Dialogic Corp.
+05b6  Proxima Corp.
+05b7  Medianix Semiconductor, Inc.
+05b8  Agiler, Inc.
+	3002  Scroll Mouse
+05b9  Philips Research Laboratories
+05ba  DigitalPersona, Inc.
+05bb  Grey Cell Systems
+05bc  3G Green Green Globe Co., Ltd
+	0004  Trackball
+05bd  RAFI GmbH & Co. KG
+05be  Tyco Electronics (Raychem)
+05bf  S & S Research
+05c0  Keil Software
+05c1  Kawasaki Microelectronics, Inc.
+05c2  Media Phonics (Suisse) S.A.
+05c5  Digi International, Inc.
+05c6  Qualcomm, Inc.
+	3100  CDMA Wireless Modem/Phone
+	3196  CDMA Wireless Modem
+	3197  CDMA Wireless Modem/Phone
+05c7  Qtronix Corp.
+	1001  Lynx Mouse
+	2011  SCorpius Keyboard
+05c8  Cheng Uei Precision Industry Co., Ltd (Foxlink)
+05c9  Semtech Corp.
+05ca  Ricoh Co., Ltd
+	0101  RDC-5300 Camera
+	2201  RDC-7 Camera
+	2205  Caplio RR30 / Medion MD 6126 Camera
+	2212  Caplio R1v Camera
+05cb  PowerVision Technologies, Inc.
+	1483  PV8630 interface (scanners, webcams)
+05cc  ELSA AG
+	2100  MicroLink ISDN Office
+	2219  MicroLink ISDN
+	2265  MicroLink 56k
+	2267  MicroLink 56k (V.250)
+	2280  MicroLink 56k Fun
+	3000  Micolink USB2Ethernet [pegasus]
+	3363  MicroLink ADSL Fun
+05cd  Silicom, Ltd
+05ce  sci-worx GmbH
+05cf  Sung Forn Co., Ltd
+05d0  GE Medical Systems Lunar
+05d1  Brainboxes, Ltd
+05d2  Wave Systems Corp.
+05d3  Tohoku Ricoh Co., Ltd
+05d5  Super Gate Technology Co., Ltd
+05d6  Philips Semiconductors, CICT
+05d7  Thomas & Betts Corp.
+	0099  10Mbps Ethernet [klsi]
+05d8  Ultima Electronics Corp.
+	4001  Artec Ultima 2000
+	4002  Artec Ultima 2000 (GT6801 based)/Lifetec LT9385 Scanner
+	4003  Artec E+ 48U
+	4004  Artec E+ Pro
+	4008  Trust Easy Webscan 19200
+	4009  Umax Astraslim
+	8105  Artec T1 USB TVBOX (cold)
+	8106  Artec T1 USB TVBOX (warm)
+	8107  Artec T1 USB TVBOX with AN2235 (cold)
+	8108  Artec T1 USB TVBOX with AN2235 (warm)
+	8109  Artec T1 USB2.0 TVBOX (cold
+05d9  Axiohm Transaction Solutions
+05da  Microtek International, Inc.
+	0093  ScanMaker V6USL
+	0094  Phantom 336CX/C3
+	0099  ScanMaker X6/X6U
+	009a  Phantom C6
+	00a0  Phantom 336CX/C3 (#2)
+	00b6  ScanMaker V6UPL
+	1011  NHJ Che-ez! Kiss Digital Camera
+	1018  Digital Dream Enigma 1.3
+	30ce  ScanMaker 3800
+	30cf  ScanMaker 4800
+	30e6  ScanMaker i320
+	40ca  ScanMaker 3600
+	80a3  ScanMaker V6USL (#2)
+	80ac  ScanMaker V6UL/SpicyU
+05db  Sun Corp. (Suntac?)
+05dc  Lexar Media, Inc.
+	0080  Jumpdrive Secure 64MB
+	0200  JumpDrive 2.0 Pro
+	0300  Jumpdrive Geysr
+	b018  Multi-Card Reader
+05dd  Delta Electronics, Inc.
+05df  Silicon Vision, Inc.
+05e0  Symbol Technologies
+05e1  Syntek Semiconductor Co., Ltd
+05e2  ElecVision, Inc.
+05e3  Genesys Logic, Inc.
+	000a  Keyboard with PS/2 Port
+	000b  Mouse
+	0100  Nintendo Game Boy Advance SP
+	0120  Pacific Image Electronics PrimeFilm 1800u slide/negative scanner
+	0300  GLUSB98PT Parallel Port
+	0406  Hub
+	0502  GL620USB GeneLink USB-USB Bridge
+	0604  USB 1.1 Hub
+	0605  USB 2.0 Hub [ednet]
+	0660  USB 2.0 Hub
+	0700  SIIG US2256 CompactFlash Card Reader
+	0701  USB 2.0 IDE Adapter
+	0702  USB 2.0 IDE Adapter
+	0703  Card Reader
+	0710  USB 2.0 33-in-1 Card Reader
+	0760  Card Reader
+	07A0  Pen Flash
+	1205  Afilias Optical Mouse H3003
+05e4  Red Wing Corp.
+05e5  Fuji Electric Co., Ltd
+05e6  Keithley Instruments
+05e8  ICC, Inc.
+05e9  Kawasaki LSI
+	0008  KL5KUSB101B Ethernet [klsi]
+	0009  Sony 10Mbps Ethernet [pegasus]
+05eb  FFC, Ltd
+05ec  COM21, Inc.
+05ee  Cytechinfo Inc.
+05ef  AVB, Inc. [anko?]
+	020a  Top Shot Pegasus Joystick
+	8884  Mag Turbo Force Wheel
+	8888  Top Shot Force Feedback Racing Wheel
+05f0  Canopus Co., Ltd
+	0101  DA-Port DAC
+05f1  Compass Communications
+05f2  Dexin Corp., Ltd
+05f3  PI Engineering, Inc.
+	0007  Kinesis Advantage PRO MPC/USB Keyboard
+	0081  Kinesis Integrated Hub
+	020b  PS2 Adapter
+	0232  X-Keys Switch Interface, Programming Mode
+	0261  X-Keys Switch Interface, SPLAT Mode
+	0264  X-Keys Switch Interface, Composite Mode
+05f5  Unixtar Technology, Inc.
+05f6  AOC International
+05f7  RFC Distribution(s) PTE, Ltd
+05f9  PSC Scanning, Inc.
+05fa  Siemens Telecommunications Systems, Ltd
+05fc  Harman Multimedia
+05fd  InterAct, Inc.
+	0251  Raider Pro
+	0253  ProPad 8 Digital
+	262a  3dfx HammerHead FX
+	daae  Game Shark
+05fe  Chic Technology Corp.
+	0001  Mouse
+	0005  Viewmaster 4D Browser Mouse
+	0007  Twinhead Mouse
+	0009  Inland Pro 4500/5000 Mouse
+	0011  Browser Mouse
+05ff  LeCroy Corp.
+0600  Barco Display Systems
+0601  Jazz Hipster Corp.
+0602  Vista Imaging, Inc.
+	1001  ViCam WebCam
+0603  Novatek Microelectronics Corp.
+	00f1  Keyboard
+	6871  Mouse
+0604  Jean Co., Ltd
+0605  Anchor C&C Co., Ltd
+0606  Royal Information Electronics Co., Ltd
+0607  Bridge Information Co., Ltd
+0608  Genrad Ads
+0609  SMK Manufacturing, Inc.
+060a  Worthington Data Solutions, Inc.
+060b  Solid Year
+	0001  MacAlly Keyboard
+	2101  Keyboard
+	5811  ACK-571U Wireless Keyboard
+	a001  Maxwell Compact Pc PM3
+060c  EEH Datalink GmbH
+060d  Auctor Corp.
+060e  Transmonde Technologies, Inc.
+060f  Joinsoon Electronics Mfg. Co., Ltd
+0610  Costar Electronics, Inc.
+0611  Totoku Electric Co., Ltd
+0613  TransAct Technologies, Inc.
+0614  Bio-Rad Laboratories
+0615  Quabbin Wire & Cable Co., Inc.
+0616  Future Techno Designs PVT, Ltd
+0617  Swiss Federal Insitute of Technology
+0618  MacAlly
+	0101  Mouse
+0619  Seiko Instruments, Inc.
+061a  Veridicom International, Inc.
+	0110  5thSense Fingerprint Sensor
+	0200  FPS200 Fingerprint Sensor
+	8200  VKI-A Fingerprint Sensor/Flash Storage (dumb)
+	9200  VKI-B Fingerprint Sensor/Flash Storage (smart)
+061b  Promptus Communications, Inc.
+061c  Act Labs, Ltd
+061d  Quatech, Inc.
+061e  Nissei Electric Co.
+0620  Alaris, Inc.
+0621  ODU-Steckverbindungssysteme GmbH & Co. KG
+0622  Iotech, Inc.
+0623  Littelfuse, Inc.
+0624  Avocent Corp.
+0625  TiMedia Technology Co., Ltd
+0626  Nippon Systems Development Co., Ltd
+0627  Adomax Technology Co., Ltd
+0628  Tasking Software, Inc.
+0629  Zida Technologies, Ltd
+062a  Creative Labs
+	0001  Notebook Optical Mouse
+062b  Greatlink Electronics Taiwan, Ltd
+062c  Institute for Information Industry
+062d  Taiwan Tai-Hao Enterprises Co., Ltd
+062e  Mainsuper Enterprises Co., Ltd
+062f  Sin Sheng Terminal & Machine, Inc.
+0631  JUJO Electronics Corp.
+0633  Cyrix Corp.
+0634  Micron Technology, Inc.
+0635  Methode Electronics, Inc.
+0636  Sierra Imaging, Inc.
+0638  Avision, Inc.
+	0268  iVina 1200U Scanner
+	026a  Minolta Dimage Scan Dual II
+	0a10  iVina FB1600/UMAX Astra 4500
+	4004  Minolta Dimage Scan Elite II
+0639  Chrontel, Inc.
+063a  Techwin Corp.
+063b  Taugagreining HF
+063c  Yamaichi Electronics Co., Ltd (Sakura)
+063d  Fong Kai Industrial Co., Ltd
+063e  RealMedia Technology, Inc.
+063f  New Technology Cable, Ltd
+0640  Hitex Development Tools
+0641  Woods Industries, Inc.
+0642  VIA Medical Corp.
+0644  TEAC Corp.
+	0000  Floppy
+	800D  TASCAM Portastudio DP-01FX
+0645  Who? Vision Systems, Inc.
+0646  UMAX
+0647  Acton Research Corp.
+	0100  ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph
+	0101  ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph
+	0102  ARC Inspectrum Mono
+	0103  ARC Filterwheel
+	03e9  Inspectrum 128x1024 F VIS Spectrograph
+	03ea  Inspectrum 256x1024 F VIS Spectrograph
+	03eb  Inspectrum 128x1024 B VIS Spectrograph
+	03ec  Inspectrum 256x1024 B VIS Spectrograph
+0648  Inside Out Networks
+0649  Weli Science Co., Ltd
+064b  White Mountain DSP, Inc.
+064c  Ji-Haw Industrial Co., Ltd
+064d  TriTech Microelectronics, Ltd
+064e  Suyin Corp.
+064f  WIBU-Systems AG
+0650  Dynapro Systems
+0651  Likom Technology Sdn. Bhd.
+0652  Stargate Solutions, Inc.
+0653  CNF, Inc.
+0654  Granite Microsystems, Inc.
+0655  Space Shuttle Hi-Tech Co., Ltd
+0656  Glory Mark Electronic, Ltd
+0657  Tekcon Electronics Corp.
+0658  Sigma Designs, Inc.
+0659  Aethra
+065a  Optoelectronics Co., Ltd
+	0001  Barcode scanner
+065b  Tracewell Systems
+065e  Silicon Graphics
+065f  Good Way Technology Co., Ltd & GWC technology Inc.
+0660  TSAY-E (BVI) International, Inc.
+0661  Hamamatsu Photonics K.K.
+0662  Kansai Electric Co., Ltd
+0663  Topmax Electronic Co., Ltd
+	0103  CobraPad
+0667  Aiwa Co., Ltd
+	0fa1  TD-U8000 Tape Drive
+0668  WordWand
+0669  Oce' Printing Systems GmbH
+066a  Total Technologies, Ltd
+066b  Linksys, Inc.
+	0105  SCM eUSB SmartMedia Card Reader
+	010a  Melco MCR-U2 SmartMedia / CompactFlash Reader
+	2202  USB10TX Ethernet [pegasus]
+	2203  USB100TX Ethernet [pegasus]
+	2204  USB100TX HomePNA Ethernet [pegasus]
+	2206  USB Ethernet [pegasus]
+	2211  WUSB11 802.11b Adapter
+	2212  WUSB11v2.5 802.11b Adapter
+	2213  WUSB12v1.1 802.11b Adapter
+066d  Entrega, Inc.
+066e  Acer Semiconductor America, Inc.
+066f  SigmaTel, Inc.
+	004b  A-Max PA11 MP3 Player
+	3400  STMP3400 D-Major MP3 Player
+	3410  STMP3410 D-Major MP3 Player
+	4200  STIr4200 IrDA Bridge
+	4210  STIr4210 IrDA Bridge
+	8004  MSCNMMC MP3 Player
+	8202  Jens of Sweden / I-BEAD 150M/150H MP3 player
+0672  Labtec, Inc.
+	1041  LCS1040 Speaker System
+	5000  SpaceBall 4000 FLX
+0673  HCL
+	5000  Keyboard
+0674  Key Mouse Electronic Enterprise Co., Ltd
+0675  Draytech
+	0110  Vigor 128 ISDN TA
+0676  Teles AG
+0677  Aiwa Co., Ltd
+	0fa1  TD-U8000 Tape Drive
+0678  ACard Technology Corp.
+067b  Prolific Technology, Inc.
+	0000  PL2301 USB-USB Bridge
+	0001  PL2302 USB-USB Bridge
+	2303  PL2303 Serial Port
+	2305  PL2305 Parallel Port
+	2307  PL2307 USB-ATAPI4 Bridge
+	2315  Flash Disk Embedded Hub
+	2316  Flash Disk Security Device
+	2317  Mass Storage Device
+	2501  PL2501 USB-USB Bridge (USB 2.0)
+	2515  Flash Disk Embedded Hub
+	2517  Flash Disk Mass Storage Device
+	3507  PL3507 ATAPI6 Bridge 
+067c  Efficient Networks, Inc.
+	1001  Siemens SpeedStream 100MBps Ethernet
+	1022  Siemens SpeedStream 1022 802.11b Adapter
+	4060  Alcatel Speedstream 4060 ADSL Modem
+067d  Hohner Corp.
+067e  Intermec
+067f  Virata, Ltd
+0680  Realtek Semiconductor Corp., CPP Div. (Avance Logic)
+	0002  Arowana Optical Wheel Mouse MSOP-01
+0681  Siemens Information and Communication Products
+	0002  Gigaset 3075 Passive ISDN
+	0005  Mouse with Fingerprint Reader
+	0012  I-Gate 802.11b Adapter
+	002b  A-100-I ADSL Modem
+0682  Victor Company of Japan, Ltd
+0684  Actiontec Electronics, Inc.
+0686  Minolta Co., Ltd
+	4003  Dimage 2330 Zoom Camera
+	4004  Scan Elite II
+	4006  Dimage 7 Camera
+	4007  Dimage S304 Camera
+	4008  Dimage 5 Camera
+	4009  Dimage X Camera
+	400a  Dimage S404 Camera
+	400b  Dimage 7i Camera
+	400c  Dimage F100 Camera
+	400d  Scan Dual III
+	400f  Dimage 7Hi Camera
+	4010  Dimage Xi Camera
+	4011  Dimage F300 Camera
+	4012  Dimage F200 Camera
+	4014  Dimage S414 Camera
+	4015  Dimage XT Camera [storage]
+	4016  Dimage XT Camera [remote mode]
+	4018  Dimage Z1  Camera
+	401a  Dimage A1 Camera
+	401c  Dimage X20 Camera
+	401e  Dimage E323 Camera
+068a  Pertech, Inc.
+068b  Potrans International, Inc.
+068e  CH Products, Inc.
+	00e2  HFX OEM Joystick
+	00f2  Flight Sim Pedals
+	00ff  Flight Sim Yoke
+	0500  GameStick 3D
+	0501  CH Pro Pedals
+	0504  F-16 Combat Stick
+0690  Golden Bridge Electech, Inc.
+0693  Hagiwara Sys-Com Co., Ltd
+	0002  FlashGate SmartMedia Card Reader
+	0003  FlashGate CompactFlash Card Reader
+	0005  FlashGate
+0694  Lego Group
+	0001  Mindstorms Tower
+0698  Chuntex (CTX)
+	1786  1300ex Monitor
+	9999  VLxxxx Monitor+Hub
+0699  Tektronix, Inc.
+069a  Askey Computer Corp.
+	0001  VC010 WebCam [pwc]
+	0303  Cable Modem
+	0321  Dynalink WLL013 / Compex WLU11A 802.11b Adapter
+	0821  BT Voyager 1010 802.11b Adapter
+069b  Thomson, Inc.
+	0704  DCM245 Cable Modem
+	2220  RCA Kazoo RD1000 MP3 Player
+	300a  RCA Lyra MP3 Player
+069d  Hughes Network Systems (HNS)
+	0002  Satellite Device
+069e  Marx
+	0005  CryptoBox v1.2
+069f  Allied Data Technologies BV
+	0010  Tornado Speakerphone FaxModem 56.0
+	0011  Tornado Speakerphone FaxModem 56.0
+06a2  Topro Technology, Inc.
+06a3  Saitek PLC
+	0006  Cyborg Gold Joystick
+	0200  Xbox Adrenalin Hub
+	0241  Xbox Adrenalin Gamepad
+	0422  ST90 Joystick
+	052d  P750 Gamepad
+	053f  X36F Flightstick
+	100a  SP550 Pad and Joystick Combo
+	100b  SP550 Pad
+	3509  P3000 RF GamePad
+06a4  Xiamen Doowell Electron Co., Ltd
+06a5  Divio
+	0000  Typhoon Webcam 100k [nw8000]
+	d001  ProLink DS3303u WebCam
+	d800  Chicony TwinkleCam
+06a7  MicroStore, Inc.
+06a8  Topaz Systems, Inc.
+	0042  SignatureGem 1X5 Pad
+	0043  SignatureGem 1X5-HID Pad
+06a9  Westell
+06aa  Sysgration, Ltd
+06ac  Fujitsu Laboratories of America, Inc.
+06ad  Greatland Electronics Taiwan, Ltd
+06ae  Professional Multimedia Testing Centre
+06af  Harting, Inc. of North America
+06b8  Pixela Corp.
+06b9  Alcatel Telecom
+	0121  SpeedTouch 121g Wireless Dongle
+	4061  SpeedTouch ISDN or ADSL Modem
+	a5a5  DynaMiTe Modem
+06ba  Smooth Cord & Connector Co., Ltd
+06bb  EDA, Inc.
+06bc  Oki Data Corp.
+06bd  AGFA-Gevaert NV
+	0001  SnapScan 1212U
+	0002  SnapScan 1236U
+	0100  SnapScan Touch
+	0403  ePhoto CL18 Camera
+	0404  ePhoto CL20 Camera
+	2061  SnapScan 1212U (?)
+	208d  Snapscan e40
+	208f  SnapScan e50
+	2091  SnapScan e20
+	2093  SnapScan e10
+	2095  SnapScan e25
+	2097  SnapScan e26
+	20fd  SnapScan e52
+	20ff  SnapScan e42
+06be  AME Optimedia Technology Co., Ltd
+06bf  Leoco Corp.
+06c2  Phidgets Inc. (formerly GLAB)
+	0030  PhidgetRFID
+	0038  4-Motor PhidgetServo v3.0
+	0039  1-Motor PhidgetServo v3.0
+	003a  8-Motor PhidgetAvancedServo
+	0040  PhidgetInterface Kit 0-0-4
+	0044  PhidgetInterface Kit 0-16-16
+	0045  PhidgetInterface Kit 8-8-8
+	0048  PhidgetStepper (Under Development)
+	0049  PhidgetTextLED Ver 1.0
+	004a  PhidgetLED Ver 1.0
+	004b  PhidgetEncoder Ver 1.0
+	0051  PhidgetInterface Kit 0-5-7 (Custom)
+	0052  PhidgetTextLCD
+	0053  PhidgetInterfaceKit 0-8-8
+	0058  PhidgetMotorControl Ver 1.0
+	0070  PhidgetTemperatureSensor Ver 1.0
+	0071  PhidgetAccelerometer Ver 1.0
+	0072  PhidgetWeightSensor Ver 1.0
+	0073  PhidgetHumiditySensor
+	0074  PhidgetPHSensor
+	0075  PhidgetGyroscope
+06c4  Bizlink International Corp.
+06c5  Hagenuk, GmbH
+06c6  Infowave Software, Inc.
+06c8  SIIG, Inc.
+06c9  Taxan (Europe), Ltd
+06ca  Newer Technology, Inc.
+06cb  Synaptics, Inc.
+	0009  Composite TouchPad and TrackPoint
+06cc  Terayon Communication Systems
+06cd  Keyspan
+	0101  USA-28 PDA [preenum]
+	0102  USA-28X PDA [preenum]
+	0103  USA-19 PDA [preenum]
+	0104  PDA [prerenum]
+	0105  USA-18X PDA [preenum]
+	0106  USA-19W PDA [preenum]
+	0107  USA-19 PDA
+	0108  USA-19W PDA
+	010b  USA-19Q PDA
+	010f  USA-28 PDA
+	0110  USA-28X PDA
+	0112  USA-18X PDA
+	0114  USA-28X PDA
+	0118  USA-19QW PDA
+	0201  Digital Media Remote
+06cf  SpheronVR AG
+	1010  PanoCam 10
+	1012  PanoCam 12/12X
+06d0  LapLink, Inc.
+	0622  LapLink Gold USB-USB Bridge [net1080]
+06d1  Daewoo Electronics Co., Ltd
+06d3  Mitsubishi Electric Corp.
+06d4  Cisco Systems
+06d5  Toshiba
+	4000  Japanese Keyboard
+06d6  Aashima Technology B.V.
+06d7  Network Computing Devices (NCD)
+06d8  Technical Marketing Research, Inc.
+06da  Phoenixtec Power Co., Ltd
+06db  Paradyne
+06dc  Foxlink Image Technology Co., Ltd
+	0014  Prolink Winscan Pro 2448U
+06de  Heisei Electronics Co., Ltd
+06e0  Multi-Tech Systems, Inc.
+	f101  MT5634ZBA-USB MultiModemUSB (old firmware)
+	f103  MT5634MU MultiMobileUSB
+	f104  MT5634ZBA-USB MultiModemUSB (new firmware)
+	f107  MT5634ZBA-USB-V92 MultiModemUSB
+06e1  ADS Technologies, Inc.
+	0008  UBS-10BT Ethernet [klsi]
+	a190  Instand VCD Usb Capture
+06e4  Alcatel Microelectronics
+06e6  Tiger Jet Network, Inc.
+06ea  Sirius Technologies
+	0001  NetCom Roadster II 56k
+	0002  Roadster II 56k
+06eb  PC Expert Tech. Co., Ltd
+06ef  I.A.C. Geometrische Ingenieurs B.V.
+06f0  T.N.C Industrial Co., Ltd
+06f1  Opcode Systems, Inc.
+06f2  Emine Technology Co.
+06f6  Wintrend Technology Co., Ltd
+06f8  Guillemot Corp.
+	a300  Dual Analog Leader GamePad
+06fa  HSD S.r.L
+06fc  Motorola Semiconductor Products Sector
+06fd  Boston Acoustics
+06fe  Gallant Computer, Inc.
+0701  Supercomal Wire & Cable SDN. BHD.
+0703  Bvtech Industry, Inc.
+0705  NKK Corp.
+0706  Ariel Corp.
+0707  Standard Microsystems Corp.
+	0100  2202 Ethernet [klsi]
+	0200  2202 Ethernet [pegasus]
+	ee06  EZ-Connect 802.11g Adapter
+	ee13  EZ-Connect 802.11g Adapter
+0708  Putercom Co., Ltd
+0709  Silicon Systems, Ltd (SSL)
+070a  Oki Electric Industry Co., Ltd
+070d  Comoss Electronic Co., Ltd
+070e  Excel Cell Electronic Co., Ltd
+0710  Connect Tech, Inc.
+	0001  WhiteHeat (fake ID)
+	8001  WhiteHeat
+0711  Magic Control Technology Corp.
+	0100  Hub
+	0200  BAY-3U1S1P Serial Port
+	0210  MCT1S Serial Port
+	0230  MCT-232 Serial Port
+	0231  PS/2 Mouse Port
+	0240  PS/2 to USB Converter
+	0300  BAY-3U1S1P Parallel Port
+	0302  Parallel Port
+	0900  SVGA Adapter
+0713  Interval Research Corp.
+0714  NewMotion, Inc.
+	0003  ADB to USB convertor
+0717  ZNK Corp.
+0718  Imation Corp.
+0719  Tremon Enterprises Co., Ltd
+071b  Domain Technologies, Inc.
+	0002  DTI-56362-USB Digital Interface Unit
+	0101  Audio4-USB DSP Data Acquisition Unit
+	0201  Audio4-5410 DSP Data Acquisition Unit
+	0301  SB-USB JTAG Emulator
+071c  Xionics Document Technologies, Inc.
+071d  Eicon Networks Corp.
+	1000  Diva ISDN TA
+071e  Ariston Technologies
+0723  Centillium Communications Corp.
+0726  Vanguard International Semiconductor-America
+0729  Amitm
+	1000  USC-1000 Serial Port
+072e  Sunix Co., Ltd
+072f  Advanced Card Systems, Ltd
+	0001  AC1030-based SmartCard Reader
+	9000  ACR38 AC1038-based Smart Card Reader
+	90cc  ACR38 SmartCard Reader
+0731  Susteen, Inc.
+	0528  SonyEricsson DCU-11 Cable
+0732  Goldfull Electronics & Telecommunications Corp.
+0733  ViewQuest Technologies, Inc.
+	0110  VQ110
+	1311  Digital Dream Epsilon 1.3
+	2211  Jenoptik
+	0401  CS330 WebCam
+	0402  M-318B WebCam
+	0430  Intel Pro Share WebCam
+0734  Lasat Communications A/S
+	0001  560V Modem
+0735  Asuscom Network
+	c541  ISDN TA 280
+0736  Lorom Industrial Co., Ltd
+0738  Mad Catz, Inc.
+073b  Suncom Technologies
+073a  Chaplet Systems, Inc.
+073d  Eutron S.p.a.
+	0005  Crypto Token
+073e  NEC, Inc.
+	0301  Game Pad
+0745  Syntech Information Co., Ltd
+0746  Onkyo Corp.
+0747  Labway Corp.
+0748  Strong Man Enterprise Co., Ltd
+0749  EVer Electronics Corp.
+074a  Ming Fortune Industry Co., Ltd
+074b  Polestar Tech. Corp.
+074c  C-C-C Group PLC
+074d  Micronas GmbH
+074e  Digital Stream Corp.
+	0001  PS/2 Adapter
+	0002  PS/2 Adapter
+0755  Aureal Semiconductor
+0757  Network Technologies, Inc.
+075b  Sophisticated Circuits, Inc.
+	0001  Kick-off! Watchdog
+0763  Midiman
+	1001  Midisport 2x2
+	1010  Midisport 1x1
+	1020  Midisport 4x4
+	1030  Midisport 8x8
+0764  Cyber Power System, Inc.
+	0005  Cyber Power UPS
+0765  X-Rite, Inc.
+0766  Jess-Link Products Co., Ltd
+0767  Tokheim Corp.
+0768  Camtel Technology Corp.
+	0006 Camtel Technology USB TV Genie Pro FM Model TVB330
+0769  Surecom Technology Corp.
+076a  Smart Technology Enablers, Inc.
+076b  OmniKey AG
+	0596  CardMan 2020
+	1784  CardMan 6020
+	3021  CardMan 3121
+076c  Partner Tech
+076d  Denso Corp.
+076e  Kuan Tech Enterprise Co., Ltd
+076f  Jhen Vei Electronic Co., Ltd
+0774  AmTRAN Technology Co., Ltd
+0775  Longshine Electronics Corp.
+0776  Inalways Corp.
+0777  Comda Enterprise Corp.
+0778  Volex, Inc.
+0779  Fairchild Semiconductor
+077a  Sankyo Seiki Mfg. Co., Ltd
+077b  Linksys
+	2219  WUSB11 V2.6 802.11b Adapter
+	2226  USB200M 100baseTX Adapter
+077c  Forward Electronics Co., Ltd
+	0005  NEC Keyboard
+077d  Griffin Technology
+	0410  PowerMate
+	041a  PowerWave
+	0223  IMic Audio In/Out
+077f  Well Excellent & Most Corp.
+0781  SanDisk Corp.
+	0001  SDDR-05a ImageMate CompactFlash Reader
+	0002  SDDR-31 ImageMate II CompactFlash Reader
+	0005  SDDR-05b (CF II) ImageMate CompactFlash Reader
+	0200  SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb]
+	0400  SecureMate SD/MMC Reader
+	0621  SDDR-86 Imagemate 6-in-1 Reader
+	0810  SDDR-75 ImageMate CF-SM Reader
+	0830  ImageMate CF/MMC/SD Reader
+	5150  SDCZ2 Cruzer Mini Flash Drive (thin)
+	5151  Cruzer Micro 256/512MB Flash Drive
+	7104  Cruzer Micro Mini 256MB Flash Drive
+	7112  Cruzer Micro 128MB Flash Drive
+	7113  Cruzer Micro 256MB Flash Drive
+	8185  SDCZ2 Cruzer Mini Flash Drive (older, thick)
+	8889  SDDR-88 Imagemate 8-in-1 Reader
+0782  Trackerball
+0783  C3PO
+	0003  LTC31 SmartCard Reader
+0784  Vivitar, Inc.
+	0100  Vivicam 2655
+	1310  Vivicam 3305
+	1688  Vivicam 3665
+	2888  Polaroid DC700
+	3330  Nytec ND-3200 Camera
+	5260  Werlisa Sport PX 100 / JVC GC-A33 Camera
+	5300  Pretec dc530
+0785  NTT-ME
+	0001  MN128mini-V ISDN TA
+	0003  MN128mini-J ISDN TA
+0789  Logitec Corp.
+078b  Happ Controls, Inc.
+	0010  Driving UGCI
+	0020  Flying UGCI
+	0030  Fighting UGCI
+078e  Brincom, Inc.
+0790  Pro-Image Manufacturing Co., Ltd
+0791  Copartner Wire and Cable Mfg. Corp.
+0792  Axis Communications AB
+0793  Wha Yu Industrial Co., Ltd
+0794  ABL Electronics Corp.
+0795  RealChip, Inc.
+0796  Certicom Corp.
+0797  Grandtech Semiconductor Corp.
+	8001  SmartCam
+	801c  Meade Binoculars/Camera
+079b  Sagem
+079d  Alfadata Computer Corp.
+	0201  GamePort Adapter
+07a1  Digicom S.p.A.
+	d952  Palladio USB V.92 Modem
+07a2  National Technical Systems
+07a3  Onnto Corp.
+07a4  Be, Inc.
+07a6  ADMtek, Inc.
+	0986  AN986 Pegasus Ethernet
+	8511  ADM8511 Pegasus II Ethernet
+07aa  Corega K.K.
+	0001  Ether USB-T Ethernet [klsi]
+	0004  FEther USB-TX Ethernet [pegasus]
+	0012  Stick-11 802.11b Adapter
+	7613  Stick-11 V2 802.11b Adapter
+07ab  Freecom Technologies
+	fc01  IDE bridge
+	fc03  USB2-IDE IDE bridge
+07af  Microtech
+	0004  SCSI-DB25 SCSI Bridge [shuttle]
+	0005  SCSI-HD50 SCSI Bridge [shuttle]
+	0006  CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle]
+07b0  Trust Technologies
+	0001  ISDN TA
+07b1  IMP, Inc.
+07b2  Motorola BCS, Inc.
+	4100  SurfBoard SB4100 Cable Modem
+	4200  SurfBoard SB4200 Cable Modem
+	5100  SurfBoard SB5100 Cable Modem
+	5120  Surfboard SB5120 Cable Modem (RNDIS)
+07b3  Plustek, Inc.
+	0001  OpticPro 1212U Scanner
+	0010  OpticPro U12 Scanner
+	0011  OpticPro U24 Scanner
+	0013  OpticPro UT12 Scanner
+	0015  OpticPro U24 Scanner
+	0017  OpticPro UT12/16/24 Scanner
+	0400  OpticPro 1248U Scanner
+	0401  OpticPro 1248U Scanner #2
+	0403  OpticPro U16B Scanner
+07b4  Olympus Optical Co., Ltd
+	0100  Camedia C-2100/C-3000 Ultra Zoom Camera
+	0102  Camedia E-10/C-220/C-50 Camera
+	0105  Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560 Zoom Camera
+	0112  MAUSB-100 xD Card Reader
+	0114  C-350Z Camera
+	0203  Digital Voice Recorder DW-90
+	0206  Digital Voice Recorder DS-330
+	0207  Digital Voice Recorder & Camera W-10
+	020d  Digital Voice Recorder VN-240PC
+07b5  Mega World International, Ltd
+	9902  GamePad
+07b6  Marubun Corp.
+07b7  TIME Interconnect, Ltd
+07b8  D-Link Corp.
+	4000  DU-E10 Ethernet [klsi]
+	4002  DU-E100 Ethernet [pegasus]
+	abc1  DU-E10 Ethernet [pegasus]
+	f101  DSB-560 Modem [atlas]
+07bc  Canon Computer Systems, Inc.
+07bd  Webgear, Inc.
+07be  Veridicom
+07c0  Code Mercenaries Hard- und Software GmbH
+	1121  The Claw
+	1500  IO-Warrior 40
+	1501  IO-Warrior 24
+	1502  IO-Warrior 48
+	1503  IO-Warrior 28
+07c4  Datafab Systems, Inc.
+	a000  CompactFlash Card Reader
+	a001  CompactFlash & SmartMedia Card Reader [eusb]
+	a002  Disk Drive
+	a005  CompactFlash & SmartMedia Card Reader
+	a006  SmartMedia Card Reader
+	a109  LC1 CompactFlash & SmartMedia Card Reader
+	a200  DF-UT-06 Hama MMC/SD Reader
+	a400  CompactFlash & Microdrive Reader
+	b004  MMC/SD Reader
+07c5  APG Cash Drawer
+07c6  ShareWave, Inc.
+07c7  Powertech Industrial Co., Ltd
+07c8  B.U.G., Inc.
+07c9  Allied Telesyn International
+07ca  AVerMedia Technologies, Inc.
+07cb  Kingmax Technology, Inc.
+07cc  Carry Computer Eng., Co., Ltd
+	0000  CF Card Reader
+	0003  SM Card Reader
+	0004  SM/CF/PCMCIA Card Reader
+	0006  SM/CF/PCMCIA Card Reader
+	000c  SM/CF Card Reader
+	000d  SM/CF Card Reader
+	0200  6-in-1 Card Reader
+	0301  6-in-1 Card Reader
+07cd  Elektor
+	0001  USBuart Serial Port
+07cf  Casio Computer Co., Ltd
+	1001  QV-8000SX/5700/3000EX Digicam
+	2002  E-125 Cassiopeia Pocket PC
+	3801  WMP-1 MP3-Watch
+	4001  Label Printer KL-P1000
+	4500  LV-20 Digital Camera
+07d0  Dazzle
+	0001  Digital Video Creator I
+	0002  Global Village VideoFX Grabber
+	0003  Fusion Model DVC-50 Rev 1 (NTSC)
+	0004  DVC-800 (PAL) Grabber
+07d1  D-Link System
+07d2  Aptio Products, Inc.
+07d3  Cyberdata Corp.
+07d7  GCC Technologies, Inc.
+07da  Arasan Chip Systems
+07df  David Electronics Co., Ltd
+07e1  Ambient Technologies, Inc.
+	5201  V.90 Modem
+07e2  Elmeg GmbH & Co., Ltd
+07e3  Planex Communications, Inc.
+07e4  Movado Enterprise Co., Ltd
+07e5  QPS, Inc.
+	5c01  Que! CDRW
+07e6  Allied Cable Corp.
+07e7  Mirvo Toys, Inc.
+07e8  Labsystems
+07ea  Iwatsu Electric Co., Ltd
+07eb  Double-H Technology Co., Ltd
+07ec  Taiyo Electric Wire & Cable Co., Ltd
+07ee  Torex Retail (formerly Logware)
+	0002  Cash Drawer I/F
+07f6  Circuit Assembly Corp.
+07f7  Century Corp.
+07f9  Dotop Technology, Inc.
+07fa  Draytek
+	0778  miniVigor 128 ISDN TA
+07fd  Mark of the Unicorn
+	0000  FastLane MIDI Interface
+0801  Mag-Tek
+0802  Mako Technologies, LLC
+0803  Zoom Telephonics, Inc.
+	9700  2986L FaxModem
+0809  Genicom Technology, Inc.
+080a  Evermuch Technology Co., Ltd
+080c  Datalogic S.p.A.
+	0300  Gryphon D120 Barcode Scanner
+	0400  Gryphon D120 Barcode Scanner
+	0500  Gryphon D120 Barcode Scanner
+	0600  Gryphon M100 Barcode Scanner
+080d  Teco Image Systems Co., Ltd
+	0102  Hercules Scan@home 48
+0810  Personal Communication Systems, Inc.
+0813  Mattel, Inc.
+	0001  Intel Play QX3 Microscope
+081a  MG Logic
+	1000  Duo Pen Tablet
+081b  Indigita Corp.
+081c  Mipsys
+081e  AlphaSmart, Inc.
+0822  Reudo Corp.
+0825  GC Protronics
+0826  Data Transit
+0827  BroadLogic, Inc.
+0828  Sato Corp.
+0829  DirecTV Broadband, Inc. (Telocity)
+082d  Handspring
+	0100  Visor
+	0300  Treo 600
+0830  Palm, Inc.
+	0002  Palm M505
+	0003  Palm M515
+	0020  Palm I705
+	0040  Palm M125
+	0050  Palm M130
+	0060  Palm Tungsten T / Zire 71
+	0080  Palm
+0832  Kouwell Electronics Corp.
+0833  Sourcenext Corp.
+0835  Action Star Enterprise Co., Ltd
+0839  Samsung Techwin Co., Ltd
+	0005  Digimax Camera
+	0008  Digimax 230 Camera
+	1003  Digimax 210SE
+	1012  6500 Document Camera
+	1542  Digimax 50 Duo
+083a  Accton Technology Corp.
+	1046  10/100 Ethernet [pegasus]
+	5046  SpeedStream 10/100 Ethernet [pegasus]
+083f  Global Village
+	b100  TelePort V.90 Fax/Modem
+0840  Argosy Research, Inc.
+0841  Rioport.com, Inc.
+	0001  Rio 500
+0844  Welland Industrial Co., Ltd
+0846  NetGear, Inc.
+	1001  EA101 Ethernet [klsi]
+	4110  MA111 WiFi (v1)
+	4200  WG121 WiFi (v1)
+	4210  WG121 WiFi (v2)
+	4220  WG111 WiFi (v1)
+	4230  MA111 WiFi
+	4240  WG111 WiFi (v2)
+	6a00  WG111 WiFi (v2)
+084d  Minton Optic Industry Co., Inc.
+	0003  S-Cam F5 Digital Camera
+	0011  Argus DC3500 Digital Camera
+084e  KB Gear
+	1002  Pablo Tablet
+084f  Empeg
+	0001  Empeg-Car Mark I/II Player
+0850  Fast Point Technologies, Inc.
+0851  Macronix International Co., Ltd
+	1543  Maxell WS30 Slim Digital Camera
+0852  CSEM
+0854  ActiveWire, Inc.
+	0100  I/O Board
+	0101  I/O Board, rev1
+0856  B&B Electronics
+	AC01  uLinks USOTL4 RS422/485 Adapter
+0858  Hitachi Maxell, Ltd
+0859  Minolta Systems Laboratory, Inc.
+085a  Xircom
+	0001  Portstation Dual Serial Port
+	0003  Portstation Paraller Port
+	000b  Portstation Dual PS/2 Port
+	0299  Colorvision, Inc. Monitor Spyder
+	8027  PGSDB9 Serial Port
+085c  ColorVision, Inc.
+	0200  Monitor Spyder
+0862  Teletrol Systems, Inc.
+0863  Filanet Corp.
+0864  NetGear, Inc.
+	4100  MA101 802.11b Adapter
+	4102  MA101 802.11b Adapter
+0867  Data Translation, Inc.
+	9812  ECON Data acquisition unit
+086a  Emagic Soft-und Hardware GmbH
+086c  DeTeWe - Deutsche Telephonwerke AG & Co.
+	1001  Eumex 504PC ISDN TA
+	1003  TA33 ISDN TA
+	1055  Eumex 220 ISDN TA
+086e  System TALKS, Inc.
+086f  MEC IMEX, Inc.
+0870  Metricom
+0871  SanDisk, Inc.
+	0001  SDDR-01 Compact Flash Reader
+	0002  SDDR-31 Compact Flash Reader
+	0005  SDDR-05 Compact Flash Reader
+0873  Xpeed, Inc.
+0874  A-Tec Subsystem, Inc.
+0879  Comtrol Corp.
+087c  Adesso/Kbtek America, Inc.
+087d  Jaton Corp.
+087e  Fujitsu Computer Products of America
+087f  Virtual IP Group, Inc.
+0880  APT Technologies, Inc.
+0883  Recording Industry Association of America (RIAA)
+0885  Boca Research, Inc.
+0886  XAC Automation Corp.
+0887  Hannstar Electronics Corp.
+088b  MassWorks, Inc.
+	4944  MassWorks ID-75 TouchScreen
+0892  DioGraphy, Inc.
+089c  United Technologies Research Cntr.
+089d  Icron Technologies Corp.
+089e  NST Co., Ltd
+089f  Primex Aerospace Co.
+08a5  e9, Inc.
+08a8  Andrea Electronics
+08ae  Macally (Mace Group, Inc.)
+08b4  Sorenson Vision, Inc.
+08b8  J. Gordon Electronic Design, Inc.
+	01f4  USBSIMM1
+08b9  RadioShack Corp. (Tandy)
+08bb  Texas Instruments Japan
+08bd  Citizen Watch Co., Ltd
+08c3  Precise Biometrics
+	0101  Precise 100 MC FingerPrint and SmartCard Reader
+08c4  Proxim, Inc.
+08c7  Key Nice Enterprise Co., Ltd
+08c8  2Wire, Inc.
+08c9  Nippon Telegraph and Telephone Corp.
+08ca  Aiptek International, Inc.
+	0010  Tablet
+	0020  APT-6000U Tablet
+	0021  APT-2 Tablet
+	0022  Tablet
+	0023  Tablet
+	0024  Tablet
+	0102  DualCam
+	0103  Pocket DV Digital Camera
+	0104  Pocket DVII
+	0106  Pocket DV3100+
+	0111  PenCam VGA Plus
+	2008  Mini PenCam 2
+	2010  Pocket CAM 3 Mega (webcam)
+	2011  Pocket CAM 3 Mega (storage)
+	2018  Pencam SD 2
+	2024  Pocket DV3500
+08cd  Jue Hsun Ind. Corp.
+08ce  Long Well Electronics Corp.
+08cf  Productivity Enhancement Products
+08d1  smartBridges, Inc.
+	0001  smartNIC Ethernet [catc]
+08d3  Virtual Ink
+08d4  Fujitsu Siemens Computers
+	0009  SCR SmartCard Reader
+08d9  Increment P Corp.
+08dd  Billionton Systems, Inc.
+	0986  USB-100N Ethernet [pegasus]
+	0987  USBLP-100 HomePNA Ethernet [pegasus]
+	0988  USBEL-100 Ethernet [pegasus]
+	8511  USBE-100 Ethernet [pegasus2]
+08de  ???
+	7a01  802.11b Adapter
+08df  Spyrus, Inc.
+08e3  Olitec, Inc.
+	0002  USB-RS232 Bridge
+08e4  Pioneer Corp.
+08e5  Litronic
+08e6  Gemplus
+	0430  GemPC430 SmartCard Reader
+	0432  GemPC432 SmartCard Reader
+	0435  GemPC435 SmartCard Reader
+	0437  GemPC433 SL SmartCard Reader
+	3437  GemPC Twin SmartCard Reader
+	3438  GemPC Key SmartCard Reader
+08e7  Pan-International Wire & Cable
+08e8  Integrated Memory Logic
+08e9  Extended Systems, Inc.
+	0100  XTNDAccess IrDA Dongle
+08ea  Ericsson, Inc., Blue Ridge Labs
+08ec  M-Systems Flash Disk Pioneers
+	0010  DiskOnKey
+08ee  CCSI/Hesso
+08f0  Corex Technologies
+08f1  CTI Electronics Corp.
+08f5  SysTec Co., Ltd
+08f6  Logic 3 International, Ltd
+08f7  Vernier
+	0001  LabPro
+	0002  EasyTemp
+08f8  Keen Top International Enterprise Co., Ltd
+08f9  Wipro Technologies
+08fa  Caere
+08fb  Socket Communications
+08fc  Sicon Cable Technology Co., Ltd
+08fd  Digianswer A/S
+08ff  AuthenTec, Inc.
+0900  Pinnacle Systems, Inc.
+0901  VST Technologies
+0906  Faraday Technology Corp.
+0909  Audio-Technica Corp.
+090a  Trumpion Microelectronics, Inc.
+	1540  Digitex Container Flash Disk
+090b  Neurosmith
+090c  Feiya Technology Corp.
+	1000  Memory Bar
+090d  Multiport Computer Vertriebs GmbH
+090e  Shining Technology, Inc.
+090f  Fujitsu Devices, Inc.
+0910  Alation Systems, Inc.
+0911  Philips Speech Processing
+0912  Voquette, Inc.
+0915  GlobeSpan, Inc.
+0917  SmartDisk Corp.
+0919  Tiger Electronics
+	0100  Fast Flicks Digital Camera
+091e  Garmin International
+	0003  GPSmap (various models)
+0920  Echelon Co.
+0921  GoHubs, Inc.
+0922  Dymo-CoStar Corp.
+	0007  LabelWriter 330
+	0009  LabelWriter 310
+0923  IC Media Corp.
+	010f  SIIG MobileCam
+0924  Xerox
+0925  Lakeview Research
+	8101  Phidgets, Inc., 1-Motor PhidgetServo v2.0
+	8104  Phidgets, Inc., 4-Motor PhidgetServo v2.0
+	8800  WiseGroup Ltd, MP-8800 Quad Joypad
+	8866  WiseGroup Ltd, MP-8866 Dual Joypad
+0927  Summus, Ltd
+0928  Oxford Semiconductor, Ltd
+0929  American Biometric Co.
+092a  Toshiba Information & Industrial Sys. And Services
+092b  Sena Technologies, Inc.
+0930  Toshiba Corp.
+	6519  Kingston DataTraveler 2.0 USB Stick
+	6533  512M USB Stick
+0931  Harmonic Data Systems, Ltd
+0932  Crescentec Corp.
+0933  Quantum Corp.
+0934  Netcom Systems
+0939  Lumberg, Inc.
+093a  Pixart Imaging, Inc.
+	2468  Easy Snap Snake Eye WebCam
+093b  Plextor Corp.
+	0042  PX-712UF DVD RW
+093c  Intrepid Control Systems, Inc.
+	0601  ValueCAN
+093d  InnoSync, Inc.
+093e  J.S.T. Mfg. Co., Ltd
+093f  Olympia Telecom Vertriebs GmbH
+0940  Japan Storage Battery Co., Ltd
+0941  Photobit Corp.
+0942  i2Go.com, LLC
+0943  HCL Technologies India Private, Ltd
+0944  KORG, Inc.
+0945  Pasco Scientific
+0948  Kronauer music in digital
+	0301  USB Pro (24/48)
+	0302  USB Pro (24/96 playback)
+	0303  USB Pro (24/96 record)
+	0304  USB Pro (16/48)
+	1105  USB One
+094b  Linkup Systems Corp.
+094d  Cable Television Laboratories
+0951  Kingston Technology
+	000a  KNU101TX 100baseTX Ethernet
+	1600  Data Traveler II Pen Drive
+0954  RPM Systems Corp.
+0955  NVidia Corp.
+0956  BSquare Corp.
+0957  Agilent Technologies, Inc.
+0958  CompuLink Research, Inc.
+0959  Cologne Chip AG
+095a  Portsmith
+095b  Medialogic Corp.
+095c  K-Tec Electronics
+095d  Polycom, Inc.
+0967  Acer (??)
+	0204  WarpLink 802.11b Adapter
+0968  Catalyst Enterprises, Inc.
+0971  Gretag-Macbeth AG
+0973  Schlumberger
+0974  Datagraphix, a business unit of Anacomp
+0975  OL'E Communications, Inc.
+0976  Adirondack Wire & Cable
+0977  Lightsurf Technologies
+0978  Beckhoff GmbH
+0979  Jeilin Technology Corp., Ltd
+097a  Minds At Work LLC
+097b  Knudsen Engineering, Ltd
+097c  Marunix Co., Ltd
+097d  Rosun Technologies, Inc.
+097f  Barun Electronics Co., Ltd
+0981  Oak Technology, Ltd
+0984  Apricorn
+0985  cab Produkttechnik GmbH & Co KG
+	00a3  A3/200 or A3/300 Label Printer
+098c  Vitana Corp.
+098d  INDesign
+098e  Integrated Intellectual Property, Inc.
+098f  Kenwood TMI Corp.
+0993  Gemstar eBook Group, Ltd
+	0001  REB1100 eBook Reader
+0996  Integrated Telecom Express, Inc.
+099a  Zippy Technology Corp.
+	610c  EL-610 Super Mini Electron luminescent Keyboard
+09a3  PairGain Technologies
+09a4  Contech Research, Inc.
+09a5  VCON Telecommunications
+09a6  Poinchips
+09a7  Data Transmission Network Corp.
+09a8  Lin Shiung Enterprise Co., Ltd
+09a9  Smart Card Technologies Co., Ltd
+09aa  Intersil Corp.
+	1000  Prism GT 802.11b/g Adapter
+	3642  Prism 2.x 802.11b Adapter
+09ae  Tripp Lite
+09b2  Franklin Electronic Publishers, Inc.
+	0001  eBookman Palm Computer
+09b3  Altius Solutions, Inc.
+09b4  MDS Telephone Systems
+09b5  Celltrix Technology Co., Ltd
+09bc  Grundig
+	0002  MPaxx MP150 MP3 Player
+09be  MySmart.Com
+	0001  MySmartPad
+09bf  Auerswald GmbH & Co. KG
+	00c0  COMpact 2104 ISDN PBX
+	00db  COMpact 4410/2206 ISDN ISDN
+	00f1  COMfort System Telephones
+09c1  Arris Interactive LLC
+09c2  Nisca Corp.
+09c3  ActivCard, Inc.
+	0008  SmartCard Reader
+09c4  ACTiSYS Corp.
+	0011  ACT-IR2000U IrDA Dongle
+09c5  Memory Corp.
+09cc  Workbit Corp.
+09cd  Psion Dacom Home Networks, Ltd
+09ce  City Electronics, Ltd
+09cf  Electronics Testing Center, Taiwan
+09d1  NeoMagic, Inc.
+09d2  Vreelin Engineering, Inc.
+09d3  Com One
+	0001  ISDN TA
+09d9  KRF Tech, Ltd
+09da  A4 Tech Co., Ltd
+	0006  Optical Mouse WOP-35 / Trust 450L Optical Mouse
+	001a  Wireless Mouse & RXM-15 Receiver
+	002a  Wireless Optical Mouse NB-30
+09db  Measurement Computing Corp.
+	0075  MiniLab 1008
+	0076  PMD-1024
+	007A  PMD-1208LS
+09dc  Aimex Corp.
+09dd  Fellowes, Inc.
+09df  Addonics Technologies Corp.
+09e1  Intellon Corp.
+09e5  Jo-Dan International, Inc.
+09e6  Silutia, Inc.
+09e7  Real 3D, Inc.
+09e8  AKAI  Professional M.I. Corp.
+09e9  Chen-Source, Inc.
+09eb  IM Networks, Inc.
+	4331  iRhythm Tuner Remote
+09ef  Xitel
+	0101  MD-Port DG2 MiniDisc Interface
+09f5  AresCom
+09f6  RocketChips, Inc.
+09f7  Edu-Science (H.K.), Ltd
+09f8  SoftConnex Technologies, Inc.
+09f9  Bay Associates
+09fa  Mtek Vision
+09fb  Altera
+09ff  Gain Technology Corp.
+0a00  Liquid Audio
+0a01  ViA, Inc.
+0a07  Ontrak Control Systems Inc.
+	0064  ADU100 Data Acquisition Interface
+	00c8  ADU200 Relay I/O Interface
+	00d0  ADU208 Data Acquisition Interface
+0a0b  Cybex Computer Products Co.
+0a11  Xentec, Inc.
+0a12  Cambridge Silicon Radio, Ltd
+	0001  Bluetooth Dongle (HCI mode)
+	1000  Bluetooth Dongle (HID proxy mode)
+0a13  Telebyte, Inc.
+0a14  Spacelabs Medical, Inc.
+0a15  Scalar Corp.
+0a16  Trek Technology (S) PTE, Ltd
+	9988  Trek2000 TD-G2
+0a17  Pentax Corp.
+	0004  Pentax Optio 330
+	0006  Pentax Optio S
+	0007  Pentax Optio 550
+	003d  Pentax Optio S55
+0a18  Heidelberger Druckmaschinen AG
+0a19  Hua Geng Technologies, Inc.
+0a21  Medtronic Physio Control Corp.
+0a22  Century Semiconductor USA, Inc.
+0a2c  AK-Modul-Bus Computer GmbH
+	0008  GPIO Ports
+0a39  Gilat Satellite Networks, Ltd
+0a3a  PentaMedia Co., Ltd
+0a3c  NTT DoCoMo, Inc.
+0a3d  Varo Vision
+0a3f  Swissonic AG
+0a43  Boca Systems, Inc.
+0a46  Davicom Semiconductor, Inc.
+0a47  Hirose Electric
+0a48  I/O Interconnect
+	3258  Dane Elec zMate SD Reader
+	3259  Dane Elec zMate CF Reader
+0a4b  Fujitsu Media Devices, Ltd
+0a4c  Computex Co., Ltd
+0a4d  Evolution Electronics, Ltd
+	008e  MK-249C MIDI Keyboard
+	00a3  MK-461C MIDI Keyboard
+	00f5  UC-33e MIDI Controller
+0a4e  Steinberg Soft-und Hardware GmbH
+0a4f  Litton Systems, Inc.
+0a50  Mimaki Engineering Co., Ltd
+0a51  Sony Electronics, Inc.
+0a52  Jebsee Electronics Co., Ltd
+0a53  Portable Peripheral Co., Ltd
+0a5a  Electronics For Imaging, Inc.
+0a5b  EAsics NV
+0a5c  Broadcom Corp.
+	2033  BCM2033 Bluetooth
+	2035  BCM2035 Bluetooth
+0a5d  Diatrend Corp.
+0a5f  Zebra
+	0009  LP2844 Printer
+0a62  MPMan
+	0010  MPMan MP-F40 MP3 Player
+0a66  ClearCube Technology
+0a67  Medeli Electronics Co., Ltd
+0a68  Comaide Corp.
+0a69  Chroma ate, Inc.
+0a6b  Green House Co., Ltd
+	0001  Compact Flash R/W with MP3 player
+0a6c  Integrated Circuit Systems, Inc.
+0a6d  UPS Manufacturing
+0a6e  Benwin
+0a6f  Core Technology, Inc.
+	0400  Xanboo
+0a70  International Game Technology
+0a72  Sanwa Denshi
+0a7d  NSTL, Inc.
+0a7e  Octagon Systems Corp.
+0a80  Rexon Technology Corp., Ltd
+0a81  Chesen Electronics Corp.
+	0101  Keyboard
+	0103  Keyboard
+	0203  Mouse
+	0205  PS/2 Keyboard+Mouse Adapter
+0a82  Syscan
+	4600  TravelScan 460/464
+0a83  NextComm, Inc.
+0a84  Maui Innovative Peripherals
+0a85  Idexx Labs
+0a86  NITGen Co., Ltd
+0a8d  Picturetel
+0a8e  Japan Aviation Electronics Industry, Ltd
+0a90  Candy Technology Co., Ltd
+0a91  Globlink Technology, Inc.
+0a92  EGO SYStems, Inc.
+0a93  C Technologies AB
+0a94  Intersense
+0aa3  Lava Computer Mfg., Inc.
+0aa4  Develco Elektronik
+0aa5  First International Digital
+0aa6  Perception Digital, Ltd
+	0101  Hercules Jukebox
+0aa7  Wincor Nixdorf GmbH & Co KG
+	0200  POS Display BA63
+	0201  POS Display BA66
+	0300  POS Printer TH210
+	0302  POS Printer TH220
+	0305  Lottery Printer XiPrintPlus
+	0306  POS Printer TH320
+	0308  POS Printer TH420
+	4304  Banking Printer TP07
+0aa8  TriGem Computer, Inc.
+0aa9  Baromtec Co.
+	f01b  Medion MD 6242 MP3 Player
+0aaa  Japan CBM Corp.
+0aab  Vision Shape Europe SA
+0aac  iCompression, Inc.
+0aad  Rohde & Schwarz GmbH & Co. KG
+0aae  NEC infrontia Corp. (Nitsuko)
+0aaf  Digitalway Co., Ltd
+0ab0  Arrow Strong Electronics Co., Ltd
+0aba  Ellisys
+	8001  USB Tracker 110 Protocol Analyzer
+0abe  Stereo-Link
+	0101  SL1200 DAC
+0ac3  Sanyo Semiconductor Company Micro
+0ac4  Leco Corp.
+0ac5  I & C Corp.
+0ac6  Singing Electrons, Inc.
+0ac7  Panwest Corp.
+0ac8  Z-Star Microelectronics Corp.
+	0302  ZC0302 WebCam
+	301b  ZC0301 WebCam
+	303b  ZC0303 WebCam
+0ac9  Micro Solutions, Inc.
+	0000  Backpack CD-ReWriter
+	0011  Backpack 40GB Hard Drive
+0acc  Koga Electronics Co.
+0acd  ID Tech
+0ace  ZyDAS
+	1201 802.11b WiFi
+	1211 802.11b/g USB2 WiFi
+0acf  Intoto, Inc.
+0ad0  Intellix Corp.
+0ad1  Remotec Technology, Ltd
+0ad2  Service & Quality Technology Co., Ltd
+0ae3  Allion Computer, Inc.
+0ae4  Taito Corp.
+0ae7  Neodym Systems, Inc.
+0ae8  System Support Co., Ltd
+0ae9  North Shore Circuit Design L.L.P.
+0aea  SciEssence, LLC
+0aeb  TTP Communications, Ltd
+0aec  Neodio Technologies Corp.
+	3050  ND3050 8-in-1 Card Reader
+	3260  7-in-1 Card Reader
+	5010  ND5010 Card Reader
+0af0  Option
+	5000  UMTS Card
+0af6  Silver I Co., Ltd
+0af7  B2C2, Inc.
+	0101  Digital TV USB Receiver (DVB-S/T/C / ATSC)
+0af9  Hama, Inc.
+	0010  USB SightCam 100
+	0011  Micro Innovations IC50C WebCam
+0afc  Zaptronix Ltd
+0afd  Tateno Dennou, Inc.
+0afe  Cummins Engine Co.
+0aff  Jump Zone Network Products, Inc.
+0b05  ASUSTek Computer, Inc.
+0b0c  Todos Data System AB
+	0009 Todos Argos Mini II Smart Card Reader
+0b0e  GN Netcom
+0b0f  AVID Technology
+0b10  Pcally
+0b11  I Tech Solutions Co., Ltd
+0b1e  Electronic Warfare Assoc., Inc. (EWA)
+0b1f  Insyde Software Corp.
+0b20  TransDimension, Inc.
+0b21  Yokogawa Electric Corp.
+0b22  Japan System Development Co., Ltd
+0b23  Pan-Asia Electronics Co., Ltd
+0b24  Link Evolution Corp.
+0b27  Ritek Corp.
+0b28  Kenwood Corp.
+0b2c  Village Center, Inc.
+0b30  PNY Technologies, Inc.
+	0006  SM Media-Shuttle Card Reader
+0b33  Contour Design, Inc.
+0b37  Hitachi ULSI Systems Co., Ltd
+0b39  Omnidirectional Control Technology, Inc.
+0b3a  IPaxess
+0b3b  Tekram Technology Co., Ltd
+	1601  Allnet 0193 802.11b Adapter
+	1602  ZyXEL ZyAIR B200 802.11b Adapter
+	1612  AIR.Mate 2@net 802.11b Adapter
+0b3c  Olivetti Techcenter
+0b3e  Kikusui Electronics Corp.
+0b41  Hal Corp.
+0b43  Play.com, Inc.
+	0003  PS2 Controller Converter
+0b47  Sportbug.com, Inc.
+0b48  TechnoTrend AG
+	1003  Technotrend/Hauppauge USB-Nova
+	1005  Technotrend/Hauppauge USB-Nova
+	1006  Technotrend/Hauppauge DEC3000-s
+	1008  Technotrend/Hauppauge DEC2000-t
+	1009  Technotrend/Hauppauge DEC2540-t
+0b49  ASCII Corp.
+	064f  Trance Vibrator
+0b4b  Pine Corp. Ltd.
+	0100  D'music MP3 Player
+0b4e  Musical Electronics, Ltd
+0b50  Dumpries Co., Ltd
+0b51  Comfort Keyboard Co.
+	0020  Comfort Keyboard
+0b52  Colorado MicroDisplay, Inc.
+0b54  Sinbon Electronics Co., Ltd
+0b56  TYI Systems, Ltd
+0b57  Beijing HanwangTechnology Co., Ltd
+0b59  Lake Communications, Ltd
+0b5a  Corel Corp.
+0b5f  Green Electronics Co., Ltd
+0b60  Nsine, Ltd
+0b61  NEC Viewtechnology, Ltd
+0b62  Orange Micro, Inc.
+	0059  iBOT2 WebCam
+0b63  ADLink Technology, Inc.
+0b64  Wonderful Wire Cable Co., Ltd
+0b65  Expert Magnetics Corp.
+0b69  CacheVision
+0b6a  Maxim Integrated Products
+0b6f  Nagano Japan Radio Co., Ltd
+0b70  PortalPlayer, Inc.
+0b71  SHIN-EI Sangyo Co., Ltd
+0b72  Embedded Wireless Technology Co., Ltd
+0b73  Computone Corp.
+0b75  Roland DG Corp.
+0b79  Sunrise Telecom, Inc.
+0b7a  Zeevo, Inc.
+0b7b  Taiko Denki Co., Ltd
+0b7c  ITRAN Communications, Ltd
+0b7d  Astrodesign, Inc.
+0b84  Rextron Technology, Inc.
+0b85  Elkat Electronics, Sdn., Bhd.
+0b86  Exputer Systems, Inc.
+0b87  Plus-One I & T, Inc.
+0b88  Sigma Koki Co., Ltd, Technology Center
+0b89  Advanced Digital Broadcast, Ltd
+0b95  ASIX Electronics Corp.
+0b96  Sewon Telecom
+0b97  O2 Micro, Inc.
+	7762  Oz776 SmartCard Reader
+0b98  Playmates Toys, Inc.
+0b99  Audio International, Inc.
+0b9b  Dipl.-Ing. Stefan Kunde
+	4012  Reflex RC-controller Interface
+0b9d  Softprotec Co.
+0b9f  Chippo Technologies
+0baf  U.S. Robotics
+	00eb  USR1120 802.11b Adapter
+	0118  U5 802.11g Adapter
+	6112  FaxModem Model 5633
+0bb0  Concord Camera Corp.
+0bb1  Infinilink Corp.
+0bb2  Ambit Microsystems Corp.
+	6098  USB Cable Modem
+0bb3  Ofuji Technology
+0bb4  High Tech Computer Corp.
+	00ce  mmO2 XDA GSM/GPRS Pocket PC
+	00cf  SPV C500 Smart Phone
+	0a02  Himalaya GSM/GPRS Pocket PC
+	0a51  SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC
+0bb5  Murata Manufacturing Co., Ltd
+0bb6  Network Alchemy
+0bb7  Joytech Computer Co., Ltd
+0bb8  Hitachi Semiconductor and Devices Sales Co., Ltd
+0bb9  Eiger M&C Co., Ltd
+0bba  ZAccess Systems
+0bbb  General Meters Corp.
+0bbc  Assistive Technology, Inc.
+0bbd  System Connection, Inc.
+0bc0  Knilink Technology, Inc.
+0bc1  Fuw Yng Electronics Co., Ltd
+0bc2  Seagate RSS LLC
+0bc3  IPWireless, Inc.
+0bc4  Microcube Corp.
+0bc5  JCN Co., Ltd
+0bc6  ExWAY, Inc.
+0bc7  X10 Wireless Technology, Inc.
+	0004  X10 Receiver
+0bc8  Telmax Communications
+0bc9  ECI Telecom, Ltd
+0bca  Startek Engineering, Inc.
+0bcb  Perfect Technic Enterprise Co., Ltd
+0bda  Realtek Semiconductor Corp.
+	8150  RTL8150 Fast Ethernet Adapter
+	8151  RTL8151 Adapteon Business Mobile Networks BV
+0bdb  Ericsson Business Mobile Networks BV
+0bdc  Y Media Corp.
+0bdd  Orange PCS
+0be2  Kanda Tsushin Kogyo Co., Ltd
+0be3  TOYO Corp.
+0be4  Elka International, Ltd
+0be5  DOME imaging systems, Inc.
+0be6  Dong Guan Humen Wonderful Wire Cable Factory
+0bee  LTK Industries, Ltd
+0bef  Way2Call Communications
+0bf0  Pace Micro Technology PLC
+0bf1  Intracom S.A.
+0bf2  Konexx
+0bf6  Addonics Technologies, Inc.
+	a002  IDE Bridge
+0bf7  Sunny Giken, Inc.
+0bf8  Fujitsu Siemens Computers
+	1001  Fujitsu Pocket Loox 600 PDA
+0c04  MOTO Development Group, Inc.
+0c05  Appian Graphics
+0c06  Hasbro Games, Inc.
+0c07  Infinite Data Storage, Ltd
+0c08  Agate
+	0378  Q 16MB Storage Device
+0c09  Comjet Information System
+0c0a  Highpoint Technologies, Inc.
+0c0b  Dura Micro, Inc. (Acomdata)
+	27cb  6-in-1 Flash Reader and Writer
+	a109  CF/SM Reader and Writer
+	a10c  SD/MS Reader and Writer
+	b004  MMC/SD Reader and Writer
+0c12  Zeroplus
+	0005  PSX Vibration Feedback Converter
+	8809  Red Octane Ignition Xbox DDR Pad
+0c15  Iris Graphics
+0c16  Gyration, Inc.
+0c17  Cyberboard A/S
+0c18  SynerTek Korea, Inc.
+0c19  cyberPIXIE, Inc.
+0c1a  Silicon Motion, Inc.
+0c1b  MIPS Technologies
+0c1c  Hang Zhou Silan Electronics Co., Ltd
+0c22  Tally Printer Corp.
+0c23  Lernout + Hauspie
+0c24  Taiyo Yuden
+0c25  Sampo Corp.
+0c2e  Metro
+	0200  Metrologic Scanner
+0c35  Eagletron, Inc.
+0c36  E Ink Corp.
+0c37  e.Digital
+0c38  Der An Electric Wire & Cable Co., Ltd
+0c39  IFR
+0c3a  Furui Precise Component (Kunshan) Co., Ltd
+0c3b  Komatsu, Ltd
+0c3c  Radius Co., Ltd
+0c3d  Innocom, Inc.
+0c3e  Nextcell, Inc.
+0c44  Motorola iDEN
+0c45  Microdia
+	1060  iFlash SM-Direct Card Reader
+	6001  Genius VideoCAM NB
+	6005  Sweex Mini WebCam
+	6029  Triplex i-mini PC Camera
+	602a  Meade ETX-105EC Camera
+	602c  Clas Ohlson TWC-30XOP WebCam
+0c46  WaveRider Communications, Inc.
+0c4b  Reiner SCT Kartensysteme GmbH
+	0100  cyberJack e-com/pinpad
+	0300  cyberJack pinpad(a)
+0c52  Sealevel Systems, Inc.
+0c53  ViewPLUS, Inc.
+0c54  Glory, Ltd
+0c55  Spectrum Digital, Inc.
+	0510 Spectrum Digital XDS510 JTAG Debugger
+0c56  Billion Bright, Ltd
+0c57  Imaginative Design Operation Co., Ltd
+0c58  Vidar Systems Corp.
+0c59  Dong Guan Shinko Wire Co., Ltd
+0c5a  TRS International Mfg., Inc.
+0c5e  Xytronix Research & Design
+0c62  Chant Sincere Co., Ltd
+0c63  Toko, Inc.
+0c64  Signality System Engineering Co., Ltd
+0c65  Eminence Enterprise Co., Ltd
+0c66  Rexon Electronics Corp.
+0c67  Concept Telecom, Ltd
+0c70  MCT Elektronikladen
+	0000  USB08 Development board
+0c74  Optronic Laboratories Inc.
+	0002  OL 700-30 Goniometer
+0c76  JMTek, LLC.
+	0003  USBdisk
+	0005  USBdisk
+	0006  Transcend JetFlash
+0c77  Sipix Group, Ltd
+0c78  Detto Corp.
+0c79  NuConnex Technologies Pte., Ltd
+0c7a  Wing-Span Enterprise Co., Ltd
+0c86  NDA Technologies, Inc.
+0c88  Kyocera Wireless Corp.
+0c89  Honda Tsushin Kogyo Co., Ltd
+0c8a  Pathway Connectivity, Inc.
+0c8b  Wavefly Corp.
+0c8c  Coactive Networks
+0c8d  Tempo
+0c8e  Cesscom Co., Ltd
+0c8f  Applied Microsystems
+0c99  Innochips Co., Ltd
+0c9a  Hanwool Robotics Corp.
+0c9b  Jobin Yvon, Inc.
+0ca2  Zyfer
+0ca3  Sega Corp.
+0ca4  ST&T Instrument Corp.
+0ca5  BAE Systems Canada, Inc.
+0ca6  Castles Technology Co., Ltd
+0ca7  Information Systems Laboratories
+0cad  Motorola CGISS
+0cae  Ascom Business Systems, Ltd
+0caf  Buslink
+	2515  Flash Disk Embedded Hub
+	2516  Flash Disk Security Device
+	2517  Flash Disk Mass Storage Device
+	3a00  Hard Drive
+0cb0  Flying Pig Systems
+0cb1  Innovonics, Inc.
+0cb6  Celestix Networks, Pte., Ltd
+0cb7  Singatron Enterprise Co., Ltd
+0cb8  Opticis Co., Ltd
+0cba  Trust Electronic (Shanghai) Co., Ltd
+0cbb  Shanghai Darong Electronics Co., Ltd
+0cbc  Palmax Technology Co., Ltd
+0cbd  Pentel Co., Ltd (Electronics Equipment Div.)
+0cbe  Keryx Technologies, Inc.
+0cbf  Union Genius Computer Co., Ltd
+0cc0  Kuon Yi Industrial Corp.
+0cc1  Given Imaging, Ltd
+0cc2  Timex Corp.
+0cc3  Rimage Corp.
+0cc4  emsys GmbH
+0cc5  Sendo
+0cc6  Intermagic Corp.
+0cc7  Kontron Medical AG
+0cc8  Technotools Corp.
+0cc9  BroadMAX Technologies, Inc.
+0cca  Amphenol
+0ccb  SKNet Co., Ltd
+0ccc  Domex Technology Corp.
+0ccd  TerraTec Electronic GmbH
+	0038  Cinergy T^2 DVB-T Receiver
+0cd4  Bang Olufsen
+	0101  BeolinkPC2
+0cd7  NewChip S.r.l.
+0cd8  JS Digitech, Inc.
+0cd9  Hitachi Shin Din Cable, Ltd
+0cde  Z-Com
+	0002  XI-725/726 Prism2.5 802.11b Adapter
+	0005  XI-735 Prism3 802.11b Adapter
+	0006  Medion 40900 802.11b Adapter
+0cf1  e-Conn Electronic Co., Ltd
+0cf2  ENE Technology, Inc.
+0cf3  Atheros Communications, Inc.
+0cf4  Fomtex Corp.
+0cf5  Cellink Co., Ltd
+0cf6  Compucable Corp.
+0cf7  ishoni Networks
+0cf8  Clarisys, Inc.
+0cf9  Central System Research Co., Ltd
+0cfa  Inviso, Inc.
+0cfc  Minolta-QMS, Inc.
+0d06  telos EDV Systementwicklung GmbH
+0d0b  Contemporary Controls
+0d0c  Astron Electronics Co., Ltd
+0d0d  MKNet Corp.
+0d0e  Hybrid Networks, Inc.
+0d0f  Feng Shin Cable Co., Ltd
+0d10  Elastic Networks
+0d11  Maspro Denkoh Corp.
+0d12  Hansol Electronics, Inc.
+0d13  BMF Corp.
+0d14  Array Comm, Inc.
+0d15  OnStream b.v.
+0d16  Hi-Touch Imaging Technologies Co., Ltd
+0d17  NALTEC, Inc.
+0d18  coaXmedia
+0d19  Hank Connection Industrial Co., Ltd
+0d32  Leo Hui Electric Wire & Cable Co., Ltd
+0d33  AirSpeak, Inc.
+0d34  Rearden Steel Technologies
+0d35  Dah Kun Co., Ltd
+0d3c  Sri Cable Technology, Ltd
+0d3d  Tangtop Technology Co., Ltd
+0d3e  Fitcom, inc.
+0d3f  MTS Systems Corp.
+0d40  Ascor, Inc.
+0d41  Ta Yun Terminals Industrial Co., Ltd
+0d42  Full Der Co., Ltd
+0d46  Kobil Systems GmbH
+	3003  mIDentity Light / KAAN SIM III
+	4000  mIDentity (mass storage)
+	4001  mIDentity Basic/Classic (composite device)
+	4081  mIDentity Basic/Classic (installationless)
+0d49  Maxtor
+0d4a  NF Corp.
+0d4b  Grape Systems, Inc.
+0d4c  Tedas AG
+0d4d  Coherent, Inc.
+0d4e  Agere Systems Netherland BV
+0d4f  EADS Airbus France
+0d50  Cleware GmbH
+	0011  USB-Temp2 Thermometer
+0d51  Volex (Asia) Pte., Ltd
+0d53  HMI Co., Ltd
+0d54  Holon Corp.
+0d55  ASKA Technologies, Inc.
+0d56  AVLAB Technology, Inc.
+0d57  Solomon Microtech, Ltd
+0d5c  Belkin
+	a002  F5D6050 802.11b Adapter
+0d5e  Myacom, Ltd
+0d5f  CSI, Inc.
+0d60  IVL Technologies, Ltd
+0d61  Meilu Electronics (Shenzhen) Co., Ltd
+0d62  Darfon Electronics Corp.
+	a100  Benq Mouse
+0d63  Fritz Gegauf AG
+0d64  DXG Technology Corp.
+	0107  Horus MT-409 Camera
+	0303  DXG-305V Camera
+0d65  KMJP Co., Ltd
+0d66  TMT
+0d67  Advanet, Inc.
+0d68  Super Link Electronics Co., Ltd
+0d69  NSI
+0d6a  Megapower International Corp.
+0d6b  And-Or Logic
+0d70  Try Computer Co., Ltd
+0d71  Hirakawa Hewtech Corp.
+0d72  Winmate Communication, Inc.
+0d73  Hit's Communications, Inc.
+0d76  MFP Korea, Inc.
+0d77  Power Sentry/Newpoint
+0d78  Japan Distributor Corp.
+0d7a  MARX Datentechnik GmbH
+0d7b  Wellco Technology Co., Ltd
+0d7c  Taiwan Line Tek Electronic Co., Ltd
+0d7d  Phison Electronics Corp.
+	0100  PS1001/1011/1006/1026 Flash Disk
+	0110  Gigabyte FlexDrive
+	0240  I/O-Magic/Transcend 6-in-1 Card Reader
+	110E  NEC uPD720121/130 USB-ATA/ATAPI Bridge
+	1240  Apacer 6-in-1 Card Reader 2.0
+	1300  Flash Disk
+	1320  PS2031 Flash Disk
+	1420  PS2044 Pen Drive
+	1470  Vosonic X's-Drive II+ VP2160
+0d7e  American Computer & Digital Components
+0d7f  Essential Reality LLC
+0d80  H.R. Silvine Electronics, Inc.
+0d81  TechnoVision
+0d83  Think Outside, Inc.
+0d89  Oz Software
+0d8a  King Jim Co., Ltd
+0d8b  Ascom Telecommunications, Ltd
+0d8c  C-Media Electronics, Inc.
+	000c  Audio Adapter
+0d8d  Promotion & Display Technology, Ltd
+0d8e  Global Sun Technology, Inc.
+	7100  802.11b Adapter
+	7a01  PRISM25 802.11b Adapter
+0d8f  Pitney Bowes
+0d90  Sure-Fire Electrical Corp.
+0d96  Skanhex Technology, Inc.
+	3300  SX330z Camera
+	4100  SX410z Camera
+	4102  MD 9700 Camera
+	5200  SX-520z Camera
+0d97  Santa Barbara Instrument Group
+	0001  SBIG Astronomy Camera (without firmware)
+	0101  SBIG Astronomy Camera (with firmware)
+0d98  Mars Semiconductor Corp.
+0d99  Trazer Technologies, Inc.
+0d9a  RTX Telecom AS
+0d9b  Tat Shing Electrical Co.
+0d9c  Chee Chen Hi-Technology Co., Ltd
+0d9d  Sanwa Supply, Inc.
+0d9e  Avaya
+0d9f  Powercom Co., Ltd
+0da0  Danger Research
+0da1  Suzhou Peter's Precise Industrial Co., Ltd
+0da2  Land Instruments International, Ltd
+0da3  Nippon Electro-Sensory Devices Corp.
+0da4  Polar Electro OY
+0da7  IOGear, Inc.
+0da8  softDSP Co., Ltd
+	0001  SDS 200A Oscilloscope
+0dab  Cubig Group
+	0100  DVR/CVR-M140 MP3 Player
+0dad  Westover Scientific
+0db0  Micro Star International
+	1967  Bluetooth Dongle
+	4011  Medion Flash XL V2.0 Card Reader
+	697a  Bluetooth Dongle
+	6982  Medion Flash XL V2.7A Card Reader
+0db1  Wen Te Electronics Co., Ltd
+0db2  Shian Hwi Plug Parts, Plastic Factory
+0db3  Tekram Technology Co., Ltd
+0db4  Chung Fu Chen Yeh Enterprise Corp.
+0dbe  Jiuh Shiuh Precision Industry Co., Ltd
+0dbf  Quik Tech Solutions
+0dc0  Great Notions
+0dc1  Tamagawa Seiki Co., Ltd
+0dc3  Athena Smartcard Solutions, Inc.
+0dc4  Macpower Peripherals, Ltd
+0dc5  SDK Co., Ltd
+0dc6  Precision Squared Technology Corp.
+0dc7  First Cable Line, Inc.
+0dcd  NetworkFab Corp.
+	0001  Remote Interface Adapter
+	0002  High Bandwidth Codec
+0dd0  Access Solutions
+	1002  Triple Talk Speech Synthesizer
+0dd1  Contek Electronics Co., Ltd
+0dd2  Power Quotient International Co., Ltd
+0dd3  MediaQ
+0dd4  Custom Engineering SPA
+0dd5  California Micro Devices
+0dd7  Kocom Co., Ltd
+0dd8  Netac Technology Co., Ltd
+	e007  OnlyDisk U222 Pendrive
+0dd9  HighSpeed Surfing
+0dda  Integrated Circuit Solution, Inc.
+0ddb  Tamarack, Inc.
+0ddd  Datelink Technology Co., Ltd
+0dde  Ubicom, Inc.
+0de0  BD Consumer Healthcare
+0ded  Novasonics
+0dee  Lifetime Memory Products
+0def  Full Rise Electronic Co., Ltd
+0df6  Sitecom Europe B.V.
+	9071  zd1211 802.11g Adapter
+0df7  Mobile Action Technology, Inc.
+	0620  MA-620 Infrared Adapter
+	0700  MA-700 Bluetooth Adapter
+0dfa  Toyo Communication Equipment Co., Ltd
+0dfc  GeneralTouch Technology Co., Ltd
+	0001  Touchscreen
+0e03  Nippon Systemware Co., Ltd
+0e08  Winbest Technology Co., Ltd
+0e0c  Gesytec
+	0101  LonUSB LonTalk Network Adapter
+0e16  JMTek, LLC
+0e17  Walex Electronic, Ltd
+0e1b  Crewave
+0e21  Cowon Systems, Inc.
+	0300  iAudio CW200
+0e23  Liou Yuane Enterprise Co., Ltd
+0e25  VinChip Systems, Inc.
+0e26  J-Phone East Co., Ltd
+0e30  HeartMath LLC
+0e34  Micro Computer Control Corp.
+0e35  3Pea Technologies, Inc.
+0e36  TiePie engineering
+0e38  Stratitec, Inc.
+0e39  Smart Modular Technologies, Inc.
+0e3a  Neostar Technology Co., Ltd
+	1100  CW-1100 Wireless Network Adapter
+0e3b  Mansella, Ltd
+0e41  Line6, Inc.
+	4250  BassPODxt
+	4252  BassPODxt Pro
+	4642  BassPODxt Live
+	4650  PODxt Live
+	4750  GuitarPort
+	5044  PODxt
+	5050  PODxt Pro
+	534D  SeaMonkey
+0e48  Julia Corp., Ltd
+	0100  CardPro SmartCard Reader
+0e4a  Shenzhen Bao Hing Electric Wire & Cable Mfr. Co.
+0e4c  Radica Games, Ltd
+0e55  Speed Dragon Multimedia, Ltd
+0e5a  Active Co., Ltd
+0e5b  Union Power Information Industrial Co., Ltd
+0e5c  Bitland Information Technology Co., Ltd
+0e5d  Neltron Industrial Co., Ltd
+0e66  Hawking
+	400c  UF100 Ethernet [pegasus2]
+0e67  Fossil, Inc.
+	0002  Wrist PDA
+0e6a  Megawin Technology Co., Ltd
+0e70  Tokyo Electronic Industry Co., Ltd
+0e72  Hsi-Chin Electronics Co., Ltd
+0e75  TVS Electronics, Ltd
+0e7b  On-Tech Industry Co., Ltd
+0e7e  Gmate, Inc.
+	0001  Yopy 3000 PDA
+0e82  Ching Tai Electric Wire & Cable Co., Ltd
+0e8c  Well Force Electronic Co., Ltd
+0e90  WiebeTech, LLC
+0e91  VTech Engineering Canada, Ltd
+0e92  C's Glory Enterprise Co., Ltd
+0e93  eM Technics Co., Ltd
+0e95  Future Technology Co., Ltd
+0e96  Aplux Communications, Ltd
+0e97  Fingerworks, Inc.
+0e98  Advanced Analogic Technologies, Inc.
+0e99  Parallel Dice Co., Ltd
+0e9a  TA HSING Industries, Ltd
+0e9b  ADTEC Corp.
+0e9c  Streamzap, Inc.
+	0000  Streamzap Remote Control
+0e9f  Tamura Corp.
+0ea0  Ours Technology, Inc.
+	2126  7-in-1 Card Reader
+	2168  Transcend JetFlash 2.0 / Astone USB Drive
+	6803  OTI-6803 Flash Disk
+	6808  OTI-6808 Flash Disk
+	6828  OTI-6828 Flash Disk
+0ea6  Nihon Computer Co., Ltd
+0ea7  MSL Enterprises Corp.
+0ea8  CenDyne, Inc.
+0ead  Humax Co., Ltd
+0eb1  WIS Technologies, Inc.
+0eb2  Y-S Electronic Co., Ltd
+0eb3  Saint Technology Corp.
+0eb7  Endor AG
+0ebe  VWeb Corp.
+0ebf  Omega Technology of Taiwan, Inc.
+0ec0  LHI Technology (China) Co., Ltd
+0ec1  Abit Computer Corp.
+0ec2  Sweetray Industrial, Ltd
+0ec3  Axell Co., Ltd
+0ec4  Ballracing Developments, Ltd
+0ec5  GT Information System Co., Ltd
+0ec6  InnoVISION Multimedia, Ltd
+0ec7  Theta Link Corp.
+	1008  So., Show 301 Digital Camera
+0ecd  Lite-On IT Corp.
+0ece  TaiSol Electronics Co., Ltd
+0ecf  Phogenix Imaging, LLC
+0ed1  WinMaxGroup
+	6660  USB Flash Disk 64M-C
+	6680  USB Flash Disk 64M-B
+0ed2  Kyoto Micro Computer Co., Ltd
+0ed3  Wing-Tech Enterprise Co., Ltd
+0eda  Noriake Itron Corp.
+0edf  e-MDT Co., Ltd
+0ee0  Shima Seiki Mfg., Ltd
+0ee1  Sarotech Co., Ltd
+0ee2  AMI Semiconductor, Inc.
+0ee3  ComTrue Technology Corp.
+	1000  Image Tank 1.5
+0ee4  Sunrich Technology, Ltd
+0eee  Digital Stream Technology, Inc.
+0eef  D-WAV Scientific Co., Ltd
+	0001  eGalax TouchScreen
+0ef0  Hitachi Cable, Ltd
+0ef1  Aichi Micro Intelligent Corp.
+0ef2  I/O Magic Corp.
+0ef3  Lynn Products, Inc.
+0ef4  DSI Datotech
+0ef5  PointChips
+	2202  Flash Disk
+0ef6  Yield Microelectronics Corp.
+0ef7  SM Tech Co., Ltd (Tulip)
+0efe  Wem Technology, Inc.
+0efd  Oasis Semiconductor
+0f06  Visual Frontier Enterprise Co., Ltd
+0f08  CSL Wire & Plug (Shen Zhen) Co.
+0f0c  CAS Corp.
+0f0d  Hori Co., Ltd
+0f0e  Energy Full Corp.
+0f12  Mars Engineering Corp.
+0f13  Acetek Technology Co., Ltd
+0f19  Oracom Co., Ltd
+0f1b  Onset Computer Corp.
+0f1c  Funai Electric Co., Ltd
+0f1d  Iwill Corp.
+0f21  IOI Technology Corp.
+0f22  Senior Industries, Inc.
+0f23  Leader Tech Manufacturer Co., Ltd
+0f24  Flex-P Industries, Snd., Bhd.
+0f2d  ViPower, Inc.
+0f2e  Geniality Maple Technology Co., Ltd
+0f2f  Priva Design Services
+0f30  Jess Technology Co., Ltd
+0f31  Chrysalis Development
+0f32  YFC-BonEagle Electric Co., Ltd
+0f37  Kokuyo Co., Ltd
+0f38  Nien-Yi Industrial Corp.
+0f3d  Airprime, Incorporated
+	0112  CDMA 1xEVDO PC Card, PC 5220
+0f41  RDC Semiconductor Co., Ltd
+0f42  Nital Consulting Services, Inc.
+0f4b  St. John Technology Co., Ltd
+0f4c  WorldWide Cable Opto Corp.
+0f4d  Microtune, Inc.
+	1000  Bluetooth Dongle
+0f4e  Freedom Scientific
+0f52  Wing Key Electrical Co., Ltd
+0f53  Dongguan White Horse Cable Factory, Ltd
+0f54  Kawai Musical Instruments Mfg. Co., Ltd
+0f55  AmbiCom, Inc.
+0f5c  Prairiecomm, Inc.
+0f5d  NewAge International, LLC
+0f5f  Key Technology Corp.
+0f60  NTK, Ltd
+0f61  Varian, Inc.
+0f62  Acrox Technologies Co., Ltd
+0f68  Kobe Steel, Ltd
+0f69  Dionex Corp.
+0f6a  Vibren Technologies, Inc.
+0f73  DFI
+0f7c  DQ Technology, Inc.
+0f7d  NetBotz, Inc.
+0f7e  Fluke Corp.
+0f88  VTech Holdings, Ltd
+0f8b  Yazaki Corp.
+0f8c  Young Generation International Corp.
+0f8d  Uniwill Computer Corp.
+0f8e  Kingnet Technology Co., Ltd
+0f8f  Soma Networks
+0f97  CviLux Corp.
+0f98  CyberBank Corp.
+0f9c  Hyun Won, Inc.
+	0301  M-Any Premium DAH-610 MP3/WMA Player
+	0332  mobiBLU DAH-1200 MP3/Ogg Player
+0f9e  Lucent Technologies
+0fa3  Starconn Electronic Co., Ltd
+0fa4  ATL Technology
+0fa5  Sotec Co., Ltd
+0fa7  Epox Computer Co., Ltd
+0fa8  Logic Controls, Inc.
+0faf  Winpoint Electronic Corp.
+0fb0  Haurtian Wire & Cable Co., Ltd
+0fb1  Inclose Design, Inc.
+0fb2  Juan-Chern Industrial Co., Ltd
+0fb8  Wistron Corp.
+0fb9  AACom Corp.
+0fba  San Shing Electronics Co., Ltd
+0fbb  Bitwise Systems, Inc.
+0fc1  Mitac Internatinal Corp.
+0fc2  Plug and Jack Industrial, Inc.
+0fc5  Delcom Engineering
+	1222  I/O Development Board
+0fc6  Dataplus Supplies, Inc.
+0fca  Research In Motion, Ltd.
+	0001  Blackberry Handheld
+0fce  Sony Ericsson Mobile Communications AB
+	d017  K608i Phone
+0fcf  Dynastream Innovations, Inc.
+0fd0  Tulip Computers B.V.
+0fd4  Tenovis GmbH & Co., KG
+0fd5  Direct Access Technology, Inc.
+0fdc  Micro Plus
+0fe4  IN-Tech Electronics, Ltd
+0fe5  Greenconn (U.S.A.), Inc.
+0fe9  DVICO
+	db00  FusionHDTV DVB-T (MT352+LgZ201) (uninitialized)
+	db01  FusionHDTV DVB-T (MT352+LgZ201) (initialized)
+	db10  FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized)
+	db11  FusionHDTV DVB-T (MT352+Thomson7579) (initialized)
+0fea  United Computer Accessories
+0feb  CRS Electronic Co., Ltd
+0fec  UMC Electronics Co., Ltd
+0fed  Access Co., Ltd
+0fee  Xsido Corp.
+0fef  MJ Research, Inc.
+0ff6  Core Valley Co., Ltd
+0ff7  CHI SHING Computer Accessories Co., Ltd
+0fff  Aopen, Inc.
+1000  Speed Tech Corp.
+1001  Ritronics Components (S) Pte., Ltd
+1003  Sigma Corp.
+1004  LG Electronics, Inc.
+	1fae  U8120 3G Cellphone
+	6000  VX4400/VX6000 Cellphone
+	6800  CDMA Modem
+1005  Apacer Technology, Inc.
+	b113  Handy Steno 2.0 (256MB)
+1006  iRiver, Ltd.
+	3002  iHP-100/120/140 MP3 Player
+1009  Emuzed, Inc.
+100a  AV Chaseway, Ltd
+100b  Chou Chin Industrial Co., Ltd
+100d  Netopia, Inc.
+	3342  Cayman 3352 DSL Modem
+	cb01  Cayman 3341 Ethernet DSL Router
+1010  Fukuda Denshi Co., Ltd
+1011  Mobile Media Tech.
+1012  SDKM Fibres, Wires & Cables Berhad
+1013  TST-Touchless Sensor Technology AG
+1014  Densitron Technologies PLC
+1015  Softronics Pty., Ltd
+1016  Xiamen Hung's Enterprise Co., Ltd
+1017  Speedy Industrial Supplies, Pte., Ltd
+1020  Labtec
+	000a Wireless Optical Mouse
+1022  Shinko Shoji Co., Ltd
+1025  Hyper-Paltek
+	005e  USB DVB-T device
+	005f  USB DVB-T device
+1026  Newly Corp.
+1027  Time Domain
+1028  Inovys Corp.
+1029  Atlantic Coast Telesys
+102a  Ramos Technology Co., Ltd
+102b  Infotronic America, Inc.
+102c  Etoms Electronics Corp.
+102d  Winic Corp.
+1031  Comax Technology, Inc.
+1032  C-One Technology Corp.
+1033  Nucam Corp.
+1038  Ideazon, Inc.
+	0100  Zboard
+1043  iCreate Technologies Corp.
+	8006  Flash Disk 32 MB
+1044  Chu Yuen Enterprise Co., Ltd
+1046  Winbond Electronics Corp. [hex]
+	9967  W9967CF/W9968CF WebCam IC
+104c  AMCO TEC International, Inc.
+1053  Immanuel Electronics Co., Ltd
+1054  BMS International Beheer N.V.
+1055  Complex Micro Interconnection Co., Ltd
+1056  Hsin Chen Ent Co., Ltd
+1057  ON Semiconductor
+1058  Western Digital Technologies, Inc.
+1059  Giesecke & Devrient GmbH
+105c  Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd
+105d  Delkin Devices, Inc.
+105e  Valence Semiconductor Design, Ltd
+105f  Chin Shong Enterprise Co., Ltd
+1060  Easthome Industrial Co., Ltd
+1063  Motorola Electronics Taiwan, Ltd [hex]
+	1555  MC141555 Hub
+1065  CCYU Technology
+	2136  EasyDisk ED1064
+106a  Loyal Legend, Ltd
+106c  Curitel Communications, Inc.
+	2101  AudioVox 8900 Cell Phone
+106d  San Chieh Manufacturing, Ltd
+106e  ConectL
+106f  Money Controls
+1076  GCT Semiconductor, Inc.
+107d  Arlec Australia, Ltd
+107e  Midoriya Electric Co., Ltd
+107f  KidzMouse, Inc.
+1082  Shin-Etsukaken Co., Ltd
+1083  Canon Electronics, Inc.
+1084  Pantech Co., Ltd
+108a  Chloride Power Protection
+108b  Grand-tek Technology Co., Ltd
+108c  Robert Bosch GmbH
+1099  Surface Optics Corp.
+109a  DATASOFT Systems GmbH
+109f  eSOL Co., Ltd
+10a0  Hirotech, Inc.
+10a3  Mitsubishi Materials Corp.
+10a9  SK Teletech Co., Ltd
+10aa  Cables To Go
+10ab  USI Co., Ltd
+	10c5  Sony-Ericsson / Samsung DataCable
+10ac  Honeywell, Inc.
+10ae  Princeton Technology Corp.
+10b5  Comodo (PLX?)
+	9060  Test Board
+10b8  DiBcom
+	0bb8  DiBcom USB DVB-T reference design (MOD300) (cold)
+	0bb9  DiBcom USB DVB-T reference design (MOD300) (warm)
+	0bc6  DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+	0bc7  DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+10bb  TM Technology, Inc.
+10bc  Dinging Technology Co., Ltd
+10bd  TMT Technology, Inc.
+10bf  SmartHome
+	0001  SmartHome PowerLinc
+10c4  Cygnal Integrated Products, Inc.
+10c5  Sanei Electric, Inc.
+10c6  Intec, Inc.
+10cb  Eratech
+10cc  GBM Connector Co., Ltd
+10cd  Kycon, Inc.
+10cf  Velleman Components, Inc.
+	5500 8055 Experiment Interface Board (address=0)
+	5501 8055 Experiment Interface Board (address=1)
+	5502 8055 Experiment Interface Board (address=2)
+	5503 8055 Experiment Interface Board (address=3)
+10d1  Hottinger Baldwin Measurement
+	0101 USB-Module for Spider8, CP32
+	0202 CP22 - Communication Processor
+	0301 CP42 - Communication Processor
+10d4  Man Boon Manufactory, Ltd
+10d5  Uni Class Technology Co., Ltd
+10d6  Actions Semiconductor Co., Ltd
+	1000  MP3 Player
+	1100  MPMan MP-Ki 128 MP3 Player/Recorder
+10de  Authenex, Inc.
+10df  In-Win Development, Inc.
+10e0  Post-Op Video, Inc.
+10e1  CablePlus, Ltd
+10e2  Nada Electronics, Ltd
+10ec  Vast Technologies, Inc.
+10fb  Pictos Technologies, Inc.
+10fd  Anubis Electronics, Ltd
+	804d  Typhoon Webshot II Webcam [zc0301]
+1a0a  ...
+	badd  USB OTG Compliance test device
+1100  VirTouch, Ltd
+	0001  VTPlayer VTP-1 Braille Mouse
+1101  EasyPass Industrial Co., Ltd
+	0001  FSK Electronics Super GSM Reader
+1108  Brightcom Technologies, Ltd
+1110  Analog Devices Canada, Ltd (Allied Telesyn)
+	900f  AT-AR215 DSL Modem
+1112  YM ELECTRIC CO., Ltd
+1113  Medion AG
+111e  VSO Electric Co., Ltd
+112e  Master Hill Electric Wire and Cable Co., Ltd
+112f  Cellon International, Inc.
+1130  Tenx Technology, Inc.
+1131  Integrated System Solution Corp.
+	1001  KY-BT100 Bluetooth Adapter
+1132  Toshiba Corp., Digital Media Equipment [hex]
+	4331  PDR-M4/M5/M70 Digital Camera
+	4332  PDR-M60 Digital Camera
+113c  Arin Tech Co., Ltd
+113d  Mapower Electronics Co., Ltd
+1141  V One Multimedia, Pte., Ltd
+1142  CyberScan Technologies, Inc.
+1147  Ever Great Electric Wire and Cable Co., Ltd
+114c  Tinius Olsen Testing Machine Co., Inc.
+114d  Alpha Imaging Technology Corp.
+1162  Secugen Corp.
+1163  DeLorme Publishing, Inc.
+1164  YUAN High-Tech Development Co., Ltd
+1165  Telson Electronics Co., Ltd
+1166  Bantam Interactive Technologies
+1167  Salient Systems Corp.
+1168  BizConn International Corp.
+116e  Gigastorage Corp.
+116f  Silicon 10 Technology Corp.
+1175  Shengyih Steel Mold Co., Ltd
+117d  Santa Electronic, Inc.
+117e  JNC, Inc.
+1182  Venture Corp., Ltd
+1183  Compaq Computer Corp. [hex] (Digital Dream ??)
+	19c7  ISDN TA
+	4008  56k FaxModem
+	504a  PJB-100 Personal Jukebox
+1184  Kyocera Elco Corp.
+118f  You Yang Technology Co., Ltd
+1190  Tripace
+1191  Loyalty Founder Enterprise Co., Ltd
+1196  Yankee Robotics, LLC
+	0010 Trifid Camera without code
+	0011 Trifid Camera
+1197  Technoimagia Co., Ltd
+1198  StarShine Technology Corp.
+1199  Sierra Wireless, Inc.
+	0112  CDMA 1xEVDO PC Card, AirCard 580
+119a  ZHAN QI Technology Co., Ltd
+119b  ruwido austria GmbH
+	0400  Infrared Keyboard V2.01
+11a0  Chipcon AS
+	eb11 CC2400EB 2.0 ZigBee Sniffer
+11a3  Technovas Co., Ltd
+11aa  GlobalMedia Group, LLC
+11ab  Exito Electronics Co., Ltd
+11db  Topfield Co., Ltd.
+	1000  PVR
+	1100  PVR
+11f5  Siemens AG (?)
+	0003  Mobile phone USB cable
+11f7  Alcatel (?)
+	02df  TD10 Mobile phone USB cable
+1209  InterBiometrics
+	1001  USB Hub
+	1002  USB Relais
+	1003  IBSecureCam-P
+	1004  IBSecureCam-O
+	1005  IBSecureCam-N
+120e  Hudson Soft Co., Ltd
+121e  Jungsoft Co., Ltd
+	3403  Muzio JM250 Audio Player
+1241  Belkin
+	1111  Mouse
+	1177  F8E842-DL Mouse
+124a  AirVast
+	4017  PC-Chips 802.11b Adapter
+124b  Nyko (Honey Bee)
+	4d01  Airflo EX Joystick
+1267  Logic3 / SpectraVideo plc
+	0201  A4Tech SWOP-3 Mouse
+	a001  JP260 PC Game Pad
+126e  Strobe Data, Inc.
+126f  TwinMOS
+	1325  Mobile Disk
+	2168  Mobile Disk III
+1275  Xaxero Marine Software Engineering, Ltd.
+	0002  WeatherFax 2000 Demodulator
+	0080  SkyEye Weather Satellite Receiver
+1292  Innomedia
+	0258  Creative Labs VoIP Blaster
+1293  Belkin Components [hex]
+	0002  F5U002 Parallel Port [uss720]
+	2101  104-key keyboard
+12fd  AIN Comm. Technology Co., Ltd
+	1001  AWU2000b 802.11b Stick
+1310  Roper
+	0001  Class 1 Bluetooth Dongle
+1312  ICS Electronics
+131d  Natural Point
+	0155  TrackIR 3 Pro Head Tracker
+132b  Konica Minolta
+	0000  Dimage A2 Camera
+	0003  Dimage Xg Camera
+	0006  Dimage Z2 Camera
+	0008  Dimage X21 Camera
+	000b  Dimage Z10 Camera
+	000d  Dimage X50 Camera [storage?]
+	000f  Dimage X50 Camera [p2p?]
+	0010  Dimage G600 Camera
+	0012  Dimage Scan Elite5400 2
+	0013  Dimage X31 Camera
+	0015  Dimage G530 Camera
+	0017  Dimage Z3 Camera
+	0019  Dimage A200 Camera
+	0021  Dimage Z5 Camera
+1342  Mobility
+	0200  EasiDock 200 Hub
+	0201  EasiDock 200 Keyboard and Mouse Port
+	0202  EasiDock 200 Serial Port
+	0203  EasiDock 200 Printer Port
+134e  Digby's Bitpile, Inc. DBA D Bit
+1370  Swissbit
+	6828  Victorinox Flash Drive
+1398  Q-tec
+	2103  USB 2.0 Storage Device
+13b0  Alesis
+	000a  Photon X25 MIDI Controller
+13b1  Linksys
+	000b  WUSB11 v4.0 802.11b Adapter
+	0011  WUSB54GP v4.0 802.11g Adapter
+	0018  USB200M 10/100 Ethernet Adapter
+13d2  Shark Multimedia
+	0400  Pocket Ethernet [klsi]
+13d3  IMC Networks
+	3201  VisionDTV USB-Ter/HAMA USB DVB-T device cold
+	3202  VisionDTV USB-Ter/HAMA USB DVB-T device warm
+1453  Radio Shack
+	4026  26-183 Serial Cable
+1462  Micro Star International
+	5512  MegaStick-1 Flash Stick
+147a  Formosa Industrial Computing, Inc.
+1484  Elsa AG [hex]
+	1746  Ecomo 19H99 Monitor
+	7616  Elsa Hub
+148f  Ralink Technology, Corp.
+	2570  802.11g WiFi
+14aa  AVerMedia (again) or C&E
+	0001  Avermedia AverTV DVBT USB1.1 (cold)
+	0002  Avermedia AverTV DVBT USB1.1 (warm)
+	0201  AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold)
+	0221  AVermedia DVBT Tuner Dongle
+	0301  AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm)
+14c2  Gemlight Computer, Ltd
+1518  Cheshire Engineering Corp.
+	0001  HDReye High Dynamic Range Camera
+	0002  HDReye (before firmware loads)
+1520  Bitwire Corp.
+152e  LG (HLDS)
+	e001  GSA-5120D DVD-RW
+1546  U-Blox AG
+1554  Prolink Microsystems Corp.
+1568  Sunf Pu Technology Co., Ltd
+15c2  SoundGraph Inc.
+	ffdc  iMON PAD Remote Controller
+15c6  Laboratoires MXM
+15e8  SohoWare
+	9100  NUB100 Ethernet [pegasus]
+15e9  Pacific Digital Corp.
+15f4  HanfTek
+	0001  HanfTek UMT-010 USB2.0 DVB-T (cold)
+	0025  HanfTek UMT-010 USB2.0 DVB-T (warm)
+1604  Tascam
+	8000  US-428 Audio/Midi Controller (without fw)
+	8001  US-428 Audio/Midi Controller
+	8004  US-224 Audio/Midi Controller (without fw)
+	8005  US-224 Audio/Midi Controller
+	8006  US-122 Audio/Midi Interface (without fw)
+	8007  US-122 Audio/Midi Interface
+1606  Umax [hex]
+	0010  Astra 1220U
+	0030  Astra 2000U
+	0060  Astra 3400U
+	0130  Astra 2100U
+	0160  Astra 5400U
+	0230  Astra 2200/2200SU
+	2020  AstraCam 1000
+1608  Inside Out Networks [hex]
+	0001  EdgePort/4 Serial Port
+	1403  MultiTech Systems MT4X56 Modem
+1645  Entrega [hex]
+	0001  1S Serial Port
+	0002  2S Serial Port
+	0003  1S25 Serial Port
+	0004  4S Serial Port
+	0005  E45 Ethernet [klsi]
+	0006  Parallel Port
+	0007  U1-SC25 SCSI
+	0093  1S9 Serial Port
+	8000  EZ-USB
+	8002  2x Serial Port
+	8093  PortGear Serial Port
+1657  Struck Innovative Systeme GmbH
+	3150  SIS3150 USB2.0 to VME interface
+1668  Actiontec Electronics, Inc. [hex]
+	0333  Modem
+	0408  Prism2.5 802.11b Adapter
+	0421  Prism2.5 802.11b Adapter
+	0500  BTM200B BlueTooth Adapter
+1690  Askey Computer Corp. [hex]
+	0101  Creative Modem Blaster DE5670
+	0103  Askey 1456 VQE-R3 Modem [conexant]
+	0109  Askey MagicXpress V.90 Pocket Modem [conexant]
+1696  Hitachi Video and Information System, Inc.
+1697  VTec Test, Inc.
+1706  BlueView Technologies, Inc.
+1733  Cellink Technology Co., Ltd
+	0101  RF Wireless Optical Mouse OP-701
+17b3  Grey Innovation
+	0004  Linux-USB Midi Gadget
+17eb  Cornice, Inc.
+1822  Twinhan
+	3201  VisionDTV USB-Ter/HAMA USB DVB-T device cold
+	3202  VisionDTV USB-Ter/HAMA USB DVB-T device warm
+185b  Compro
+	d000  Compro Videomate DVB-U2000 - DVB-T USB cold
+	d001  Compro Videomate DVB-U2000 - DVB-T USB warm
+1894  Topseed
+	5632  Atek Tote Remote
+	5641  TSAM-004 Presentation Remote
+1977  T-Logic
+	0111  TL203 MP3 Player and Voice Recorder
+1995  Trillium Technology Pty. Ltd.
+	3202  REC-ADPT-USB (recorder)
+	3203  REC-A-ADPT-USB (recorder)
+1ebb  NuCORE Technology, Inc.
+2001  D-Link Corp. [hex]
+	3200  DWL-120 802.11b (Atmel RFMD503A) [usbvnetr]
+	3700  DWL-122 802.11b
+	3701  DWL-G120 Spinnaker 802.11b
+	3703  DWL-122 802.11b
+	3704  DWL-G122 802.11g rev. A2
+	3c00  DWL-G122 802.11g rev. B1 [ralink]
+	4000  DSB-650C Ethernet [klsi]
+	4001  DSB-650TX Ethernet [pegasus]
+	4002  DSB-650TX Ethernet [pegasus]
+	4003  DSB-650TX-PNA Ethernet [pegasus]
+	abc1  DSB-650 Ethernet [pegasus]
+	f013  DLink 7 port USB2.0 Hub
+	f10d  Accent Communications Modem
+2040  Hauppauge
+	9300  Hauppauge WinTV NOVA-T USB2 (cold)
+	9301  Hauppauge WinTV NOVA-T USB2 (warm)
+2101  ActionStar
+	0201  SIIG 4-to-2 Printer Switch
+2162  Creative (?)
+	500c  DE5771 Modem Blaster
+2222  MacAlly
+	0004  iWebKey Keyboard
+22b8  Motorola PCS
+	0005  V.60c/V.60i GSM Phone
+	1005  T280e GSM/GPRS Phone
+	2821  T720 GSM Phone
+	2822  V.120e GSM Phone
+	3002  A835 GSM Phone
+	3802  C330/A780 GSM Phone
+	4002  A920/A925 UMTS Phone
+	4810  E398 Storage
+	4902  E398 GSM Phone
+	600c  A768i GSM Phone
+	604c  A780 GSM Phone (storage)
+	6631  CDC Modem
+	6604  Washington CDMA Phone
+22b9  eTurboTouch Technology, Inc.
+22ba  Technology Innovation Holdings, Ltd
+2304  Pinnacle Systems, Inc. [hex]
+	0109  Pinnacle Studio PCTV USB (SECAM)
+	0110  Pinnacle Studio PCTV USB (PAL)
+	0111  Miro PCTV USB
+	0112  Pinnacle Studio PCTV USB (NTSC) with FM radio
+	0208  Pinnacle Studio PCTV USB2
+	0210  Pinnacle Studio PCTV USB (PAL) with FM radio
+	0212  Pinnacle Studio PCTV USB (NTSC)
+	0214  Pinnacle Studio PCTV USB (PAL) with FM radio
+	0300  Pinnacle Studio Linx Video input cable (NTSC)
+	0301  Pinnacle Studio Linx Video input cable (PAL)
+	0419  Pinnacle PCTV Bungee USB (PAL) with FM radio
+2318  Shining Technologies, Inc. [hex]
+	0011  CitiDISK Jr. IDE Enclosure
+2375  Digit@lway, Inc.
+	0001  Digital Audio Player
+2406  SANHO Digital Electronics Co., Ltd.
+	6688  PD7X Portable Storage
+2632  TwinMOS
+	3209  7-in-1 Card Reader
+2650  Electronics For Imaging, Inc. [hex]
+2770  NHJ, Ltd
+	9120  Che-ez! Snap / iClick Tiny VGA Digital Camera
+2899  Toptronic Industrial Co., Ltd
+2fb2  Fujitsu, Ltd
+3125  Eagletron
+	0001  TrackerPod Camera Stand
+3176  Whanam Electronics Co., Ltd
+3340  Yakumo
+	0e3a  Pocket PC 300 GPS SL
+3504  Micro Star
+	f110  Security Key
+3538  Power Quotient International Co., Ltd
+	0001  Travel Flash
+	0042  Cool Drive U339 Flash Disk
+3579  DIVA
+	6901  Media Reader
+3636  InVibro
+3838  WEM
+	0001  5-in-1 Card Reader
+3923  National Instruments Corp.
+	703c  USB-485 RS485 Cable
+4102  iRiver, Ltd.
+	1001  iFP-100 series mp3 player
+	1003  iFP-300 series mp3 player
+	1005  iFP-500 series mp3 player
+	1007  iFP-700 series mp3/ogg vorbis player
+	1008  iFP-800 series mp3/ogg vorbis player
+	100A  iFP-1000 series mp3/ogg vorbis player
+	1101  iFP-100 series mp3 player (ums firmware)
+	1103  iFP-300 series mp3 player (ums firmware)
+	1105  iFP-500 series mp3 player (ums firmware)
+413c  Dell Computer Corp.
+	1002  Keyboard Hub
+	2002  SK-8125 Keyboard
+	2100  SK-3106 Keyboard
+	2101  SmartCard Reader Keyboard
+	2500  DRAC4 Remote Access Card
+	3010  Optical Wheel Mouse
+	4001  Axim X5
+	4002  Axim X3
+	4003  Axim X30
+	8100  TrueMobile 1180 802.11b Adapter
+	8103  Wireless 350 Bluetooth
+	a001  Hub
+	a700  Hub (in 1905FP LCD Monitor)
+4242  USB Design by Example
+	4201  Buttons and Lights HID device
+	4220  Echo 1 Camera
+4146  USBest Technology
+	9281  Iomega Micro Mini 128MB Flash Drive
+	ba01  Intuix Flash Drive
+4572  Shuttle, Inc.
+	4572  Shuttle PN31 Remote
+4586  Panram
+	1026  Crystal Bar Flash Drive
+4670  EMS Production
+	9394  Game Cube USB Memory Adaptor 64M
+5032  Grandtec
+	0bb8  Grandtec USB1.1 DVB-T (cold)
+	0bb9  Grandtec USB1.1 DVB-T (warm)
+	0fa0  Grandtec USB1.1 DVB-T (cold)
+	0fa1  Grandtec USB1.1 DVB-T (warm)
+5041  Linksys (?)
+	2234  WUSB54G 802.11g Adapter
+544d  Transmeta Corp.
+5543  UC-Logic Technology Corp.
+	0002  SuperPen WP3325U Tablet
+	0004  Genius MousePen 5x4 Tablet
+55aa  OnSpec Electronic, Inc.
+	1234  ATAPI Bridge
+	a103  Sandisk SDDR-55 SmartMedia Card Reader
+	b012  Mitsumi FA402M 8-in-2 Card Reader
+636c  CoreLogic, Inc.
+6666  Prototype product Vendor ID
+	0667  Smart Joy PSX, PS-PC Smart JoyPad
+6993  Freshtel
+	b001  FT-102 VoIP USB Phone
+6a75  Shanghai Jujo Electronics Co., Ltd
+8086  Intel Corp.
+	0110  Easy PC Camera
+	0431  Intel Pro Video PC Camera
+	0510  Digital Movie Creator
+	0630  Pocket PC Camera
+	07d3  BLOB boot loader firmware
+	1111  PRO/Wireless 2011B 802.11b Adapter
+	9890  82930 Test Board
+	c013  Wireless HID Station
+8341  EGO Systems, Inc.
+	2000  Flashdisk
+9710  MosChip Semiconductor
+	7705  Printer cable
+	7715  Printer cable
+c251  Keil Software, Inc.
+	2710  ULink
+eb1a  eMPIA Technology, Inc.
+	17de  KWorld V-Stream XPERT DTV - DVB-T USB cold
+	17df  KWorld V-Stream XPERT DTV - DVB-T USB warm
+	2710  SilverCrest WebCam
+	2800  Terratec Cinergy 200
+	2801  GrabBeeX+ Video Encoder
+
+# List of known device classes, subclasses and protocols
+
+# Syntax:
+# C class  class_name
+#	subclass  subclass_name			<-- single tab
+#		protocol  protocol_name		<-- two tabs
+
+C 00  (Defined at Interface level)
+C 01  Audio
+	01  Control Device
+	02  Streaming
+	03  MIDI Streaming
+C 02  Communications
+	01  Direct Line
+	02  Abstract (modem)
+		00  None
+		01  AT-commands (v.25ter)
+		02  AT-commands (PCCA101)
+		03  AT-commands (PCCA101 + wakeup)
+		04  AT-commands (GSM)
+		05  AT-commands (3G)
+		06  AT-commands (CDMA)
+		fe  Defined by command set descriptor
+		ff  Vendor Specific (MSFT RNDIS?)
+	03  Telephone
+	04  Multi-Channel
+	05  CAPI Control
+	06  Ethernet Networking
+	07  ATM Networking
+	08  Wireless Handset Control
+	09  Device Management
+	0a  Mobile Direct Line
+	0b  OBEX
+	0c  Ethernet Emulation
+		07  Ethernet Emulation (EEM)
+C 03  Human Interface Devices
+	00  No Subclass
+		00  None
+		01  Keyboard
+		02  Mouse
+	01  Boot Interface Subclass
+		00  None
+		01  Keyboard
+		02  Mouse
+C 06  Imaging
+	01  Still Image Capture
+		01 Picture Transfer Protocol (PIMA 15470)
+C 07  Printer
+	01  Printer
+		00  Reserved/Undefined
+		01  Unidirectional
+		02  Bidirectional
+		03  IEEE 1284.4 compatible bidirectional
+		ff  Vendor Specific
+C 08  Mass Storage
+	01  RBC (typically Flash)
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+	02  SFF-8020i, MMC-2 (ATAPI)
+	03  QIC-157
+	04  Floppy (UFI)
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+	05  SFF-8070i
+	06  SCSI
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+C 09  Hub
+	00  Unused
+		00  Full speed (or root) hub
+		01  Single TT
+		02  TT per port
+C 0a  CDC Data
+	00  Unused
+		30  I.430 ISDN BRI
+		31  HDLC
+		32  Transparent
+		50  Q.921M
+		51  Q.921
+		52  Q.921TM
+		90  V.42bis
+		91  Q.932 EuroISDN
+		92  V.120 V.24 rate ISDN
+		93  CAPI 2.0
+		fd  Host Based Driver
+		fe  CDC PUF
+		ff  Vendor specific
+C 0b  Chip/SmartCard
+C 0d  Content Security
+C 0e  Video
+	00  Undefined
+	01  Video Control
+	02  Video Streaming
+	03  Video Interface Collection
+C dc  Diagnostic
+	01  Reprogrammable Diagnostics
+		01  USB2 Compliance
+C e0  Wireless
+	01  Radio Frequency
+		01  Bluetooth
+		02  Ultra WideBand Radio Control
+		03  RNDIS
+	02  Wireless USB Wire Adapter
+		01  Host Wire Adapter Control/Data Streaming
+		02  Device Wire Adapter Control/Data Streaming
+		03  Device Wire Adapter Isochronous Streaming
+C ef  Miscellaneous Device
+	01  ?
+		01  Microsoft ActiveSync
+		02  Palm Sync
+	02  Common Class
+		01  Interface Association
+		02  Wire Adapter Multifunction Peripheral
+	03  ?
+		01  Cable Based Association
+C fe  Application Specific Interface
+	01  Device Firmware Update
+	02  IRDA Bridge
+	03  Test and Measurement
+		01  TMC
+		02  USB488
+C ff  Vendor Specific Class
+	ff  Vendor Specific Subclass
+		ff  Vendor Specific Protocol
+
+# List of Audio Class Terminal Types
+
+# Syntax:
+# AT terminal_type  terminal_type_name
+
+AT 0100  USB Undefined
+AT 0101  USB Streaming
+AT 01ff  USB Vendor Specific
+AT 0200  Input Undefined
+AT 0201  Microphone
+AT 0202  Desktop Microphone
+AT 0203  Personal Microphone
+AT 0204  Omni-directional Microphone
+AT 0205  Microphone Array
+AT 0206  Processing Microphone Array
+AT 0300  Output Undefined
+AT 0301  Speaker
+AT 0302  Headphones
+AT 0303  Head Mounted Display Audio
+AT 0304  Desktop Speaker
+AT 0305  Room Speaker
+AT 0306  Communication Speaker
+AT 0307  Low Frequency Effects Speaker
+AT 0400  Bidirectional Undefined
+AT 0401  Handset
+AT 0402  Headset
+AT 0403  Speakerphone, no echo reduction
+AT 0404  Echo-suppressing speakerphone
+AT 0405  Echo-canceling speakerphone
+AT 0500  Telephony Undefined
+AT 0501  Phone line
+AT 0502  Telephone
+AT 0503  Down Line Phone
+AT 0600  External Undefined
+AT 0601  Analog Connector
+AT 0602  Digital Audio Interface
+AT 0603  Line Connector
+AT 0604  Legacy Audio Connector
+AT 0605  SPDIF interface
+AT 0606  1394 DA stream
+AT 0607  1394 DV stream soundtrack
+AT 0700  Embedded Undefined
+AT 0701  Level Calibration Noise Source
+AT 0702  Equalization Noise
+AT 0703  CD Player
+AT 0704  DAT
+AT 0705  DCC
+AT 0706  MiniDisc
+AT 0707  Analog Tape
+AT 0708  Phonograph
+AT 0709  VCR Audio
+AT 070a  Video Disc Audio
+AT 070b  DVD Audio
+AT 070c  TV Tuner Audio
+AT 070d  Satellite Receiver Audio
+AT 070e  Cable Tuner Audio
+AT 070f  DSS Audio
+AT 0710  Radio Receiver
+AT 0711  Radio Transmitter
+AT 0712  Multitrack Recorder
+AT 0713  Synthesizer
+
+# List of HID Descriptor Types
+
+# Syntax:
+# HID descriptor_type  descriptor_type_name
+
+HID 21  HID
+HID 22  Report
+HID 23  Physical
+
+# List of HID Descriptor Item Types
+# Note: 2 bits LSB encode data length following
+
+# Syntax:
+# R item_type  item_type_name
+
+# Main Items
+R 80  Input
+R 90  Output
+R b0  Feature
+R a0  Collection
+R c0  End Collection
+
+# Global Items
+R 04  Usage Page
+R 14  Logical Minimum
+R 24  Logical Maximum
+R 34  Physical Minimum
+R 44  Physical Maximum
+R 54  Unit Exponent
+R 64  Unit
+R 74  Report Size
+R 84  Report ID
+R 94  Report Count
+R a4  Push
+R b4  Pop
+
+# Local Items
+R 08  Usage
+R 18  Usage Minimum
+R 28  Usage Maximum
+R 38  Designator Index
+R 48  Designator Minimum
+R 58  Designator Maximum
+R 78  String Index
+R 88  String Minimum
+R 98  String Maximum
+R a8  Delimiter
+
+# List of Physical Descriptor Bias Types
+
+# Syntax:
+# BIAS item_type  item_type_name
+
+BIAS 0  Not Applicable
+BIAS 1  Right Hand
+BIAS 2  Left Hand
+BIAS 3  Both Hands
+BIAS 4  Either Hand
+
+# List of Physical Descriptor Item Types
+
+# Syntax:
+# PHY item_type  item_type_name
+
+PHY 00  None
+PHY 01  Hand
+PHY 02  Eyeball
+PHY 03  Eyebrow
+PHY 04  Eyelid
+PHY 05  Ear
+PHY 06  Nose
+PHY 07  Mouth
+PHY 08  Upper Lip
+PHY 09  Lower Lip
+PHY 0a  Jaw
+PHY 0b  Neck
+PHY 0c  Upper Arm
+PHY 0d  Elbow
+PHY 0e  Forearm
+PHY 0f  Wrist
+PHY 10  Palm
+PHY 11  Thumb
+PHY 12  Index Finger
+PHY 13  Middle Finger
+PHY 14  Ring Finger
+PHY 15  Little Finger
+PHY 16  Head
+PHY 17  Shoulder
+PHY 18  Hip
+PHY 19  Waist
+PHY 1a  Thigh
+PHY 1b  Knee
+PHY 1c  calf
+PHY 1d  Ankle
+PHY 1e  Foot
+PHY 1f  Heel
+PHY 20  Ball of Foot
+PHY 21  Big Toe
+PHY 22  Second Toe
+PHY 23  Third Toe
+PHY 24  Fourth Toe
+PHY 25  Fifth Toe
+PHY 26  Brow
+PHY 27  Cheek
+
+# List of HID Usages
+
+# Syntax:
+# HUT hi  _usage_page  hid_usage_page_name
+#	hid_usage  hid_usage_name
+
+HUT 00  Undefined
+HUT 01  Generic Desktop Controls
+	000  Undefined
+	001  Pointer
+	002  Mouse
+	004  Joystick
+	005  Gamepad
+	006  Keyboard
+	007  Keypad
+	008  Multi-Axis Controller
+	030  Direction-X
+	031  Direction-Y
+	032  Direction-Z
+	033  Rotate-X
+	034  Rotate-Y
+	035  Rotate-Z
+	036  Slider
+	037  Dial
+	038  Wheel
+	039  Hat Switch
+	03a  Counted Buffer
+	03b  Byte Count
+	03c  Motion Wakeup
+	03d  Start
+	03e  Select
+	040  Vector-X
+	041  Vector-Y
+	042  Vector-Z
+	043  Vector-X relative Body
+	044  Vector-Y relative Body
+	045  Vector-Z relative Body
+	046  Vector
+	080  System Control
+	081  System Power Down
+	082  System Sleep
+	083  System Wake Up
+	084  System Context Menu
+	085  System Main Menu
+	086  System App Menu
+	087  System Menu Help
+	088  System Menu Exit
+	089  System Menu Select
+	08a  System Menu Right
+	08b  System Menu Left
+	08c  System Menu Up
+	08d  System Menu Down
+	090  Direction Pad Up
+	091  Direction Pad Down
+	092  Direction Pad Right
+	093  Direction Pad Left
+HUT 02  Simulation Controls
+	000  Undefined
+	001  Flight Simulation Device
+	002  Automobile Simulation Device
+	003  Tank Simulation Device
+	004  Spaceship Simulation Device
+	005  Submarine Simulation Device
+	006  Sailing Simulation Device
+	007  Motorcycle Simulation Device
+	008  Sports Simulation Device
+	009  Airplane Simualtion Device
+	00a  Helicopter Simulation Device
+	00b  Magic Carpet Simulation Device
+	00c  Bicycle Simulation Device
+	020  Flight Control Stick
+	021  Flight Stick
+	022  Cyclic Control
+	023  Cyclic Trim
+	024  Flight Yoke
+	025  Track Control
+	0b0  Aileron
+	0b1  Aileron Trim
+	0b2  Anti-Torque Control
+	0b3  Autopilot Enable
+	0b4  Chaff Release
+	0b5  Collective Control
+	0b6  Dive Break
+	0b7  Electronic Countermeasures
+	0b8  Elevator
+	0b9  Elevator Trim
+	0ba  Rudder
+	0bb  Throttle
+	0bc  Flight COmmunications
+	0bd  Flare Release
+	0be  Landing Gear
+	0bf  Toe Break
+	0c0  Trigger
+	0c1  Weapon Arm
+	0c2  Weapons Select
+	0c3  Wing Flaps
+	0c4  Accelerator
+	0c5  Brake
+	0c6  Clutch
+	0c7  Shifter
+	0c8  Steering
+	0c9  Turret Direction
+	0ca  Barrel Elevation
+	0cb  Drive Plane
+	0cc  Ballast
+	0cd  Bicylce Crank
+	0ce  Handle Bars
+	0cf  Front Brake
+	0d0  Rear Brake
+HUT 03  VR Controls
+	000  Unidentified
+	001  Belt
+	002  Body Suit
+	003  Flexor
+	004  Glove
+	005  Head Tracker
+	006  Head Mounted Display
+	007  Hand Tracker
+	008  Oculometer
+	009  Vest
+	00a  Animatronic Device
+	020  Stereo Enable
+	021  Display Enable
+HUT 04  Sport Controls
+	000  Unidentified
+	001  Baseball Bat
+	002  Golf Club
+	003  Rowing Machine
+	004  Treadmill
+	030  Oar
+	031  Slope
+	032  Rate
+	033  Stick Speed
+	034  Stick Face Angle
+	035  Stick Heel/Toe
+	036  Stick Follow Through
+	047  Stick Temp
+	038  Stick Type
+	039  Stick Height
+	050  Putter
+	051  1 Iron
+	052  2 Iron
+	053  3 Iron
+	054  4 Iron
+	055  5 Iron
+	056  6 Iron
+	057  7 Iron
+	058  8 Iron
+	059  9 Iron
+	05a  10 Iron
+	05b  11 Iron
+	05c  Sand Wedge
+	05d  Loft Wedge
+	05e  Power Wedge
+	05f  1 Wood
+	060  3 Wood
+	061  5 Wood
+	062  7 Wood
+	063  9 Wood
+HUT 05  Game Controls
+	000  Undefined
+	001  3D Game Controller
+	002  Pinball Device
+	003  Gun Device
+	020  Point Of View
+	021  Turn Right/Left
+	022  Pitch Right/Left
+	023  Roll Forward/Backward
+	024  Move Right/Left
+	025  Move Forward/Backward
+	026  Move Up/Down
+	027  Lean Right/Left
+	028  Lean Forward/Backward
+	029  Height of POV
+	02a  Flipper
+	02b  Secondary Flipper
+	02c  Bump
+	02d  New Game
+	02e  Shoot Ball
+	02f  Player
+	030  Gun Bolt
+	031  Gun Clip
+	032  Gun Selector
+	033  Gun Single Shot
+	034  Gun Burst
+	035  Gun Automatic
+	036  Gun Safety
+	037  Gamepad Fire/Jump
+	038  Gamepad Fun
+	039  Gamepad Trigger
+HUT 07  Keyboard
+	000  No Event
+	001  Keyboard ErrorRollOver
+	002  Keyboard POSTfail
+	003  Keyboard Error Undefined
+	004  A
+	005  B
+	006  C
+	007  D
+	008  E
+	009  F
+	00a  G
+	00b  H
+	00c  I
+	00d  J
+	00e  K
+	00f  L
+	010  M
+	011  N
+	012  O
+	013  P
+	014  Q
+	015  R
+	016  S
+	017  T
+	018  U
+	019  V
+	01a  W
+	01b  X
+	01c  Y
+	01d  Z
+	01e  1 and ! (One and Exclamation)
+	01f  2 and @ (2 and at)
+	020  3 and # (3 and Hash)
+	021  4 and $ (4 and Dollar Sign)
+	022  5 and % (5 and Percent Sign)
+	023  6 and ^ (6 and circumflex)
+	024  7 and & (Seven and Ampersand)
+	025  8 and * (Eight and asterisk)
+	026  9 and ( (Nine and Parenthesis Left)
+	027  0 and ) (Zero and Parenthesis Right)
+	028  Return (Enter)
+	029  Escape
+	02a  Delete (Backspace)
+	02b  Tab
+	02c  Space Bar
+	02d  - and _ (Minus and underscore)
+	02e  = and + (Equal and Plus)
+	02f  [ and { (Bracket and Braces Left)
+	030  ] and } (Bracket and Braces Right)
+	031  \ and | (Backslash and Bar)
+	032  # and ~ (Hash and Tilde, Non-US Keyboard near right shift)
+	033  ; and : (Semicolon and Colon)
+	034  ´ and " (Accent Acute and Double Quotes)
+	035  ` and ~ (Accent Grace and Tilde)
+	036  , and < (Comma and Less)
+	037  . and > (Period and Greater)
+	038  / and ? (Slash and Question Mark)
+	039  Caps Lock
+	03a  F1
+	03b  F2
+	03c  F3
+	03d  F4
+	03e  F5
+	03f  F6
+	040  F7
+	041  F8
+	042  F9
+	043  F10
+	044  F11
+	045  F12
+	046  Print Screen
+	047  Scroll Lock
+	048  Pause
+	049  Insert
+	04a  Home
+	04b  Page Up
+	04c  Delete Forward (without Changing Position)
+	04d  End
+	04e  Page Down
+	04f  Right Arrow
+	050  Left Arrow
+	051  Down Arrow
+	052  Up Arrow
+	053  Num Lock and Clear
+	054  Keypad / (Division Sign)
+	055  Keypad * (Multiplication Sign)
+	056  Keypad - (Subtraction Sign)
+	057  Keypad + (Addition Sign)
+	058  Keypad Enter
+	059  Keypad 1 and END
+	05a  Keypad 2 and Down Arrow
+	05b  Keypad 3 and Page Down
+	05c  Keypad 4 and Left Arrow
+	05d  Keypad 5 (Tactilei Raised)
+	05f  Keypad 6 and Right Arrow
+	060  Keypad 7 and Home
+	061  Keypad 8 and Up Arrow
+	062  Keypad 8 and Page Up
+	063  Keypad . (decimal delimiter) and Delete
+	064  \ and | (Backslash and Bar, UK and Non-US Keyboard near left shift)
+	065  Keyboard Application (Windows Key for Win95 or Compose)
+	066  Power (not a key)
+	067  Keypad = (Equal Sign)
+	068  F13
+	069  F14
+	06a  F15
+	06b  F16
+	06c  F17
+	06d  F18
+	06e  F19
+	06f  F20
+	070  F21
+	071  F22
+	072  F23
+	073  F24
+	074  Execute
+	075  Help
+	076  Menu
+	077  Select
+	078  Stop
+	079  Again
+	07a  Undo
+	07b  Cut
+	07c  Copy
+	07d  Paste
+	07e  Find
+	07f  Mute
+	080  Volume Up
+	081  Volume Down
+	082  Locking Caps Lock
+	083  Locking Num Lock
+	084  Locking Scroll Lock
+	085  Keypad Comma
+	086  Keypad Equal Sign (AS/400)
+	087  International 1 (PC98)
+	088  International 2 (PC98)
+	089  International 3 (PC98)
+	08a  International 4 (PC98)
+	08b  International 5 (PC98)
+	08c  International 6 (PC98)
+	08d  International 7 (Toggle Single/Double Byte Mode)
+	08e  International 8
+	08f  International 9
+	090  LANG 1 (Hangul/English Toggle, Korea)
+	091  LANG 2 (Hanja Conversion, Korea)
+	092  LANG 3 (Katakana, Japan)
+	093  LANG 4 (Hiragana, Japan)
+	094  LANG 5 (Zenkaku/Hankaku, Japan)
+	095  LANG 6
+	096  LANG 7
+	097  LANG 8
+	098  LANG 9
+	099  Alternate Erase
+	09a  SysReq/Attention
+	09b  Cancel
+	09c  Clear
+	09d  Prior
+	09e  Return
+	09f  Separator
+	0a0  Out
+	0a1  Open
+	0a2  Clear/Again
+	0a3  CrSel/Props
+	0a4  ExSel
+	0e0  Control Left
+	0e1  Shift Left
+	0e2  Alt Left
+	0e3  GUI Left
+	0e4  Control Right
+	0e5  Shift Right
+	0e6  Alt Rigth
+	0e7  GUI Right
+HUT 08  LEDs
+	000  Undefined
+	001  NumLock
+	002  CapsLock
+	003  Scroll Lock
+	004  Compose
+	005  Kana
+	006  Power
+	007  Shift
+	008  Do not disturb
+	009  Mute
+	00a  Tone Enabke
+	00b  High Cut Filter
+	00c  Low Cut Filter
+	00d  Equalizer Enable
+	00e  Sound Field ON
+	00f  Surround On
+	010  Repeat
+	011  Stereo
+	012  Sampling Rate Detect
+	013  Spinning
+	014  CAV
+	015  CLV
+	016  Recording Format Detect
+	017  Off-Hook
+	018  Ring
+	019  Message Waiting
+	01a  Data Mode
+	01b  Battery Operation
+	01c  Battery OK
+	01d  Battery Low
+	01e  Speaker
+	01f  Head Set
+	020  Hold
+	021  Microphone
+	022  Coverage
+	023  Night Mode
+	024  Send Calls
+	025  Call Pickup
+	026  Conference
+	027  Stand-by
+	028  Camera On
+	029  Camera Off
+	02a  On-Line
+	02b  Off-Line
+	02c  Busy
+	02d  Ready
+	02e  Paper-Out
+	02f  Paper-Jam
+	030  Remote
+	031  Forward
+	032  Reverse
+	033  Stop
+	034  Rewind
+	035  Fast Forward
+	036  Play
+	037  Pause
+	038  Record
+	039  Error
+	03a  Usage Selected Indicator
+	03b  Usage In Use Indicator
+	03c  Usage Multi Indicator
+	03d  Indicator On
+	03e  Indicator Flash
+	03f  Indicator Slow Blink
+	040  Indicator Fast Blink
+	041  Indicator Off
+	042  Flash On Time
+	043  Slow Blink On Time
+	044  Slow Blink Off Time
+	045  Fast Blink On Time
+	046  Fast Blink Off Time
+	047  Usage Color Indicator
+	048  Indicator Red
+	049  Indicator Green
+	04a  Indicator Amber
+	04b  Generic Indicator
+	04c  System Suspend
+	04d  External Power Connected
+HUT 09  Buttons
+	000  No Button Pressed
+	001  Button 1 (Primary)
+	002  Button 2 (Secondary)
+	003  Button 3 (Tertiary)
+	004  Button 4
+	005  Button 5
+HUT 0a  Ordinal
+	001  Instance 1
+	002  Instance 2
+	003  Instance 3
+HUT 0b  Telephony
+	000  Unassigned
+	001  Phone
+	002  Answering Machine
+	003  Message Controls
+	004  Handset
+	005  Headset
+	006  Telephony Key Pad
+	007  Programmable Button
+	020  Hook Switch
+	021  Flash
+	022  Feature
+	023  Hold
+	024  Redial
+	025  Transfer
+	026  Drop
+	027  Park
+	028  Forward Calls
+	029  Alternate Function
+	02a  Line
+	02b  Speaker Phone
+	02c  Conference
+	02d  Ring Enable
+	02e  Ring Select
+	02f  Phone Mute
+	030  Caller ID
+	050  Speed Dial
+	051  Store Number
+	052  Recall Number
+	053  Phone Directory
+	070  Voice Mail
+	071  Screen Calls
+	072  Do Not Disturb
+	073  Message
+	074  Answer On/Offf
+	090  Inside Dial Tone
+	091  Outside Dial Tone
+	092  Inside Ring Tone
+	093  Outside Ring Tone
+	094  Priority Ring Tone
+	095  Inside Ringback
+	096  Priority Ringback
+	097  Line Busy Tone
+	098  Recorder Tone
+	099  Call Waiting Tone
+	09a  Confirmation Tone 1
+	09b  Confirmation Tone 2
+	09c  Tones Off
+	09d  Outside Ringback
+	0b0  Key 1
+	0b1  Key 2
+	0b3  Key 3
+	0b4  Key 4
+	0b5  Key 5
+	0b6  Key 6
+	0b7  Key 7
+	0b8  Key 8
+	0b9  Key 9
+	0ba  Key Star
+	0bb  Key Pound
+	0bc  Key A
+	0bd  Key B
+	0be  Key C
+	0bf  Key D
+HUT 0c  Consumer
+	000  Unassigned
+	001  Consumer Control
+	002  Numeric Ky Pad
+	003  Programmable Buttons
+	020  +10
+	021  +100
+	022  AM/PM
+	030  Power
+	031  Reset
+	032  Sleep
+	033  Sleep After
+	034  Sleep Mode
+	035  Illumination
+	036  Funtion Buttons
+	040  Menu
+	041  Menu Pick
+	042  Menu Up
+	043  Menu Down
+	044  Menu Left
+	045  Menu Right
+	046  Menu Escape
+	047  Menu Value Increase
+	048  Menu Value Decrease
+	060  Data on Screen
+	061  Closed Caption
+	062  Closed Caption Select
+	063  VCR/TV
+	064  Broadcast Mode
+	065  SNapshot
+	066  Still
+	080  Selection
+	081  Assign Selection
+	082  Mode Step
+	083  Recall Last
+	084  Enter Channel
+	085  Order Movie
+	086  Channel
+	087  Media Selection
+	088  Media Select Computer
+	089  Media Select TV
+	08a  Media Select WWW
+	08b  Media Select DVD
+	08c  Media Select Telephone
+	08d  Media Select Program Guide
+	08e  Media Select Video Phone
+	08f  Media Select Games
+	090  Media Select Messages
+	091  Media Select CD
+	092  Media Select VCR
+	093  Media Select Tuner
+	094  Quit
+	095  Help
+	096  Media Select Tape
+	097  Media Select Cable
+	098  Media Select Satellite
+	099  Media Select Security
+	09a  Media Select Home
+	09b  Media Select Call
+	09c  Channel Increment
+	09d  Channel Decrement
+	09e  Media Select SAP
+	0a0  VCR Plus
+	0a1  Once
+	0a2  Daily
+	0a3  Weekly
+	0a4  Monthly
+	0b0  Play
+	0b1  Pause
+	0b2  Record
+	0b3  Fast Forward
+	0b4  Rewind
+	0b5  Scan Next Track
+	0b6  Scan Previous Track
+	0b7  Stop
+	0b8  Eject
+	0b9  Random Play
+	0ba  Select Disc
+	0bb  Enter Disc
+	0bc  Repeat
+	0bd  Tracking
+	0be  Track Normal
+	0bf  Slow Tracking
+	0c0  Frame Forward
+	0c1  Frame Back
+	0c2  Mark
+	0c3  Clear Mark
+	0c4  Repeat from Mark
+	0c5  Return to Mark
+	0c6  Search Mark Forward
+	0c7  Search Mark Backward
+	0c8  Counter Reset
+	0c9  Show Counter
+	0ca  Tracking Increment
+	0cb  Tracking Decrement
+	0cc  Stop/Eject
+	0cd  Play/Pause
+	0ce  Play/Skip
+	0e0  Volume
+	0e1  Balance
+	0e2  Mute
+	0e3  Bass
+	0e4  Treble
+	0e5  Bass Boost
+	0e6  Surround Mode
+	0e7  Loudness
+	0e8  MPX
+	0e9  Volume Increment
+	0ea  Volume Decrement
+	0f0  Speed Select
+	0f1  Playback Speed
+	0f2  Standard Play
+	0f3  Long Play
+	0f4  Extended Play
+	0f5  Slow
+	100  Fan Enable
+	101  Fan Speed
+	102  Light Enable
+	103  Light Illumination Level
+	104  Climate Control Enable
+	105  Room Temperature
+	106  Security Enable
+	107  Fire Alarm
+	108  Police Alarm
+	150  Balance Right
+	151  Balance Left
+	152  Bass Increment
+	153  Bass Decrement
+	154  Treble Increment
+	155  Treble Decrement
+	160  Speaker System
+	161  Channel Left
+	162  Channel Right
+	163  Channel Center
+	164  Channel Front
+	165  Channel Center Front
+	166  Channel Side
+	167  Channel Surround
+	168  Channel Low Frequency Enhancement
+	169  Channel Top
+	16a  Channel Unknown
+	170  Sub-Channel
+	171  Sub-Channel Increment
+	172  Sub-Channel Decrement
+	173  Alternative Audio Increment
+	174  Alternative Audio Decrement
+	180  Application Launch Buttons
+	181  AL Launch Button Configuration Tool
+	182  AL Launch Button Configuration
+	183  AL Consumer Control Configuration
+	184  AL Word Processor
+	185  AL Text Editor
+	186  AL Spreadsheet
+	187  AL Graphics Editor
+	188  AL Presentation App
+	189  AL Database App
+	18a  AL Email Reader
+	18b  AL Newsreader
+	18c  AL Voicemail
+	18d  AL Contacts/Address Book
+	18e  AL Calendar/Schedule
+	18f  AL Task/Project Manager
+	190  AL Log/Jounal/Timecard
+	191  AL Checkbook/Finance
+	192  AL Calculator
+	193  AL A/V Capture/Playback
+	194  AL Local Machine Browser
+	195  AL LAN/Wan Browser
+	196  AL Internet Browser
+	197  AL Remote Networking/ISP Connect
+	198  AL Network Conference
+	199  AL Network Chat
+	19a  AL Telephony/Dialer
+	19b  AL Logon
+	19c  AL Logoff
+	19d  AL Logon/Logoff
+	19e  AL Terminal Local/Screensaver
+	19f  AL Control Panel
+	1a0  AL Command Line Processor/Run
+	1a1  AL Process/Task Manager
+	1a2  AL Select Task/Application
+	1a3  AL Next Task/Application
+	1a4  AL Previous Task/Application
+	1a5  AL Preemptive Halt Task/Application
+	200  Generic GUI Application Controls
+	201  AC New
+	202  AC Open
+	203  AC CLose
+	204  AC Exit
+	205  AC Maximize
+	206  AC Minimize
+	207  AC Save
+	208  AC Print
+	209  AC Properties
+	21a  AC Undo
+	21b  AC Copy
+	21c  AC Cut
+	21d  AC Paste
+	21e  AC Select All
+	21f  AC Find
+	220  AC Find and Replace
+	221  AC Search
+	222  AC Go To
+	223  AC Home
+	224  AC Back
+	225  AC Forward
+	226  AC Stop
+	227  AC Refresh
+	228  AC Previous Link
+	229  AC Next Link
+	22b  AC History
+	22c  AC Subscriptions
+	22d  AC Zoom In
+	22e  AC Zoom Out
+	22f  AC Zoom
+	230  AC Full Screen View
+	231  AC Normal View
+	232  AC View Toggle
+	233  AC Scroll Up
+	234  AC Scroll Down
+	235  AC Scroll
+	236  AC Pan Left
+	237  AC Pan Right
+	238  AC Pan
+	239  AC New Window
+	23a  AC Tile Horizontally
+	23b  AC Tile Vertically
+	23c  AC Format
+HUT 0d  Digitizer
+	000  Undefined
+	001  Digitizer
+	002  Pen
+	003  Light Pen
+	004  Touch Screen
+	005  Touch Pad
+	006  White Board
+	007  Coordinate Measuring Machine
+	008  3D Digitizer
+	009  Stereo Plotter
+	00a  Articulated Arm
+	00b  Armature
+	00c  Multiple Point Digitizer
+	00d  Free Space Wand
+	020  Stylus
+	021  Puck
+	022  Finger
+	030  Tip Pressure
+	031  Barrel Pressure
+	032  In Range
+	033  Touch
+	034  Untouch
+	035  Tap
+	036  Quality
+	037  Data Valid
+	038  Transducer Index
+	039  Tablet Function Keys
+	03a  Program Change Keys
+	03b  Battery Strength
+	03c  Invert
+	03d  X Tilt
+	03e  Y Tilt
+	03f  Azimuth
+	040  Altitude
+	041  Twist
+	042  Tip Switch
+	043  Secondary Tip Switch
+	044  Barrel Switch
+	045  Eraser
+	046  Tablet Pick
+HUT 0f  PID Page
+	000  Undefined
+	001  Physical Interface Device
+	020  Normal
+	021  Set Effect Report
+	022  Effect Block Index
+	023  Parameter Block Offset
+	024  ROM Flag
+	025  Effect Type
+	026  ET Constant Force
+	027  ET Ramp
+	028  ET Custom Force Data
+	030  ET Square
+	031  ET Sine
+	032  ET Triangle
+	033  ET Sawtooth Up
+	034  ET Sawtooth Down
+	040  ET Spring
+	041  ET Damper
+	042  ET Inertia
+	043  ET Friction
+	050  Duration
+	051  Sample Period
+	052  Gain
+	053  Trigger Button
+	054  Trigger Repeat Interval
+	055  Axes Enable
+	056  Direction Enable
+	057  Direction
+	058  Type Specific Block Offset
+	059  Block Type
+	05A  Set Envelope Report
+	05B  Attack Level
+	05C  Attack Time
+	05D  Fade Level
+	05E  Fade Time
+	05F  Set Condition Report
+	060  CP Offset
+	061  Positive Coefficient
+	062  Negative Coefficient
+	063  Positive Saturation
+	064  Negative Saturation
+	065  Dead Band
+	066  Download Force Sample
+	067  Isoch Custom Force Enable
+	068  Custom Force Data Report
+	069  Custom Force Data
+	06A  Custom Force Vendor Defined Data
+	06B  Set Custom Force Report
+	06C  Custom Force Data Offset
+	06D  Sample Count
+	06E  Set Periodic Report
+	06F  Offset
+	070  Magnitude
+	071  Phase
+	072  Period
+	073  Set Constant Force Report
+	074  Set Ramp Force Report
+	075  Ramp Start
+	076  Ramp End
+	077  Effect Operation Report
+	078  Effect Operation
+	079  Op Effect Start
+	07A  Op Effect Start Solo
+	07B  Op Effect Stop
+	07C  Loop Count
+	07D  Device Gain Report
+	07E  Device Gain
+	07F  PID Pool Report
+	080  RAM Pool Size
+	081  ROM Pool Size
+	082  ROM Effect Block Count
+	083  Simultaneous Effects Max
+	084  Pool Alignment
+	085  PID Pool Move Report
+	086  Move Source
+	087  Move Destination
+	088  Move Length
+	089  PID Block Load Report
+	08B  Block Load Status
+	08C  Block Load Success
+	08D  Block Load Full
+	08E  Block Load Error
+	08F  Block Handle
+	090  PID Block Free Report
+	091  Type Specific Block Handle
+	092  PID State Report
+	094  Effect Playing
+	095  PID Device Control Report
+	096  PID Device Control
+	097  DC Enable Actuators
+	098  DC Disable Actuators
+	099  DC Stop All Effects
+	09A  DC Device Reset
+	09B  DC Device Pause
+	09C  DC Device Continue
+	09F  Device Paused
+	0A0  Actuators Enabled
+	0A4  Safety Switch
+	0A5  Actuator Override Switch
+	0A6  Actuator Power
+	0A7  Start Delay
+	0A8  Parameter Block Size
+	0A9  Device Managed Pool
+	0AA  Shared Parameter Blocks
+	0AB  Create New Effect Report
+	0AC  RAM Pool Available
+HUT 10  Unicode
+HUT 14  Alphanumeric Display
+	000  Undefined
+	001  Alphanumeric Display
+	020  Display Attributes Report
+	021  ASCII Character Set
+	022  Data Read Back
+	023  Font Read Back
+	024  Display Control Report
+	025  Clear Display
+	026  Display Enable
+	027  Screen Saver Delay
+	028  Screen Saver Enable
+	029  Vertical Scroll
+	02a  Horizontal Scroll
+	02b  Character Report
+	02c  Display Data
+	02d  Display Status
+	02e  Stat Not Ready
+	02f  Stat Ready
+	030  Err Not a loadable Character
+	031  Err Font Data Cannot Be Read
+	032  Cursur Position Report
+	033  Row
+	034  Column
+	035  Rows
+	036  Columns
+	037  Cursor Pixel Positioning
+	038  Cursor Mode
+	039  Cursor Enable
+	03a  Cursor Blink
+	03b  Font Report
+	03c  Font Data
+	03d  Character Width
+	03e  Character Height
+	03f  Character Spacing Horizontal
+	040  Character Spacing Vertical
+	041  Unicode Character Set
+HUT 80  USB Monitor
+	001  Monitor Control
+	002  EDID Information
+	003  VDIF Information
+	004  VESA Version
+HUT 81  USB Monitor Enumerated Values
+HUT 82  Monitor VESA Virtual Controls
+	001  Degauss
+	010  Brightness
+	012  Contrast
+	016  Red Video Gain
+	018  Green Video Gain
+	01a  Blue Video Gain
+	01c  Focus
+	020  Horizontal Position
+	022  Horizontal Size
+	024  Horizontal Pincushion
+	026  Horizontal Pincushion Balance
+	028  Horizontal Misconvergence
+	02a  Horizontal Linearity
+	02c  Horizontal Linearity Balance
+	030  Vertical Position
+	032  Vertical Size
+	034  Vertical Pincushion
+	036  Vertical Pincushion Balance
+	038  Vertical Misconvergence
+	03a  Vertical Linearity
+	03c  Vertical Linearity Balance
+	040  Parallelogram Balance (Key Distortion)
+	042  Trapezoidal Distortion (Key)
+	044  Tilt (Rotation)
+	046  Top Corner Distortion Control
+	048  Top Corner Distortion Balance
+	04a  Bottom Corner Distortion Control
+	04c  Bottom Corner Distortion Balance
+	056  Horizontal Moire
+	058  Vertical Moire
+	05e  Input Level Select
+	060  Input Source Select
+	06c  Red Video Black Level
+	06e  Green Video Black Level
+	070  Blue Video Black Level
+	0a2  Auto Size Center
+	0a4  Polarity Horizontal Sychronization
+	0a6  Polarity Vertical Synchronization
+	0aa  Screen Orientation
+	0ac  Horizontal Frequency in Hz
+	0ae  Vertical Frequency in 0.1 Hz
+	0b0  Settings
+	0ca  On Screen Display (OSD)
+	0d4  Stereo Mode
+HUT 84  Power Device Page
+	000  Undefined
+	001  iName
+	002  Present Status
+	003  Changed Status
+	004  UPS
+	005  Power Supply
+	010  Battery System
+	011  Battery System ID
+	012  Battery
+	013  Battery ID
+	014  Charger
+	015  Charger ID
+	016  Power Converter
+	017  Power Converter ID
+	018  Outlet System
+	019  Outlet System ID
+	01a  Input
+	01b  Input ID
+	01c  Output
+	01d  Output ID
+	01e  Flow
+	01f  Flow ID
+	020  Outlet
+	021  Outlet ID
+	022  Gang
+	023  Gang ID
+	024  Power Summary
+	025  Power Summary ID
+	030  Voltage
+	031  Current
+	032  Frequency
+	033  Apparent Power
+	034  Active Power
+	035  Percent Load
+	036  Temperature
+	037  Humidity
+	038  Bad Count
+	040  Config Voltage
+	041  Config Current
+	042  Config Frequency
+	043  Config Apparent Power
+	044  Config Active Power
+	045  Config Percent Load
+	046  Config Temperature
+	047  Config Humidity
+	050  Switch On Control
+	051  Switch Off Control
+	052  Toggle Control
+	053  Low Voltage Transfer
+	054  High Voltage Transfer
+	055  Delay Before Reboot
+	056  Delay Before Startup
+	057  Delay Before Shutdown
+	058  Test
+	059  Module Reset
+	05a  Audible Alarm Control
+	060  Present
+	061  Good
+	062  Internal Failure
+	063  Voltage out of range
+	064  Frequency out of range
+	065  Overload
+	066  Over Charged
+	067  Over Temperature
+	068  Shutdown Requested
+	069  Shutdown  Imminent
+	06a  Reserved
+	06b  Switch On/Off
+	06c  Switchable
+	06d  Used
+	06e  Boost
+	06f  Buck
+	070  Initialized
+	071  Tested
+	072  Awaiting Power
+	073  Communication Lost
+	0fd  iManufacturer
+	0fe  iProduct
+	0ff  iSerialNumber
+HUT 85  Battery System Page
+	000  Undefined
+	001  SMB Battery Mode
+	002  SMB Battery Status
+	003  SMB Alarm Warning
+	004  SMB Charger Mode
+	005  SMB Charger Status
+	006  SMB Charger Spec Info
+	007  SMB Selector State
+	008  SMB Selector Presets
+	009  SMB Selector Info
+	010  Optional Mfg. Function 1
+	011  Optional Mfg. Function 2
+	012  Optional Mfg. Function 3
+	013  Optional Mfg. Function 4
+	014  Optional Mfg. Function 5
+	015  Connection to SMBus
+	016  Output Connection
+	017  Charger Connection
+	018  Battery Insertion
+	019  Use Next
+	01a  OK to use
+	01b  Battery  Supported
+	01c  SelectorRevision
+	01d  Charging Indicator
+	028  Manufacturer Access
+	029  Remaining Capacity Limit
+	02a  Remaining Time Limit
+	02b  At Rate
+	02c  Capacity Mode
+	02d  Broadcast To Charger
+	02e  Primary Battery
+	02f  Charge Controller
+	040  Terminate Charge
+	041  Terminate Discharge
+	042  Below Remaining Capacity Limit
+	043  Remaining Time Limit Expired
+	044  Charging
+	045  Discharging
+	046  Fully Charged
+	047  Fully Discharged
+	048  Conditioning Flag
+	049  At Rate OK
+	04a  SMB Error Code
+	04b  Need Replacement
+	060  At Rate Time To Full
+	061  At Rate Time To Empty
+	062  Average Current
+	063  Max Error
+	064  Relative State Of Charge
+	065  Absolute State Of Charge
+	066  Remaining Capacity
+	067  Full Charge Capacity
+	068  Run Time To Empty
+	069  Average Time To Empty
+	06a  Average Time To Full
+	06b  Cycle Count
+	080  Batt. Pack Model Level
+	081  Internal Charge Controller
+	082  Primary Battery Support
+	083  Design Capacity
+	084  Specification Info
+	085  Manufacturer Date
+	086  Serial Number
+	087  iManufacturerName
+	088  iDeviceName
+	089  iDeviceChemistry
+	08a  Manufacturer Data
+	08b  Rechargeable
+	08c  Warning Capacity Limit
+	08d  Capacity Granularity 1
+	08e  Capacity Granularity 2
+	08f  iOEMInformation
+	0c0  Inhibit Charge
+	0c1  Enable Polling
+	0c2  Reset To Zero
+	0d0  AC Present
+	0d1  Battery Present
+	0d2  Power Fail
+	0d3  Alarm Inhibited
+	0d4  Thermistor Under Range
+	0d5  Thermistor Hot
+	0d6  Thermistor Cold
+	0d7  Thermistor Over Range
+	0d8  Voltage Out Of Range
+	0d9  Current Out Of Range
+	0da  Current Not Regulated
+	0db  Voltage Not Regulated
+	0dc  Master Mode
+	0f0  Charger Selector Support
+	0f1  Charger Spec
+	0f2  Level 2
+	0f3  Level 3
+HUT 86  Power Pages
+HUT 87  Power Pages
+HUT 8c  Bar Code Scanner Page (POS)
+HUT 8d  Scale Page (POS)
+HUT 90  Camera Control Page
+HUT 91  Arcade Control Page
+HUT f0  Cash Device
+	0f1  Cash Drawer
+	0f2  Cash Drawer Number
+	0f3  Cash Drawer Set
+	0f4  Cash Drawer Status
+HUT ff  Vendor Specific
+
+# List of Languages
+
+# Syntax:
+# L language_id  language_name
+#	dialect_id  dialect_name
+
+L 0001  Arabic
+	01  Saudi Arabia
+	02  Iraq
+	03  Egypt
+	04  Libya
+	05  Algeria
+	06  Morocco
+	07  Tunesia
+	08  Oman
+	09  Yemen
+	0a  Syria
+	0b  Jordan
+	0c  Lebanon
+	0d  Kuwait
+	0e  U.A.E
+	0f  Bahrain
+	10  Qatar
+L 0002  Bulgarian
+L 0003  Catalan
+L 0004  Chinese
+	01  Traditional
+	02  Simplified
+	03  Hongkong SAR, PRC
+	04  Singapore
+	05  Macau SAR
+L 0005  Czech
+L 0006  Danish
+L 0007  German
+	01  German
+	02  Swiss
+	03  Austrian
+	04  Luxembourg
+	05  Liechtenstein
+L 0008  Greek
+L 0009  English
+	01  US
+	02  UK
+	03  Australian
+	04  Canadian
+	05  New Zealand
+	06  Ireland
+	07  South Africa
+	08  Jamaica
+	09  Carribean
+	0a  Belize
+	0b  Trinidad
+	0c  Zimbabwe
+	0d  Philippines
+L 000a  Spanish
+	01  Castilian
+	02  Mexican
+	03  Modern
+	04  Guatemala
+	05  Costa Rica
+	06  Panama
+	07  Dominican Republic
+	08  Venzuela
+	09  Colombia
+	0a  Peru
+	0b  Argentina
+	0c  Ecuador
+	0d  Chile
+	0e  Uruguay
+	0f  Paraguay
+	10  Bolivia
+	11  El Salvador
+	12  Honduras
+	13  Nicaragua
+	14  Puerto Rico
+L 000b  Finnish
+L 000c  French
+	01  French
+	02  Belgian
+	03  Canadian
+	04  Swiss
+	05  Luxembourg
+	06  Monaco
+L 000d  Hebrew
+L 000e  Hungarian
+L 000f  Idelandic
+L 0010  Italian
+	01  Italian
+	02  Swiss
+L 0011  Japanese
+L 0012  Korean
+	01  Korean
+L 0013  Dutch
+	01  Dutch
+	02  Belgian
+L 0014  Norwegian
+	01  Bokmal
+	02  Nynorsk
+L 0015  Polish
+L 0016	Portuguese
+	01  Portuguese
+	02  Brazilian
+L 0017  forgotten
+L 0018  Romanian
+L 0019  Russian
+L 001a  Serbian
+	01  Croatian
+	02  Latin
+	03  Cyrillic
+L 001b  Slovak
+L 001c  Albanian
+L 001d  Swedish
+	01  Swedish
+	02  Finland
+L 001e  Thai
+L 001f  Turkish
+L 0020  Urdu
+	01  Pakistan
+	02  India
+L 0021  Indonesian
+L 0022  Ukrainian
+L 0023  Belarusian
+L 0024  Slovenian
+L 0025  Estonian
+L 0026  Latvian
+L 0027  Lithuanian
+	01  Lithuanian
+L 0028  forgotten
+L 0029  Farsi
+L 002a  Vietnamese
+L 002b  Armenian
+L 002c  Azeri
+	01  Cyrillic
+	02  Latin
+L 002d  Basque
+L 002e  forgotten
+L 002f  Macedonian
+L 0036  Afrikaans
+L 0037  Georgian
+L 0038  Faeroese
+L 0039  Hindi
+L 003e  Malay
+	01  Malaysia
+	02  Brunei Darassalam
+L 003f  Kazak
+L 0041  Awahili
+L 0043  Uzbek
+	01  Latin
+	02  Cyrillic
+L 0044  Tatar
+L 0045  Bengali
+L 0046  Punjabi
+L 0047  Gujarati
+L 0048  Oriya
+L 0049  Tamil
+L 004a  Telugu
+L 004b  Kannada
+L 004c  Malayalam
+L 004d  Assamese
+L 004e  Marathi
+L 004f  Sanskrit
+L 0057  Konkani
+L 0058  Manipuri
+L 0059  Sindhi
+L 0060  Kashmiri
+	02  India
+L 0061  Nepali
+	02  India
+
+# HID Descriptor bCountryCode
+# HID Specification 1.11 (2001-06-27) page 23
+#
+# Syntax:
+# HCC country_code keymap_type
+
+HCC 00  Not supported
+HCC 01  Arabic
+HCC 02  Belgian
+HCC 03  Canadian-Bilingual
+HCC 04  Canadian-French
+HCC 05  Czech Republic
+HCC 06  Danish
+HCC 07  Finnish
+HCC 08  French
+HCC 09  German
+HCC 10  Greek
+HCC 11  Hebrew
+HCC 12  Hungary
+HCC 13  International (ISO)
+HCC 14  Italian
+HCC 15  Japan (Katakana)
+HCC 16  Korean
+HCC 17  Latin American
+HCC 18  Netherlands/Dutch
+HCC 19  Norwegian
+HCC 20  Persian (Farsi)
+HCC 21  Poland
+HCC 22  Portuguese
+HCC 23  Russia
+HCC 24  Slovakia
+HCC 25  Spanish
+HCC 26  Swedish
+HCC 27  Swiss/French
+HCC 28  Swiss/German
+HCC 29  Switzerland
+HCC 30  Taiwan
+HCC 31  Turkish-Q
+HCC 32  UK
+HCC 33  US
+HCC 34  Yugoslavia
+HCC 35  Turkish-F
+
+# List of Video Class Terminal Types
+
+# Syntax:
+# VT terminal_type  terminal_type_name
+
+VT 0100  USB Vendor Specific
+VT 0101  USB Streaming
+VT 0200  Input Vendor Specific
+VT 0201  Camera Sensor
+VT 0202  Sequential Media
+VT 0300  Output Vendor Specific
+VT 0301  Generic Display
+VT 0302  Sequential Media
+VT 0400  External Vendor Specific
+VT 0401  Composite Video
+VT 0402  S-Video
+VT 0403  Component Video
+
