blob: 7acec759bf7dd094ff5f9563363b624eb29f8b3b [file] [log] [blame]
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -06001/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#ifndef __VHCI_COMMON_H
21#define __VHCI_COMMON_H
22
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060023#include <linux/version.h>
matt mooney4980d962011-05-06 03:47:45 -070024#include <linux/compiler.h>
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060025#include <linux/usb.h>
26#include <asm/byteorder.h>
27#include <net/sock.h>
28
29/*-------------------------------------------------------------------------*/
30
31/*
32 * define macros to print messages
33 */
34
35/**
Himanshu411a8612010-01-23 17:52:02 +053036 * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060037 * @fmt:
38 * @args:
39 */
Himanshu411a8612010-01-23 17:52:02 +053040#ifdef CONFIG_USB_IP_DEBUG_ENABLE
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060041
Brian G. Merrellb8868e42009-07-21 00:46:13 -060042#define usbip_udbg(fmt, args...) \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060043 do { \
44 printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt, \
matt mooney4980d962011-05-06 03:47:45 -070045 (in_interrupt() ? "interrupt" : (current)->comm),\
46 __FILE__, __LINE__, __func__, ##args); \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060047 } while (0)
48
Himanshu411a8612010-01-23 17:52:02 +053049#else /* CONFIG_USB_IP_DEBUG_ENABLE */
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060050
matt mooney4980d962011-05-06 03:47:45 -070051#define usbip_udbg(fmt, args...) do { } while (0)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060052
Himanshu411a8612010-01-23 17:52:02 +053053#endif /* CONFIG_USB_IP_DEBUG_ENABLE */
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060054
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060055enum {
56 usbip_debug_xmit = (1 << 0),
57 usbip_debug_sysfs = (1 << 1),
58 usbip_debug_urb = (1 << 2),
59 usbip_debug_eh = (1 << 3),
60
61 usbip_debug_stub_cmp = (1 << 8),
62 usbip_debug_stub_dev = (1 << 9),
63 usbip_debug_stub_rx = (1 << 10),
64 usbip_debug_stub_tx = (1 << 11),
65
66 usbip_debug_vhci_rh = (1 << 8),
67 usbip_debug_vhci_hc = (1 << 9),
68 usbip_debug_vhci_rx = (1 << 10),
69 usbip_debug_vhci_tx = (1 << 11),
70 usbip_debug_vhci_sysfs = (1 << 12)
71};
72
Brian G. Merrellb8868e42009-07-21 00:46:13 -060073#define usbip_dbg_flag_xmit (usbip_debug_flag & usbip_debug_xmit)
74#define usbip_dbg_flag_vhci_rh (usbip_debug_flag & usbip_debug_vhci_rh)
75#define usbip_dbg_flag_vhci_hc (usbip_debug_flag & usbip_debug_vhci_hc)
76#define usbip_dbg_flag_vhci_rx (usbip_debug_flag & usbip_debug_vhci_rx)
77#define usbip_dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx)
78#define usbip_dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx)
79#define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx)
80#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060081
82extern unsigned long usbip_debug_flag;
83extern struct device_attribute dev_attr_usbip_debug;
84
Brian G. Merrellb8868e42009-07-21 00:46:13 -060085#define usbip_dbg_with_flag(flag, fmt, args...) \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060086 do { \
87 if (flag & usbip_debug_flag) \
matt mooney4980d962011-05-06 03:47:45 -070088 usbip_udbg(fmt , ##args); \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060089 } while (0)
90
matt mooney4980d962011-05-06 03:47:45 -070091#define usbip_dbg_sysfs(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -060092 usbip_dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -070093#define usbip_dbg_xmit(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -060094 usbip_dbg_with_flag(usbip_debug_xmit, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -070095#define usbip_dbg_urb(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -060096 usbip_dbg_with_flag(usbip_debug_urb, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -070097#define usbip_dbg_eh(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -060098 usbip_dbg_with_flag(usbip_debug_eh, fmt , ##args)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -060099
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600100#define usbip_dbg_vhci_rh(fmt, args...) \
101 usbip_dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
102#define usbip_dbg_vhci_hc(fmt, args...) \
103 usbip_dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
104#define usbip_dbg_vhci_rx(fmt, args...) \
105 usbip_dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
106#define usbip_dbg_vhci_tx(fmt, args...) \
107 usbip_dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -0700108#define usbip_dbg_vhci_sysfs(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600109 usbip_dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600110
matt mooney4980d962011-05-06 03:47:45 -0700111#define usbip_dbg_stub_cmp(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600112 usbip_dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -0700113#define usbip_dbg_stub_rx(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600114 usbip_dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
matt mooney4980d962011-05-06 03:47:45 -0700115#define usbip_dbg_stub_tx(fmt, args...) \
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600116 usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600117
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600118/**
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600119 * usbip_uerr - print error messages
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600120 * @fmt:
121 * @args:
122 */
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600123#define usbip_uerr(fmt, args...) \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600124 do { \
125 printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt, \
matt mooney4980d962011-05-06 03:47:45 -0700126 (in_interrupt() ? "interrupt" : (current)->comm),\
127 __FILE__, __LINE__, __func__, ##args); \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600128 } while (0)
129
130/**
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600131 * usbip_uinfo - print information messages
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600132 * @fmt:
133 * @args:
134 */
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600135#define usbip_uinfo(fmt, args...) \
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600136 do { \
137 printk(KERN_INFO "usbip: " fmt , ## args); \
138 } while (0)
139
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600140/*-------------------------------------------------------------------------*/
141
142/*
143 * USB/IP request headers.
144 * Currently, we define 4 request types:
145 *
146 * - CMD_SUBMIT transfers a USB request, corresponding to usb_submit_urb().
147 * (client to server)
148 * - RET_RETURN transfers the result of CMD_SUBMIT.
149 * (server to client)
150 * - CMD_UNLINK transfers an unlink request of a pending USB request.
151 * (client to server)
152 * - RET_UNLINK transfers the result of CMD_UNLINK.
153 * (server to client)
154 *
155 * Note: The below request formats are based on the USB subsystem of Linux. Its
156 * details will be defined when other implementations come.
157 *
158 *
159 */
160
161/*
162 * A basic header followed by other additional headers.
163 */
164struct usbip_header_basic {
165#define USBIP_CMD_SUBMIT 0x0001
166#define USBIP_CMD_UNLINK 0x0002
167#define USBIP_RET_SUBMIT 0x0003
168#define USBIP_RET_UNLINK 0x0004
169 __u32 command;
170
Uwe Kleine-König65cfe842010-07-01 20:48:45 +0200171 /* sequential number which identifies requests.
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600172 * incremented per connections */
173 __u32 seqnum;
174
175 /* devid is used to specify a remote USB device uniquely instead
176 * of busnum and devnum in Linux. In the case of Linux stub_driver,
177 * this value is ((busnum << 16) | devnum) */
178 __u32 devid;
179
180#define USBIP_DIR_OUT 0
Ruslan Pisarev1bd33022010-03-15 17:00:57 +0200181#define USBIP_DIR_IN 1
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600182 __u32 direction;
183 __u32 ep; /* endpoint number */
matt mooney4980d962011-05-06 03:47:45 -0700184} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600185
186/*
187 * An additional header for a CMD_SUBMIT packet.
188 */
189struct usbip_header_cmd_submit {
190 /* these values are basically the same as in a URB. */
191
192 /* the same in a URB. */
193 __u32 transfer_flags;
194
195 /* set the following data size (out),
196 * or expected reading data size (in) */
197 __s32 transfer_buffer_length;
198
199 /* it is difficult for usbip to sync frames (reserved only?) */
200 __s32 start_frame;
201
202 /* the number of iso descriptors that follows this header */
203 __s32 number_of_packets;
204
205 /* the maximum time within which this request works in a host
206 * controller of a server side */
207 __s32 interval;
208
209 /* set setup packet data for a CTRL request */
210 unsigned char setup[8];
matt mooney4980d962011-05-06 03:47:45 -0700211} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600212
213/*
214 * An additional header for a RET_SUBMIT packet.
215 */
216struct usbip_header_ret_submit {
217 __s32 status;
matt mooney4980d962011-05-06 03:47:45 -0700218 __s32 actual_length; /* returned data length */
219 __s32 start_frame; /* ISO and INT */
220 __s32 number_of_packets; /* ISO only */
221 __s32 error_count; /* ISO only */
222} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600223
224/*
225 * An additional header for a CMD_UNLINK packet.
226 */
227struct usbip_header_cmd_unlink {
matt mooney4980d962011-05-06 03:47:45 -0700228 __u32 seqnum; /* URB's seqnum that will be unlinked */
229} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600230
231/*
232 * An additional header for a RET_UNLINK packet.
233 */
234struct usbip_header_ret_unlink {
235 __s32 status;
matt mooney4980d962011-05-06 03:47:45 -0700236} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600237
238/* the same as usb_iso_packet_descriptor but packed for pdu */
239struct usbip_iso_packet_descriptor {
240 __u32 offset;
matt mooney4980d962011-05-06 03:47:45 -0700241 __u32 length; /* expected length */
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600242 __u32 actual_length;
243 __u32 status;
matt mooney4980d962011-05-06 03:47:45 -0700244} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600245
246/*
247 * All usbip packets use a common header to keep code simple.
248 */
249struct usbip_header {
250 struct usbip_header_basic base;
251
252 union {
253 struct usbip_header_cmd_submit cmd_submit;
254 struct usbip_header_ret_submit ret_submit;
255 struct usbip_header_cmd_unlink cmd_unlink;
256 struct usbip_header_ret_unlink ret_unlink;
257 } u;
matt mooney4980d962011-05-06 03:47:45 -0700258} __packed;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600259
260/*-------------------------------------------------------------------------*/
261
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600262int usbip_xmit(int, struct socket *, char *, int, int);
263int usbip_sendmsg(struct socket *, struct msghdr *, int);
264
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600265static inline int interface_to_busnum(struct usb_interface *interface)
266{
267 struct usb_device *udev = interface_to_usbdev(interface);
268 return udev->bus->busnum;
269}
270
271static inline int interface_to_devnum(struct usb_interface *interface)
272{
273 struct usb_device *udev = interface_to_usbdev(interface);
274 return udev->devnum;
275}
276
277static inline int interface_to_infnum(struct usb_interface *interface)
278{
279 return interface->cur_altsetting->desc.bInterfaceNumber;
280}
281
282#if 0
283int setnodelay(struct socket *);
284int setquickack(struct socket *);
285int setkeepalive(struct socket *socket);
286void setreuse(struct socket *);
287#endif
288
289struct socket *sockfd_to_socket(unsigned int);
290int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
291
292void usbip_dump_urb(struct urb *purb);
293void usbip_dump_header(struct usbip_header *pdu);
294
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600295struct usbip_device;
296
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600297enum usbip_side {
298 USBIP_VHCI,
299 USBIP_STUB,
300};
301
302enum usbip_status {
303 /* sdev is available. */
304 SDEV_ST_AVAILABLE = 0x01,
305 /* sdev is now used. */
306 SDEV_ST_USED,
307 /* sdev is unusable because of a fatal error. */
308 SDEV_ST_ERROR,
309
310 /* vdev does not connect a remote device. */
311 VDEV_ST_NULL,
312 /* vdev is used, but the USB address is not assigned yet */
313 VDEV_ST_NOTASSIGNED,
314 VDEV_ST_USED,
315 VDEV_ST_ERROR
316};
317
318/* a common structure for stub_device and vhci_device */
319struct usbip_device {
320 enum usbip_side side;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600321 enum usbip_status status;
322
323 /* lock for status */
324 spinlock_t lock;
325
326 struct socket *tcp_socket;
327
Arnd Bergmann9720b4b2011-03-02 00:13:05 +0100328 struct task_struct *tcp_rx;
329 struct task_struct *tcp_tx;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600330
331 /* event handler */
332#define USBIP_EH_SHUTDOWN (1 << 0)
333#define USBIP_EH_BYE (1 << 1)
334#define USBIP_EH_RESET (1 << 2)
335#define USBIP_EH_UNUSABLE (1 << 3)
336
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600337#define SDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600338#define SDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
339#define SDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
340#define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
341#define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
342
343#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
344#define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
345#define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
346#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
347
348 unsigned long event;
Arnd Bergmann9720b4b2011-03-02 00:13:05 +0100349 struct task_struct *eh;
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600350 wait_queue_head_t eh_waitq;
351
352 struct eh_ops {
353 void (*shutdown)(struct usbip_device *);
354 void (*reset)(struct usbip_device *);
355 void (*unusable)(struct usbip_device *);
356 } eh_ops;
357};
358
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600359void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
matt mooney4980d962011-05-06 03:47:45 -0700360 int pack);
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600361
362void usbip_header_correct_endian(struct usbip_header *pdu, int send);
363/* some members of urb must be substituted before. */
364int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
365/* some members of urb must be substituted before. */
366int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
Arjan Mels28276a22011-04-05 20:26:59 +0200367/* some members of urb must be substituted before. */
368int usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600369void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
370
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600371/* usbip_event.c */
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600372int usbip_start_eh(struct usbip_device *ud);
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600373void usbip_stop_eh(struct usbip_device *ud);
374void usbip_event_add(struct usbip_device *ud, unsigned long event);
Brian G. Merrellb8868e42009-07-21 00:46:13 -0600375int usbip_event_happened(struct usbip_device *ud);
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600376
Takahiro Hirofuchi05a1f282008-07-09 14:56:51 -0600377#endif