105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* 205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * Copyright (C) 2003-2008 Takahiro Hirofuchi 305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * 405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * This is free software; you can redistribute it and/or modify 505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * it under the terms of the GNU General Public License as published by 605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * the Free Software Foundation; either version 2 of the License, or 705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * (at your option) any later version. 805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * 905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * This is distributed in the hope that it will be useful, 1005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * but WITHOUT ANY WARRANTY; without even the implied warranty of 1105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * GNU General Public License for more details. 1305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * 1405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * You should have received a copy of the GNU General Public License 1505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * along with this program; if not, write to the Free Software 1605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * USA. 1805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi */ 1905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 207aaacb43ed97714ff0f7f77f306f24b6e564ad03matt mooney#include <asm/byteorder.h> 2105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi#include <linux/file.h> 227aaacb43ed97714ff0f7f77f306f24b6e564ad03matt mooney#include <linux/fs.h> 237aaacb43ed97714ff0f7f77f306f24b6e564ad03matt mooney#include <linux/kernel.h> 245a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 25452962366c11a9126fabac8cb28af49c27464408Paul Gortmaker#include <linux/module.h> 267aaacb43ed97714ff0f7f77f306f24b6e564ad03matt mooney#include <net/sock.h> 274ce0a41f1054b58801f7e14f5036cf27a75152e2matt mooney 2805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi#include "usbip_common.h" 2905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 304ce0a41f1054b58801f7e14f5036cf27a75152e2matt mooney#define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>" 3164e62426f40d1017a7ced93ee71d333529196365matt mooney#define DRIVER_DESC "USB/IP Core" 3205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 3364e62426f40d1017a7ced93ee71d333529196365matt mooney#ifdef CONFIG_USBIP_DEBUG 3405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchiunsigned long usbip_debug_flag = 0xffffffff; 3505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi#else 3605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchiunsigned long usbip_debug_flag; 3705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi#endif 3805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_debug_flag); 3905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 4005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* FIXME */ 4105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistruct device_attribute dev_attr_usbip_debug; 4205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(dev_attr_usbip_debug); 4305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 4405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic ssize_t show_flag(struct device *dev, struct device_attribute *attr, 45f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney char *buf) 4605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 4705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return sprintf(buf, "%lx\n", usbip_debug_flag); 4805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 4905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 5005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic ssize_t store_flag(struct device *dev, struct device_attribute *attr, 51f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney const char *buf, size_t count) 5205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 531e5065dbd6fe53b46d8281db7b4286751dcf607aHimanshu Chauhan sscanf(buf, "%lx", &usbip_debug_flag); 5405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return count; 5505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 5605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiDEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag); 5705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 5805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_dump_buffer(char *buff, int bufflen) 5905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 601a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney print_hex_dump(KERN_DEBUG, "usbip-core", DUMP_PREFIX_OFFSET, 16, 4, 61aad86577b829be29048e0a692e1c28c3ffeda6caHimanshu Chauhan buff, bufflen, false); 6205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 6305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 6405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_dump_pipe(unsigned int p) 6505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 6605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi unsigned char type = usb_pipetype(p); 6787352760173082c2a774f83dc6fe826fdbf219c0matt mooney unsigned char ep = usb_pipeendpoint(p); 6887352760173082c2a774f83dc6fe826fdbf219c0matt mooney unsigned char dev = usb_pipedevice(p); 6987352760173082c2a774f83dc6fe826fdbf219c0matt mooney unsigned char dir = usb_pipein(p); 7005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 711a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT"); 7205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 7305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (type) { 7405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case PIPE_ISOCHRONOUS: 751a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("ISO\n"); 7605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 7705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case PIPE_INTERRUPT: 781a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("INT\n"); 7905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 8005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case PIPE_CONTROL: 811a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("CTRL\n"); 8205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 8305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case PIPE_BULK: 841a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("BULK\n"); 8505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 8605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 871a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("ERR\n"); 8849aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 8905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 9005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 9105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 9205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_dump_usb_device(struct usb_device *udev) 9305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 9405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct device *dev = &udev->dev; 9505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int i; 9605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 971a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney dev_dbg(dev, " devnum(%d) devpath(%s) ", 9805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi udev->devnum, udev->devpath); 9905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 10005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (udev->speed) { 10105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_SPEED_HIGH: 1021a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SPD_HIGH "); 10305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 10405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_SPEED_FULL: 1051a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SPD_FULL "); 10605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 10705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_SPEED_LOW: 1081a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SPD_LOW "); 10905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 11005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_SPEED_UNKNOWN: 1111a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SPD_UNKNOWN "); 11205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 11305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 1141a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SPD_ERROR "); 11549aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 11605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 11705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 1181a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("tt %p, ttport %d\n", udev->tt, udev->ttport); 11905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 12005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " "); 12105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < 16; i++) 1221a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" %2u", i); 1231a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n"); 12405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 12505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " toggle0(IN) :"); 12605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < 16; i++) 1271a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0); 1281a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n"); 12905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 13005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " toggle1(OUT):"); 13105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < 16; i++) 1321a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0); 1331a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n"); 13405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 13505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " epmaxp_in :"); 13605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < 16; i++) { 13705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (udev->ep_in[i]) 1381a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" %2u", 1391a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize)); 14005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 1411a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n"); 14205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 14305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " epmaxp_out :"); 14405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < 16; i++) { 14505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (udev->ep_out[i]) 1461a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" %2u", 1471a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize)); 14805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 1491a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n"); 15005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 15105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus); 15205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 15305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, "descriptor %p, config %p, actconfig %p, " 15405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi "rawdescriptors %p\n", &udev->descriptor, udev->config, 15505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi udev->actconfig, udev->rawdescriptors); 15605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 15705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, "have_langid %d, string_langid %d\n", 15805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi udev->have_langid, udev->string_langid); 15905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 16005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, "maxchild %d, children %p\n", 16105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi udev->maxchild, udev->children); 16205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 16305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 16405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_dump_request_type(__u8 rt) 16505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 16605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (rt & USB_RECIP_MASK) { 16705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_RECIP_DEVICE: 1681a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("DEVICE"); 16905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 17005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_RECIP_INTERFACE: 1711a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("INTERF"); 17205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 17305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_RECIP_ENDPOINT: 1741a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("ENDPOI"); 17505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 17605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_RECIP_OTHER: 1771a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("OTHER "); 17805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 17905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 1801a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("------"); 18149aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 18205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 18305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 18405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 18505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd) 18605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 18705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!cmd) { 1881a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" : null pointer\n"); 18905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return; 19005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 19105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 1921a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug(" "); 1931a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("bRequestType(%02X) bRequest(%02X) wValue(%04X) wIndex(%04X) " 1941a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney "wLength(%04X) ", cmd->bRequestType, cmd->bRequest, 1951a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney cmd->wValue, cmd->wIndex, cmd->wLength); 1961a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("\n "); 19705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 19805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { 1991a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("STANDARD "); 20005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (cmd->bRequest) { 20105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_GET_STATUS: 2021a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("GET_STATUS\n"); 20305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 20405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_CLEAR_FEATURE: 2051a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("CLEAR_FEAT\n"); 20605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 20705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SET_FEATURE: 2085ad7b85b90e30eb5af4fbf6ce21907a2bd8934dfAkshay Joshi pr_debug("SET_FEAT\n"); 20905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 21005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SET_ADDRESS: 2111a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SET_ADDRRS\n"); 21205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 21305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_GET_DESCRIPTOR: 2141a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("GET_DESCRI\n"); 21505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 21605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SET_DESCRIPTOR: 2171a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SET_DESCRI\n"); 21805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 21905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_GET_CONFIGURATION: 2201a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("GET_CONFIG\n"); 22105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 22205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SET_CONFIGURATION: 2231a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SET_CONFIG\n"); 22405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 22505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_GET_INTERFACE: 2261a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("GET_INTERF\n"); 22705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 22805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SET_INTERFACE: 2291a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SET_INTERF\n"); 23005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 23105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USB_REQ_SYNCH_FRAME: 2321a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("SYNC_FRAME\n"); 23305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 23405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 2355ad7b85b90e30eb5af4fbf6ce21907a2bd8934dfAkshay Joshi pr_debug("REQ(%02X)\n", cmd->bRequest); 23649aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 23705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 23805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_dump_request_type(cmd->bRequestType); 2391a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { 2405ad7b85b90e30eb5af4fbf6ce21907a2bd8934dfAkshay Joshi pr_debug("CLASS\n"); 2411a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { 2425ad7b85b90e30eb5af4fbf6ce21907a2bd8934dfAkshay Joshi pr_debug("VENDOR\n"); 2431a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) { 2441a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("RESERVED\n"); 2451a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney } 24605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 24705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 24805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchivoid usbip_dump_urb(struct urb *urb) 24905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 25005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct device *dev; 25105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 25205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!urb) { 2531a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("urb: null pointer!!\n"); 25405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return; 25505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 25605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 25705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!urb->dev) { 2581a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("urb->dev: null pointer!!\n"); 25905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return; 26005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 2611a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney 26205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev = &urb->dev->dev; 26305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 26405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " urb :%p\n", urb); 26505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " dev :%p\n", urb->dev); 26605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 26705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_dump_usb_device(urb->dev); 26805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 26905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " pipe :%08x ", urb->pipe); 27005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 27105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_dump_pipe(urb->pipe); 27205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 27305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " status :%d\n", urb->status); 27405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags); 27505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " transfer_buffer :%p\n", urb->transfer_buffer); 276b8868e45c5f8956d57ba489df3ebd24e3f858684Brian G. Merrell dev_dbg(dev, " transfer_buffer_length:%d\n", 277b8868e45c5f8956d57ba489df3ebd24e3f858684Brian G. Merrell urb->transfer_buffer_length); 27805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " actual_length :%d\n", urb->actual_length); 27905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " setup_packet :%p\n", urb->setup_packet); 28005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 28105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL) 282f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney usbip_dump_usb_ctrlrequest( 28305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi (struct usb_ctrlrequest *)urb->setup_packet); 28405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 28505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " start_frame :%d\n", urb->start_frame); 28605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets); 28705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " interval :%d\n", urb->interval); 28805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " error_count :%d\n", urb->error_count); 28905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " context :%p\n", urb->context); 29005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_dbg(dev, " complete :%p\n", urb->complete); 29105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 29205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_dump_urb); 29305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 29405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchivoid usbip_dump_header(struct usbip_header *pdu) 29505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 2961a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("BASE: cmd %u seq %u devid %u dir %u ep %u\n", 2971a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->base.command, 2981a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->base.seqnum, 2991a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->base.devid, 3001a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->base.direction, 3011a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->base.ep); 30205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 30305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (pdu->base.command) { 30405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_CMD_SUBMIT: 3051a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("USBIP_CMD_SUBMIT: " 3061a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney "x_flags %u x_len %u sf %u #p %d iv %d\n", 3071a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_submit.transfer_flags, 3081a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_submit.transfer_buffer_length, 3091a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_submit.start_frame, 3101a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_submit.number_of_packets, 3111a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_submit.interval); 312f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney break; 31305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_CMD_UNLINK: 3141a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("USBIP_CMD_UNLINK: seq %u\n", 3151a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.cmd_unlink.seqnum); 31605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 31705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_RET_SUBMIT: 3181a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("USBIP_RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", 3191a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_submit.status, 3201a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_submit.actual_length, 3211a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_submit.start_frame, 3221a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_submit.number_of_packets, 3231a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_submit.error_count); 3241a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney break; 32505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_RET_UNLINK: 3261a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_debug("USBIP_RET_UNLINK: status %d\n", 3271a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pdu->u.ret_unlink.status); 32805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 32905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 33005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* NOT REACHED */ 3311a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_err("unknown command\n"); 33249aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 33305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 33405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 33505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_dump_header); 33605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 3375a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest/* Receive data over TCP/IP. */ 3385a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeestint usbip_recv(struct socket *sock, void *buf, int size) 33905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 34005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int result; 34105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct msghdr msg; 34205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct kvec iov; 34305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int total = 0; 34405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 345b8868e45c5f8956d57ba489df3ebd24e3f858684Brian G. Merrell /* for blocks of if (usbip_dbg_flag_xmit) */ 34605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi char *bp = buf; 34705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int osize = size; 34805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 349b8868e45c5f8956d57ba489df3ebd24e3f858684Brian G. Merrell usbip_dbg_xmit("enter\n"); 35005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 35105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!sock || !buf || !size) { 3521a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, 3531a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney size); 35405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return -EINVAL; 35505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 35605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 35705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi do { 35805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi sock->sk->sk_allocation = GFP_NOIO; 35905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iov.iov_base = buf; 36005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iov.iov_len = size; 36105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi msg.msg_name = NULL; 36205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi msg.msg_namelen = 0; 36305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi msg.msg_control = NULL; 36405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi msg.msg_controllen = 0; 36505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi msg.msg_namelen = 0; 3665a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest msg.msg_flags = MSG_NOSIGNAL; 36705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 3685a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); 36905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (result <= 0) { 3705a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest pr_debug("receive sock %p buf %p size %u ret %d total %d\n", 3715a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest sock, buf, size, result, total); 37205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi goto err; 37305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 37405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 37505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi size -= result; 37605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi buf += result; 37705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi total += result; 37805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } while (size > 0); 37905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 380b8868e45c5f8956d57ba489df3ebd24e3f858684Brian G. Merrell if (usbip_dbg_flag_xmit) { 3815a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest if (!in_interrupt()) 3825a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest pr_debug("%-10s:", current->comm); 3835a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest else 3845a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest pr_debug("interrupt :"); 38505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 3865a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest pr_debug("receiving....\n"); 3875a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest usbip_dump_buffer(bp, osize); 3885a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest pr_debug("received, osize %d ret %d size %d total %d\n", 3895a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest osize, result, size, total); 39005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 39105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 39205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return total; 39305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 39405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchierr: 39505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return result; 39605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 3975a08c5267e45fe936452051a8c126e8418984eb7Bart WestgeestEXPORT_SYMBOL_GPL(usbip_recv); 39805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 39905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistruct socket *sockfd_to_socket(unsigned int sockfd) 40005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 40105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct socket *socket; 40205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct file *file; 40305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct inode *inode; 40405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 40505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi file = fget(sockfd); 40605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!file) { 4071a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_err("invalid sockfd\n"); 40805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return NULL; 40905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 41005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 41105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi inode = file->f_dentry->d_inode; 41205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 41305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!inode || !S_ISSOCK(inode->i_mode)) 41405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return NULL; 41505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 41605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi socket = SOCKET_I(inode); 41705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 41805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return socket; 41905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 42005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(sockfd_to_socket); 42105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 42205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* there may be more cases to tweak the flags. */ 42305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic unsigned int tweak_transfer_flags(unsigned int flags) 42405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 42585bcb5ee889e0ebb9154718939e049de265fcdfbAlan Stern flags &= ~URB_NO_TRANSFER_DMA_MAP; 42605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return flags; 42705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 42805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 42905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, 430f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int pack) 43105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 43205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit; 43305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 43405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* 43505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * Some members are not still implemented in usbip. I hope this issue 43605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi * will be discussed when usbip is ported to other operating systems. 43705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi */ 43805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (pack) { 43905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* vhci_tx.c */ 44005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi spdu->transfer_flags = 441f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney tweak_transfer_flags(urb->transfer_flags); 44205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi spdu->transfer_buffer_length = urb->transfer_buffer_length; 44305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi spdu->start_frame = urb->start_frame; 44405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi spdu->number_of_packets = urb->number_of_packets; 44505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi spdu->interval = urb->interval; 44605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 44705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* stub_rx.c */ 44805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->transfer_flags = spdu->transfer_flags; 44905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 45005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->transfer_buffer_length = spdu->transfer_buffer_length; 45105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->start_frame = spdu->start_frame; 45205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->number_of_packets = spdu->number_of_packets; 45305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->interval = spdu->interval; 45405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 45505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 45605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 45705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, 458f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int pack) 45905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 46005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit; 46105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 46205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (pack) { 46305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* stub_tx.c */ 46405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 46505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi rpdu->status = urb->status; 46605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi rpdu->actual_length = urb->actual_length; 46705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi rpdu->start_frame = urb->start_frame; 4681325f85fa49f57df034869de430f7c302ae23109Arjan Mels rpdu->number_of_packets = urb->number_of_packets; 46905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi rpdu->error_count = urb->error_count; 47005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 47105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* vhci_rx.c */ 47205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 47305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->status = rpdu->status; 47405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->actual_length = rpdu->actual_length; 47505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->start_frame = rpdu->start_frame; 4761325f85fa49f57df034869de430f7c302ae23109Arjan Mels urb->number_of_packets = rpdu->number_of_packets; 47705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi urb->error_count = rpdu->error_count; 47805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 47905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 48005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 48105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchivoid usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, 482f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int pack) 48305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 48405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (cmd) { 48505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_CMD_SUBMIT: 48605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_pack_cmd_submit(pdu, urb, pack); 48705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 48805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_RET_SUBMIT: 48905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_pack_ret_submit(pdu, urb, pack); 49005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 49105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 49249aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney /* NOT REACHED */ 4931a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_err("unknown command\n"); 49449aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 49505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 49605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 49705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_pack_pdu); 49805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 49905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void correct_endian_basic(struct usbip_header_basic *base, int send) 50005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 50105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) { 50205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->command = cpu_to_be32(base->command); 50305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->seqnum = cpu_to_be32(base->seqnum); 50405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->devid = cpu_to_be32(base->devid); 50505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->direction = cpu_to_be32(base->direction); 50605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->ep = cpu_to_be32(base->ep); 50705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 50805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->command = be32_to_cpu(base->command); 50905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->seqnum = be32_to_cpu(base->seqnum); 51005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->devid = be32_to_cpu(base->devid); 51105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->direction = be32_to_cpu(base->direction); 51205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi base->ep = be32_to_cpu(base->ep); 51305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 51405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 51505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 51605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, 517f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int send) 51805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 51905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) { 52005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags); 52105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 52205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->transfer_buffer_length); 52305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->start_frame); 52405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->number_of_packets); 52505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->interval); 52605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 52705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags); 52805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 52905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->transfer_buffer_length); 53005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->start_frame); 53105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->number_of_packets); 53205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->interval); 53305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 53405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 53505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 53605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, 537f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int send) 53805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 53905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) { 54005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->status); 54105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->actual_length); 54205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->start_frame); 5431325f85fa49f57df034869de430f7c302ae23109Arjan Mels cpu_to_be32s(&pdu->number_of_packets); 54405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->error_count); 54505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 54605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->status); 54705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->actual_length); 54805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->start_frame); 549cacd18a8476ce145ca5dcd46dc5b75585fd1289cDavid Chang be32_to_cpus(&pdu->number_of_packets); 55005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->error_count); 55105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 55205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 55305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 55405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, 555f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int send) 55605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 55705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) 55805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi pdu->seqnum = cpu_to_be32(pdu->seqnum); 55905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi else 56005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi pdu->seqnum = be32_to_cpu(pdu->seqnum); 56105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 56205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 56305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, 564f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney int send) 56505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 56605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) 56705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cpu_to_be32s(&pdu->status); 56805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi else 56905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi be32_to_cpus(&pdu->status); 57005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 57105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 57205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchivoid usbip_header_correct_endian(struct usbip_header *pdu, int send) 57305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 57405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi __u32 cmd = 0; 57505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 57605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) 57705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cmd = pdu->base.command; 57805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 57905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi correct_endian_basic(&pdu->base, send); 58005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 58105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!send) 58205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi cmd = pdu->base.command; 58305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 58405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi switch (cmd) { 58505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_CMD_SUBMIT: 58605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi correct_endian_cmd_submit(&pdu->u.cmd_submit, send); 58705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 58805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_RET_SUBMIT: 58905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi correct_endian_ret_submit(&pdu->u.ret_submit, send); 59005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 59105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_CMD_UNLINK: 59205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send); 59305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 59405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi case USBIP_RET_UNLINK: 59505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi correct_endian_ret_unlink(&pdu->u.ret_unlink, send); 59605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi break; 59705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi default: 59849aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney /* NOT REACHED */ 5991a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_err("unknown command\n"); 60049aecefcdef5a26a7fb036d4c57573f0e0e2089bmatt mooney break; 60105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 60205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 60305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_header_correct_endian); 60405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 6052282e1fb6b696b0fa3c08b6a9b3a94be84ef458bmatt mooneystatic void usbip_iso_packet_correct_endian( 60687352760173082c2a774f83dc6fe826fdbf219c0matt mooney struct usbip_iso_packet_descriptor *iso, int send) 60705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 60805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* does not need all members. but copy all simply. */ 60905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (send) { 61005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->offset = cpu_to_be32(iso->offset); 61105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->length = cpu_to_be32(iso->length); 61205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->status = cpu_to_be32(iso->status); 61305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->actual_length = cpu_to_be32(iso->actual_length); 61405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 61505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->offset = be32_to_cpu(iso->offset); 61605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->length = be32_to_cpu(iso->length); 61705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->status = be32_to_cpu(iso->status); 61805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->actual_length = be32_to_cpu(iso->actual_length); 61905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 62005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 62105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 62205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchistatic void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso, 623f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney struct usb_iso_packet_descriptor *uiso, int pack) 62405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 62505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (pack) { 62605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->offset = uiso->offset; 62705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->length = uiso->length; 62805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->status = uiso->status; 62905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso->actual_length = uiso->actual_length; 63005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 63105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi uiso->offset = iso->offset; 63205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi uiso->length = iso->length; 63305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi uiso->status = iso->status; 63405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi uiso->actual_length = iso->actual_length; 63505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 63605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 63705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 63805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* must free buffer */ 63905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchivoid *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) 64005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 64105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi void *buff; 64205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct usbip_iso_packet_descriptor *iso; 64305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int np = urb->number_of_packets; 64405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi ssize_t size = np * sizeof(*iso); 64505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int i; 64605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 64705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi buff = kzalloc(size, GFP_KERNEL); 64805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!buff) 64905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return NULL; 65005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 65105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < np; i++) { 65205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso = buff + (i * sizeof(*iso)); 65305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 65405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1); 6552282e1fb6b696b0fa3c08b6a9b3a94be84ef458bmatt mooney usbip_iso_packet_correct_endian(iso, 1); 65605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 65705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 65805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi *bufflen = size; 65905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 66005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return buff; 66105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 66205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu); 66305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 66405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* some members of urb must be substituted before. */ 66505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchiint usbip_recv_iso(struct usbip_device *ud, struct urb *urb) 66605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 66705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi void *buff; 66805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi struct usbip_iso_packet_descriptor *iso; 66905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int np = urb->number_of_packets; 67005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int size = np * sizeof(*iso); 67105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int i; 67205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int ret; 67328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels int total_length = 0; 67405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 67505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!usb_pipeisoc(urb->pipe)) 67605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 67705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 67805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* my Bluetooth dongle gets ISO URBs which are np = 0 */ 67905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (np == 0) { 6801a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney /* pr_info("iso np == 0\n"); */ 68105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* usbip_dump_urb(urb); */ 68205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 68305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 68405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 68505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi buff = kzalloc(size, GFP_KERNEL); 68605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!buff) 68705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return -ENOMEM; 68805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 6895a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest ret = usbip_recv(ud->tcp_socket, buff, size); 69005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (ret != size) { 69105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n", 69205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi ret); 69305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi kfree(buff); 69405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 69505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (ud->side == USBIP_STUB) 69605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 69705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi else 69805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); 69905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 70005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return -EPIPE; 70105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 70205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 70305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi for (i = 0; i < np; i++) { 70405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi iso = buff + (i * sizeof(*iso)); 70505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 7062282e1fb6b696b0fa3c08b6a9b3a94be84ef458bmatt mooney usbip_iso_packet_correct_endian(iso, 0); 70705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); 70828276a28d8b3cd19f4449991faad4945fe557656Arjan Mels total_length += urb->iso_frame_desc[i].actual_length; 70905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 71005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 71105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi kfree(buff); 71205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 71328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels if (total_length != urb->actual_length) { 71428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels dev_err(&urb->dev->dev, 715f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney "total length of iso packets %d not equal to actual " 716f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney "length of buffer %d\n", 717f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney total_length, urb->actual_length); 71828276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 71928276a28d8b3cd19f4449991faad4945fe557656Arjan Mels if (ud->side == USBIP_STUB) 72028276a28d8b3cd19f4449991faad4945fe557656Arjan Mels usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 72128276a28d8b3cd19f4449991faad4945fe557656Arjan Mels else 72228276a28d8b3cd19f4449991faad4945fe557656Arjan Mels usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); 72328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 72428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels return -EPIPE; 72528276a28d8b3cd19f4449991faad4945fe557656Arjan Mels } 72628276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 72705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return ret; 72805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 72905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_recv_iso); 73005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 73128276a28d8b3cd19f4449991faad4945fe557656Arjan Mels/* 73228276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * This functions restores the padding which was removed for optimizing 73328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * the bandwidth during transfer over tcp/ip 73428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * 73528276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * buffer and iso packets need to be stored and be in propeper endian in urb 73628276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * before calling this function 73728276a28d8b3cd19f4449991faad4945fe557656Arjan Mels */ 738ac2b41acfa3efe4650102067a99251587a806d70Bart Westgeestvoid usbip_pad_iso(struct usbip_device *ud, struct urb *urb) 73928276a28d8b3cd19f4449991faad4945fe557656Arjan Mels{ 74028276a28d8b3cd19f4449991faad4945fe557656Arjan Mels int np = urb->number_of_packets; 74128276a28d8b3cd19f4449991faad4945fe557656Arjan Mels int i; 74228276a28d8b3cd19f4449991faad4945fe557656Arjan Mels int actualoffset = urb->actual_length; 74328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 74428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels if (!usb_pipeisoc(urb->pipe)) 745ac2b41acfa3efe4650102067a99251587a806d70Bart Westgeest return; 74628276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 74728276a28d8b3cd19f4449991faad4945fe557656Arjan Mels /* if no packets or length of data is 0, then nothing to unpack */ 74828276a28d8b3cd19f4449991faad4945fe557656Arjan Mels if (np == 0 || urb->actual_length == 0) 749ac2b41acfa3efe4650102067a99251587a806d70Bart Westgeest return; 75028276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 75128276a28d8b3cd19f4449991faad4945fe557656Arjan Mels /* 75228276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * if actual_length is transfer_buffer_length then no padding is 75328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * present. 75428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels */ 75528276a28d8b3cd19f4449991faad4945fe557656Arjan Mels if (urb->actual_length == urb->transfer_buffer_length) 756ac2b41acfa3efe4650102067a99251587a806d70Bart Westgeest return; 75728276a28d8b3cd19f4449991faad4945fe557656Arjan Mels 75828276a28d8b3cd19f4449991faad4945fe557656Arjan Mels /* 75928276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * loop over all packets from last to first (to prevent overwritting 76028276a28d8b3cd19f4449991faad4945fe557656Arjan Mels * memory when padding) and move them into the proper place 76128276a28d8b3cd19f4449991faad4945fe557656Arjan Mels */ 76228276a28d8b3cd19f4449991faad4945fe557656Arjan Mels for (i = np-1; i > 0; i--) { 76328276a28d8b3cd19f4449991faad4945fe557656Arjan Mels actualoffset -= urb->iso_frame_desc[i].actual_length; 76428276a28d8b3cd19f4449991faad4945fe557656Arjan Mels memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset, 765f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney urb->transfer_buffer + actualoffset, 766f9eacc9846041f84f5f9abcbb99cb1a52c235e88matt mooney urb->iso_frame_desc[i].actual_length); 76728276a28d8b3cd19f4449991faad4945fe557656Arjan Mels } 76828276a28d8b3cd19f4449991faad4945fe557656Arjan Mels} 76928276a28d8b3cd19f4449991faad4945fe557656Arjan MelsEXPORT_SYMBOL_GPL(usbip_pad_iso); 77005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 77105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi/* some members of urb must be substituted before. */ 77205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchiint usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) 77305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 77405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int ret; 77505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi int size; 77605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 77705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (ud->side == USBIP_STUB) { 77805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* stub_rx.c */ 77905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* the direction of urb must be OUT. */ 78005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (usb_pipein(urb->pipe)) 78105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 78205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 78305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi size = urb->transfer_buffer_length; 78405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 78505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* vhci_rx.c */ 78605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* the direction of urb must be IN. */ 78705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (usb_pipeout(urb->pipe)) 78805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 78905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 79005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi size = urb->actual_length; 79105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 79205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 79305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi /* no need to recv xbuff */ 79405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (!(size > 0)) 79505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 79605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 7975a08c5267e45fe936452051a8c126e8418984eb7Bart Westgeest ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size); 79805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (ret != size) { 79905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret); 80005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi if (ud->side == USBIP_STUB) { 80105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); 80205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } else { 80305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); 80405a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return -EPIPE; 80505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 80605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi } 80705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 80805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return ret; 80905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 81005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiEXPORT_SYMBOL_GPL(usbip_recv_xbuff); 81105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 8123028d0ae6c69318c11f67affb29411d30c0cb955matt mooneystatic int __init usbip_core_init(void) 81305a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 8141a4b6f66285785ddccef049e6b45be4e7c7a2189matt mooney pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); 81505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return 0; 81605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 81705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 8183028d0ae6c69318c11f67affb29411d30c0cb955matt mooneystatic void __exit usbip_core_exit(void) 81905a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi{ 82005a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi return; 82105a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi} 82205a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 8233028d0ae6c69318c11f67affb29411d30c0cb955matt mooneymodule_init(usbip_core_init); 8243028d0ae6c69318c11f67affb29411d30c0cb955matt mooneymodule_exit(usbip_core_exit); 82505a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro Hirofuchi 82605a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiMODULE_AUTHOR(DRIVER_AUTHOR); 82705a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiMODULE_DESCRIPTION(DRIVER_DESC); 82805a1f28e879e3b4d6a9c08e30b1898943f77b6e7Takahiro HirofuchiMODULE_LICENSE("GPL"); 8296973c6f24e105f1bdf811ec2320d2de8798145eematt mooneyMODULE_VERSION(USBIP_VERSION); 830