[PATCH] Add code to support USBIP Project for Windows

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: VizXu <xujiweigo@xxxxxxx>
---
 drivers/usb/usbip/stub_dev.c     |  4 ++++
 drivers/usb/usbip/stub_rx.c      | 37 +++++++++++++++++++++++++++++++++++++
 drivers/usb/usbip/usbip_common.h | 16 ++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
index c0d6ff1..be95c72 100644
--- a/drivers/usb/usbip/stub_dev.c
+++ b/drivers/usb/usbip/stub_dev.c
@@ -270,6 +270,10 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev)
 	sdev->ud.tcp_socket	= NULL;
 	sdev->ud.sockfd		= -1;
 
+#ifdef SUPPORT_WIN
+	sdev->ud.is_configured = false;
+#endif
+
 	INIT_LIST_HEAD(&sdev->priv_init);
 	INIT_LIST_HEAD(&sdev->priv_tx);
 	INIT_LIST_HEAD(&sdev->priv_free);
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c
index 97b09a4..8e004bc 100644
--- a/drivers/usb/usbip/stub_rx.c
+++ b/drivers/usb/usbip/stub_rx.c
@@ -11,6 +11,35 @@
 #include "usbip_common.h"
 #include "stub.h"
 
+#ifdef SUPPORT_WIN
+static int usbip_device_init_configuration(struct usbip_device *ud)
+{
+	struct usb_ctrlrequest req;
+	__u16 config;
+	int err;
+
+	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
+
+	struct usb_device *udev = sdev->udev;
+
+	req.bRequest = USB_REQ_SET_CONFIGURATION;
+	req.bRequestType = USB_RECIP_DEVICE;
+	req.wIndex	= 0x00;
+	req.wLength = 0x00;
+	req.wValue	= 0x01;
+	config = le16_to_cpu(req.wValue);
+
+	err = usb_set_configuration(udev, config);
+	if (err && err != -ENODEV) {
+		dev_err(&udev->dev, "%s can't set config\n", "usbip_device_init_configuration");
+		return -1;
+	}
+	ud->is_configured = true;
+
+	return 0;
+}
+#endif
+
 static int is_clear_halt_cmd(struct urb *urb)
 {
 	struct usb_ctrlrequest *req;
@@ -579,6 +608,14 @@ int stub_rx_loop(void *data)
 {
 	struct usbip_device *ud = data;
 
+#ifdef SUPPORT_WIN
+	if (!ud->is_configured) {
+		if (-1 == usbip_device_init_configuration(ud)) {
+			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
+		}
+	}
+#endif
+
 	while (!kthread_should_stop()) {
 		if (usbip_event_happened(ud))
 			break;
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index bf8afe9..b5189e6 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -122,6 +122,17 @@ extern struct device_attribute dev_attr_usbip_debug;
 #define USBIP_DIR_IN	0x01
 
 /**
+* Support USBIP project for Windows: http://usbip.sourceforge.net/
+*	The configuration is not initialized after an USB device bound in Linux
+* 	and that would make Linux kernel crash if usbip.exe attach it.
+*	I've analysized this process with wireshark and found that usbip.exe
+*	would not "SET CONFIGURATION Request". I suppose the process of loading
+*	a USB device is different between Linux and Windows.
+*	Make a usb_set_configuration at the first time would fix this issue.
+*/
+#define SUPPORT_WIN
+
+/**
  * struct usbip_header_basic - data pertinent to every request
  * @command: the usbip request type
  * @seqnum: sequential number that identifies requests; incremented per
@@ -257,6 +268,11 @@ struct usbip_device {
 	spinlock_t lock;
 
 	int sockfd;
+
+#ifdef SUPPORT_WIN
+	bool is_configured;
+#endif
+
 	struct socket *tcp_socket;
 
 	struct task_struct *tcp_rx;
-- 
2.7.4





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux