Documentation / usb / usbip_protocol.rst


Based on kernel version 6.8. Page generated on 2024-03-11 21:26 EST.

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