1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
===============
USB/IP protocol
===============
Architecture
============
The USB/IP protocol follows a server/client architecture. The server exports the
USB devices and the clients import them. The device driver for the exported
USB device runs on the client machine.
The client may ask for the list of the exported USB devices. To get the list the
client opens a TCP/IP connection to the server, and sends an OP_REQ_DEVLIST
packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent
in one or more pieces at the low level transport layer). The server sends back
the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the
TCP/IP connection is closed.
::
virtual host controller usb host
"client" "server"
(imports USB devices) (exports USB devices)
| |
| OP_REQ_DEVLIST |
| ----------------------------------------------> |
| |
| OP_REP_DEVLIST |
| <---------------------------------------------- |
| |
Once the client knows the list of exported USB devices it may decide to use one
of them. First the client opens a TCP/IP connection to the server and
sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the
import was successful the TCP/IP connection remains open and will be used
to transfer the URB traffic between the client and the server. The client may
send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and
USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the
server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively.
::
virtual host controller usb host
"client" "server"
(imports USB devices) (exports USB devices)
| |
| OP_REQ_IMPORT |
| ----------------------------------------------> |
| |
| OP_REP_IMPORT |
| <---------------------------------------------- |
| |
| |
| USBIP_CMD_SUBMIT(seqnum = n) |
| ----------------------------------------------> |
| |
| USBIP_RET_SUBMIT(seqnum = n) |
| <---------------------------------------------- |
| . |
| : |
| |
| USBIP_CMD_SUBMIT(seqnum = m) |
| ----------------------------------------------> |
| |
| USBIP_CMD_SUBMIT(seqnum = m+1) |
| ----------------------------------------------> |
| |
| USBIP_CMD_SUBMIT(seqnum = m+2) |
| ----------------------------------------------> |
| |
| USBIP_RET_SUBMIT(seqnum = m) |
| <---------------------------------------------- |
| |
| USBIP_CMD_SUBMIT(seqnum = m+3) |
| ----------------------------------------------> |
| |
| USBIP_RET_SUBMIT(seqnum = m+1) |
| <---------------------------------------------- |
| |
| USBIP_CMD_SUBMIT(seqnum = m+4) |
| ----------------------------------------------> |
| |
| USBIP_RET_SUBMIT(seqnum = m+2) |
| <---------------------------------------------- |
| . |
| : |
For UNLINK, note that after a successful USBIP_RET_UNLINK, the unlinked URB
submission would not have a corresponding USBIP_RET_SUBMIT (this is explained in
function stub_recv_cmd_unlink of drivers/usb/usbip/stub_rx.c).
::
virtual host controller usb host
"client" "server"
(imports USB devices) (exports USB devices)
| |
| USBIP_CMD_SUBMIT(seqnum = p) |
| ----------------------------------------------> |
| |
| USBIP_CMD_UNLINK |
| (seqnum = p+1, unlink_seqnum = p) |
| ----------------------------------------------> |
| |
| USBIP_RET_UNLINK |
| (seqnum = p+1, status = -ECONNRESET) |
| <---------------------------------------------- |
| |
| Note: No USBIP_RET_SUBMIT(seqnum = p) |
| <--X---X---X---X---X---X---X---X---X---X---X--- |
| . |
| : |
| |
| USBIP_CMD_SUBMIT(seqnum = q) |
| ----------------------------------------------> |
| |
| USBIP_RET_SUBMIT(seqnum = q) |
| <---------------------------------------------- |
| |
| USBIP_CMD_UNLINK |
| (seqnum = q+1, unlink_seqnum = q) |
| ----------------------------------------------> |
| |
| USBIP_RET_UNLINK |
| (seqnum = q+1, status = 0) |
| <---------------------------------------------- |
| |
The fields are in network (big endian) byte order meaning that the most significant
byte (MSB) is stored at the lowest address.
Protocol Version
================
The documented USBIP version is v1.1.1. The binary representation of this
version in message headers is 0x0111.
This is defined in tools/usb/usbip/configure.ac
Message Format
==============
OP_REQ_DEVLIST:
Retrieve the list of exported USB devices.
+-----------+--------+------------+---------------------------------------------------+
| Offset | Length | Value | Description |
+===========+========+============+===================================================+
| 0 | 2 | | USBIP version |
+-----------+--------+------------+---------------------------------------------------+
| 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB |
| | | | devices. |
+-----------+--------+------------+---------------------------------------------------+
| 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 |
+-----------+--------+------------+---------------------------------------------------+
OP_REP_DEVLIST:
Reply with the list of exported USB devices.
+-----------+--------+------------+---------------------------------------------------+
| Offset | Length | Value | Description |
+===========+========+============+===================================================+
| 0 | 2 | | USBIP version |
+-----------+--------+------------+---------------------------------------------------+
| 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. |
+-----------+--------+------------+---------------------------------------------------+
| 4 | 4 | 0x00000000 | Status: 0 for OK |
+-----------+--------+------------+---------------------------------------------------+
| 8 | 4 | n | Number of exported devices: 0 means no exported |
| | | | devices. |
+-----------+--------+------------+---------------------------------------------------+
| 0x0C | | | From now on the exported n devices are described, |
| | | | if any. If no devices are exported the message |
| | | | ends with the previous "number of exported |
| | | | devices" field. |
+-----------+--------+------------+---------------------------------------------------+
| | 256 | | path: Path of the device on the host exporting the|
| | | | USB device, string closed with zero byte, e.g. |
| | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" |
| | | | The unused bytes shall be filled with zero |
| | | | bytes. |
+-----------+--------+------------+---------------------------------------------------+
| 0x10C | 32 | | busid: Bus ID of the exported device, string |
| | | | closed with zero byte, e.g. "3-2". The unused |
| | | | bytes shall be filled with zero bytes. |
+-----------+--------+------------+---------------------------------------------------+
| 0x12C | 4 | | busnum |
+-----------+--------+------------+---------------------------------------------------+
| 0x130 | 4 | | devnum |
+-----------+--------+------------+---------------------------------------------------+
| 0x134 | 4 | | speed |
+-----------+--------+------------+---------------------------------------------------+
| 0x138 | 2 | | idVendor |
+-----------+--------+------------+---------------------------------------------------+
| 0x13A | 2 | | idProduct |
+-----------+--------+------------+---------------------------------------------------+
| 0x13C | 2 | | bcdDevice |
+-----------+--------+------------+---------------------------------------------------+
| 0x13E | 1 | | bDeviceClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x13F | 1 | | bDeviceSubClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x140 | 1 | | bDeviceProtocol |
+-----------+--------+------------+---------------------------------------------------+
| 0x141 | 1 | | bConfigurationValue |
+-----------+--------+------------+---------------------------------------------------+
| 0x142 | 1 | | bNumConfigurations |
+-----------+--------+------------+---------------------------------------------------+
| 0x143 | 1 | | bNumInterfaces |
+-----------+--------+------------+---------------------------------------------------+
| 0x144 | | m_0 | From now on each interface is described, all |
| | | | together bNumInterfaces times, with the following |
| | | | 4 fields: |
+-----------+--------+------------+---------------------------------------------------+
| | 1 | | bInterfaceClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x145 | 1 | | bInterfaceSubClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x146 | 1 | | bInterfaceProtocol |
+-----------+--------+------------+---------------------------------------------------+
| 0x147 | 1 | | padding byte for alignment, shall be set to zero |
+-----------+--------+------------+---------------------------------------------------+
| 0xC + | | | The second exported USB device starts at i=1 |
| i*0x138 + | | | with the path field. |
| m_(i-1)*4 | | | |
+-----------+--------+------------+---------------------------------------------------+
OP_REQ_IMPORT:
Request to import (attach) a remote USB device.
+-----------+--------+------------+---------------------------------------------------+
| Offset | Length | Value | Description |
+===========+========+============+===================================================+
| 0 | 2 | | USBIP version |
+-----------+--------+------------+---------------------------------------------------+
| 2 | 2 | 0x8003 | Command code: import a remote USB device. |
+-----------+--------+------------+---------------------------------------------------+
| 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 |
+-----------+--------+------------+---------------------------------------------------+
| 8 | 32 | | busid: the busid of the exported device on the |
| | | | remote host. The possible values are taken |
| | | | from the message field OP_REP_DEVLIST.busid. |
| | | | A string closed with zero, the unused bytes |
| | | | shall be filled with zeros. |
+-----------+--------+------------+---------------------------------------------------+
OP_REP_IMPORT:
Reply to import (attach) a remote USB device.
+-----------+--------+------------+---------------------------------------------------+
| Offset | Length | Value | Description |
+===========+========+============+===================================================+
| 0 | 2 | | USBIP version |
+-----------+--------+------------+---------------------------------------------------+
| 2 | 2 | 0x0003 | Reply code: Reply to import. |
+-----------+--------+------------+---------------------------------------------------+
| 4 | 4 | 0x00000000 | Status: |
| | | | |
| | | | - 0 for OK |
| | | | - 1 for error |
+-----------+--------+------------+---------------------------------------------------+
| 8 | | | From now on comes the details of the imported |
| | | | device, if the previous status field was OK (0), |
| | | | otherwise the reply ends with the status field. |
+-----------+--------+------------+---------------------------------------------------+
| | 256 | | path: Path of the device on the host exporting the|
| | | | USB device, string closed with zero byte, e.g. |
| | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" |
| | | | The unused bytes shall be filled with zero |
| | | | bytes. |
+-----------+--------+------------+---------------------------------------------------+
| 0x108 | 32 | | busid: Bus ID of the exported device, string |
| | | | closed with zero byte, e.g. "3-2". The unused |
| | | | bytes shall be filled with zero bytes. |
+-----------+--------+------------+---------------------------------------------------+
| 0x128 | 4 | | busnum |
+-----------+--------+------------+---------------------------------------------------+
| 0x12C | 4 | | devnum |
+-----------+--------+------------+---------------------------------------------------+
| 0x130 | 4 | | speed |
+-----------+--------+------------+---------------------------------------------------+
| 0x134 | 2 | | idVendor |
+-----------+--------+------------+---------------------------------------------------+
| 0x136 | 2 | | idProduct |
+-----------+--------+------------+---------------------------------------------------+
| 0x138 | 2 | | bcdDevice |
+-----------+--------+------------+---------------------------------------------------+
| 0x139 | 1 | | bDeviceClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x13A | 1 | | bDeviceSubClass |
+-----------+--------+------------+---------------------------------------------------+
| 0x13B | 1 | | bDeviceProtocol |
+-----------+--------+------------+---------------------------------------------------+
| 0x13C | 1 | | bConfigurationValue |
+-----------+--------+------------+---------------------------------------------------+
| 0x13D | 1 | | bNumConfigurations |
+-----------+--------+------------+---------------------------------------------------+
| 0x13E | 1 | | bNumInterfaces |
+-----------+--------+------------+---------------------------------------------------+
The following four commands have a common basic header called
'usbip_header_basic', and their headers, called 'usbip_header' (before
transfer_buffer payload), have the same length, therefore paddings are needed.
usbip_header_basic:
+-----------+--------+---------------------------------------------------+
| Offset | Length | Description |
+===========+========+===================================================+
| 0 | 4 | command |
+-----------+--------+---------------------------------------------------+
| 4 | 4 | seqnum: sequential number that identifies requests|
| | | and corresponding responses; |
| | | incremented per connection |
+-----------+--------+---------------------------------------------------+
| 8 | 4 | devid: specifies a remote USB device uniquely |
| | | instead of busnum and devnum; |
| | | for client (request), this value is |
| | | ((busnum << 16) | devnum); |
| | | for server (response), this shall be set to 0 |
+-----------+--------+---------------------------------------------------+
| 0xC | 4 | direction: |
| | | |
| | | - 0: USBIP_DIR_OUT |
| | | - 1: USBIP_DIR_IN |
| | | |
| | | only used by client, for server this shall be 0 |
+-----------+--------+---------------------------------------------------+
| 0x10 | 4 | ep: endpoint number |
| | | only used by client, for server this shall be 0; |
| | | for UNLINK, this shall be 0 |
+-----------+--------+---------------------------------------------------+
USBIP_CMD_SUBMIT:
Submit an URB
+-----------+--------+---------------------------------------------------+
| Offset | Length | Description |
+===========+========+===================================================+
| 0 | 20 | usbip_header_basic, 'command' shall be 0x00000001 |
+-----------+--------+---------------------------------------------------+
| 0x14 | 4 | transfer_flags: possible values depend on the |
| | | USBIP_URB transfer_flags. |
| | | Refer to include/uapi/linux/usbip.h and |
| | | Documentation/driver-api/usb/URB.rst. |
| | | Refer to usbip_pack_cmd_submit() and |
| | | tweak_transfer_flags() in drivers/usb/usbip/ |
| | | usbip_common.c. |
+-----------+--------+---------------------------------------------------+
| 0x18 | 4 | transfer_buffer_length: |
| | | use URB transfer_buffer_length |
+-----------+--------+---------------------------------------------------+
| 0x1C | 4 | start_frame: use URB start_frame; |
| | | initial frame for ISO transfer; |
| | | shall be set to 0 if not ISO transfer |
+-----------+--------+---------------------------------------------------+
| 0x20 | 4 | number_of_packets: number of ISO packets; |
| | | shall be set to 0xffffffff if not ISO transfer |
+-----------+--------+---------------------------------------------------+
| 0x24 | 4 | interval: maximum time for the request on the |
| | | server-side host controller |
+-----------+--------+---------------------------------------------------+
| 0x28 | 8 | setup: data bytes for USB setup, filled with |
| | | zeros if not used. |
+-----------+--------+---------------------------------------------------+
| 0x30 | n | transfer_buffer. |
| | | If direction is USBIP_DIR_OUT then n equals |
| | | transfer_buffer_length; otherwise n equals 0. |
| | | For ISO transfers the padding between each ISO |
| | | packets is not transmitted. |
+-----------+--------+---------------------------------------------------+
| 0x30+n | m | iso_packet_descriptor |
+-----------+--------+---------------------------------------------------+
USBIP_RET_SUBMIT:
Reply for submitting an URB
+-----------+--------+---------------------------------------------------+
| Offset | Length | Description |
+===========+========+===================================================+
| 0 | 20 | usbip_header_basic, 'command' shall be 0x00000003 |
+-----------+--------+---------------------------------------------------+
| 0x14 | 4 | status: zero for successful URB transaction, |
| | | otherwise some kind of error happened. |
+-----------+--------+---------------------------------------------------+
| 0x18 | 4 | actual_length: number of URB data bytes; |
| | | use URB actual_length |
+-----------+--------+---------------------------------------------------+
| 0x1C | 4 | start_frame: use URB start_frame; |
| | | initial frame for ISO transfer; |
| | | shall be set to 0 if not ISO transfer |
+-----------+--------+---------------------------------------------------+
| 0x20 | 4 | number_of_packets: number of ISO packets; |
| | | shall be set to 0xffffffff if not ISO transfer |
+-----------+--------+---------------------------------------------------+
| 0x24 | 4 | error_count |
+-----------+--------+---------------------------------------------------+
| 0x28 | 8 | padding, shall be set to 0 |
+-----------+--------+---------------------------------------------------+
| 0x30 | n | transfer_buffer. |
| | | If direction is USBIP_DIR_IN then n equals |
| | | actual_length; otherwise n equals 0. |
| | | For ISO transfers the padding between each ISO |
| | | packets is not transmitted. |
+-----------+--------+---------------------------------------------------+
| 0x30+n | m | iso_packet_descriptor |
+-----------+--------+---------------------------------------------------+
USBIP_CMD_UNLINK:
Unlink an URB
+-----------+--------+---------------------------------------------------+
| Offset | Length | Description |
+===========+========+===================================================+
| 0 | 20 | usbip_header_basic, 'command' shall be 0x00000002 |
+-----------+--------+---------------------------------------------------+
| 0x14 | 4 | unlink_seqnum, of the SUBMIT request to unlink |
+-----------+--------+---------------------------------------------------+
| 0x18 | 24 | padding, shall be set to 0 |
+-----------+--------+---------------------------------------------------+
USBIP_RET_UNLINK:
Reply for URB unlink
+-----------+--------+---------------------------------------------------+
| Offset | Length | Description |
+===========+========+===================================================+
| 0 | 20 | usbip_header_basic, 'command' shall be 0x00000004 |
+-----------+--------+---------------------------------------------------+
| 0x14 | 4 | status: This is similar to the status of |
| | | USBIP_RET_SUBMIT (share the same memory offset). |
| | | When UNLINK is successful, status is -ECONNRESET; |
| | | when USBIP_CMD_UNLINK is after USBIP_RET_SUBMIT |
| | | status is 0 |
+-----------+--------+---------------------------------------------------+
| 0x18 | 24 | padding, shall be set to 0 |
+-----------+--------+---------------------------------------------------+
EXAMPLE
=======
The following data is captured from wire with Human Interface Devices (HID)
payload
::
CmdIntrIN: 00000001 00000d05 0001000f 00000001 00000001 00000200 00000040 ffffffff 00000000 00000004 00000000 00000000
CmdIntrOUT: 00000001 00000d06 0001000f 00000000 00000001 00000000 00000040 ffffffff 00000000 00000004 00000000 00000000
ffffffff860008a784ce5ae212376300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
RetIntrOut: 00000003 00000d06 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
RetIntrIn: 00000003 00000d05 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
ffffffff860011a784ce5ae2123763612891b1020100000400000000000000000000000000000000000000000000000000000000000000000000000000000000
|