github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/sys/netbsd/vusb.txt (about)

     1  # Copyright 2019 syzkaller project authors. All rights reserved.
     2  # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  # General redefinitions, taken from the Linux headers.
     5  
     6  # ch9.h
     7  define USB_DIR_OUT	0
     8  define USB_DIR_IN	0x80
     9  define USB_TYPE_MASK	(0x03 << 5)
    10  define USB_TYPE_STANDARD	(0x00 << 5)
    11  define USB_TYPE_CLASS	(0x01 << 5)
    12  define USB_TYPE_VENDOR	(0x02 << 5)
    13  define USB_TYPE_RESERVED	(0x03 << 5)
    14  define USB_DT_DEVICE	0x01
    15  define USB_DT_CONFIG	0x02
    16  define USB_DT_STRING	0x03
    17  define USB_DT_INTERFACE	0x04
    18  define USB_DT_ENDPOINT	0x05
    19  define USB_DT_DEVICE_QUALIFIER	0x06
    20  define USB_DT_OTHER_SPEED_CONFIG	0x07
    21  define USB_DT_INTERFACE_POWER	0x08
    22  define USB_DT_OTG	0x09
    23  define USB_DT_DEBUG	0x0a
    24  define USB_DT_INTERFACE_ASSOCIATION	0x0b
    25  define USB_DT_SECURITY	0x0c
    26  define USB_DT_KEY	0x0d
    27  define USB_DT_ENCRYPTION_TYPE	0x0e
    28  define USB_DT_BOS	0x0f
    29  define USB_DT_DEVICE_CAPABILITY	0x10
    30  define USB_DT_WIRELESS_ENDPOINT_COMP	0x11
    31  define USB_DT_WIRE_ADAPTER	0x21
    32  define USB_DT_RPIPE	0x22
    33  define USB_DT_CS_RADIO_CONTROL	0x23
    34  define USB_DT_PIPE_USAGE	0x24
    35  define USB_DT_SS_ENDPOINT_COMP	0x30
    36  define USB_DT_SSP_ISOC_ENDPOINT_COMP	0x31
    37  define USB_DT_CS_DEVICE	(USB_TYPE_CLASS | USB_DT_DEVICE)
    38  define USB_DT_CS_CONFIG	(USB_TYPE_CLASS | USB_DT_CONFIG)
    39  define USB_DT_CS_STRING	(USB_TYPE_CLASS | USB_DT_STRING)
    40  define USB_DT_CS_INTERFACE	(USB_TYPE_CLASS | USB_DT_INTERFACE)
    41  define USB_DT_CS_ENDPOINT	(USB_TYPE_CLASS | USB_DT_ENDPOINT)
    42  define USB_CLASS_PER_INTERFACE	0
    43  define USB_CLASS_AUDIO	1
    44  define USB_CLASS_COMM	2
    45  define USB_CLASS_HID	3
    46  define USB_CLASS_PHYSICAL	5
    47  define USB_CLASS_STILL_IMAGE	6
    48  define USB_CLASS_PRINTER	7
    49  define USB_CLASS_MASS_STORAGE	8
    50  define USB_CLASS_HUB	9
    51  define USB_CLASS_CDC_DATA	0x0a
    52  define USB_CLASS_CSCID	0x0b
    53  define USB_CLASS_CONTENT_SEC	0x0d
    54  define USB_CLASS_VIDEO	0x0e
    55  define USB_CLASS_WIRELESS_CONTROLLER	0xe0
    56  define USB_CLASS_MISC	0xef
    57  define USB_CLASS_APP_SPEC	0xfe
    58  define USB_CLASS_VENDOR_SPEC	0xff
    59  define USB_SUBCLASS_VENDOR_SPEC	0xff
    60  define USB_ENDPOINT_NUMBER_MASK	0x0f
    61  define USB_ENDPOINT_DIR_MASK	0x80
    62  define USB_ENDPOINT_XFERTYPE_MASK	0x03
    63  define USB_ENDPOINT_XFER_CONTROL	0
    64  define USB_ENDPOINT_XFER_ISOC	1
    65  define USB_ENDPOINT_XFER_BULK	2
    66  define USB_ENDPOINT_XFER_INT	3
    67  define USB_ENDPOINT_MAX_ADJUSTABLE	0x80
    68  define USB_ENDPOINT_MAXP_MASK	0x07ff
    69  define USB_EP_MAXP_MULT_SHIFT	11
    70  define USB_EP_MAXP_MULT_MASK	(3 << USB_EP_MAXP_MULT_SHIFT)
    71  define USB_ENDPOINT_INTRTYPE	0x30
    72  define USB_ENDPOINT_INTR_PERIODIC	(0 << 4)
    73  define USB_ENDPOINT_INTR_NOTIFICATION	(1 << 4)
    74  define USB_ENDPOINT_SYNCTYPE	0x0c
    75  define USB_ENDPOINT_SYNC_NONE	(0 << 2)
    76  define USB_ENDPOINT_SYNC_ASYNC	(1 << 2)
    77  define USB_ENDPOINT_SYNC_ADAPTIVE	(2 << 2)
    78  define USB_ENDPOINT_SYNC_SYNC	(3 << 2)
    79  define USB_ENDPOINT_USAGE_MASK	0x30
    80  define USB_ENDPOINT_USAGE_DATA	0x00
    81  define USB_ENDPOINT_USAGE_FEEDBACK	0x10
    82  define USB_ENDPOINT_USAGE_IMPLICIT_FB	0x20
    83  
    84  # hid.h
    85  define USB_INTERFACE_CLASS_HID	3
    86  define USB_INTERFACE_SUBCLASS_BOOT	1
    87  define USB_INTERFACE_PROTOCOL_KEYBOARD	1
    88  define USB_INTERFACE_PROTOCOL_MOUSE	2
    89  define HID_REQ_GET_REPORT	0x01
    90  define HID_REQ_GET_IDLE	0x02
    91  define HID_REQ_GET_PROTOCOL	0x03
    92  define HID_REQ_SET_REPORT	0x09
    93  define HID_REQ_SET_IDLE	0x0A
    94  define HID_REQ_SET_PROTOCOL	0x0B
    95  define HID_DT_HID	(USB_TYPE_CLASS | 0x01)
    96  define HID_DT_REPORT	(USB_TYPE_CLASS | 0x02)
    97  define HID_DT_PHYSICAL	(USB_TYPE_CLASS | 0x03)
    98  define HID_MAX_DESCRIPTOR_SIZE	4096
    99  
   100  # cdc.h
   101  define USB_CDC_HEADER_TYPE	0x00
   102  define USB_CDC_CALL_MANAGEMENT_TYPE	0x01
   103  define USB_CDC_ACM_TYPE	0x02
   104  define USB_CDC_UNION_TYPE	0x06
   105  define USB_CDC_COUNTRY_TYPE	0x07
   106  define USB_CDC_NETWORK_TERMINAL_TYPE	0x0a
   107  define USB_CDC_ETHERNET_TYPE	0x0f
   108  define USB_CDC_WHCM_TYPE	0x11
   109  define USB_CDC_MDLM_TYPE	0x12
   110  define USB_CDC_MDLM_DETAIL_TYPE	0x13
   111  define USB_CDC_DMM_TYPE	0x14
   112  define USB_CDC_OBEX_TYPE	0x15
   113  define USB_CDC_NCM_TYPE	0x1a
   114  define USB_CDC_MBIM_TYPE	0x1b
   115  define USB_CDC_MBIM_EXTENDED_TYPE	0x1c
   116  define USB_CDC_PROTO_NONE	0
   117  
   118  # ------------------------------------------------------------------------------
   119  
   120  # This is a special fd for USB fuzzing and should only be used with syz_usb_* pseudo-syscalls.
   121  # We don't inherit it from the fd resource, to discourage syzkaller calling raw ioctls on it.
   122  resource fd_usb[int32]: -1
   123  
   124  # These are generic pseudo-syscalls for emulating arbitrary USB devices.
   125  # They are mostly targeted to cover the enumeration process.
   126  syz_usb_connect(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb (timeout[3000], prog_timeout[3000])
   127  syz_usb_disconnect(fd fd_usb) (timeout[300])
   128  
   129  define USB_SPEED_UNKNOWN	1
   130  define USB_SPEED_LOW	2
   131  define USB_SPEED_FULL	3
   132  define USB_SPEED_HIGH	4
   133  define USB_SPEED_WIRELESS	5
   134  define USB_SPEED_SUPER	6
   135  define USB_SPEED_SUPER_PLUS	7
   136  usb_device_speed = USB_SPEED_UNKNOWN, USB_SPEED_LOW, USB_SPEED_FULL, USB_SPEED_HIGH, USB_SPEED_WIRELESS, USB_SPEED_SUPER, USB_SPEED_SUPER_PLUS
   137  
   138  # TODO: consider patching idVendor and idProduct for all class specific descriptions in Go code to cover more drivers.
   139  # TODO: custom syz_usb_ep_write() descriptions for all class specific descriptions.
   140  # TODO: consider adding custom vusb_connect_descriptors definitions to all class specific descriptions.
   141  
   142  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   143  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   144  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   145  
   146  define USB_DT_DEVICE_SIZE	18
   147  type usb_device_descriptor_verbose_t[USB, CLASS, SUBCLASS, PROTOCOL, PACKET, VENDOR, PRODUCT, DEVICE, CFS] {
   148  	bLength			const[USB_DT_DEVICE_SIZE, int8]
   149  	bDescriptorType		const[USB_DT_DEVICE, int8]
   150  
   151  	bcdUSB			USB
   152  	bDeviceClass		const[CLASS, int8]
   153  	bDeviceSubClass		const[SUBCLASS, int8]
   154  	bDeviceProtocol		const[PROTOCOL, int8]
   155  	bMaxPacketSize0		PACKET
   156  	idVendor		const[VENDOR, int16]
   157  	idProduct		const[PRODUCT, int16]
   158  	bcdDevice		const[DEVICE, int16]
   159  	iManufacturer		const[1, int8]
   160  	iProduct		const[2, int8]
   161  	iSerialNumber		const[3, int8]
   162  	bNumConfigurations	len[configs, int8]
   163  
   164  	configs			CFS
   165  } [packed]
   166  
   167  type usb_device_descriptor_t[CLASS, SUBCLASS, PROTOCOL, VENDOR, PRODUCT, DEVICE, CFS] usb_device_descriptor_verbose_t[flags[usb_versions, int16], CLASS, SUBCLASS, PROTOCOL, flags[usb_device_max_packet_sizes, int8], VENDOR, PRODUCT, DEVICE, CFS]
   168  
   169  usb_versions = 0x110, 0x200, 0x201, 0x250, 0x300, 0x310
   170  
   171  # https://elixir.bootlin.com/linux/v5.1.7/source/drivers/usb/core/hub.c#L4661
   172  usb_device_max_packet_sizes = 8, 16, 32, 64, 255
   173  
   174  define USB_DT_CONFIG_SIZE	9
   175  type usb_config_descriptor_verbose_t[NUM, IFSNUM, ICONFIG, ATTRS, POWER, IFS] {
   176  	bLength			const[USB_DT_CONFIG_SIZE, int8]
   177  	bDescriptorType		const[USB_DT_CONFIG, int8]
   178  
   179  	wTotalLength		len[parent, int16]
   180  	bNumInterfaces		IFSNUM
   181  	bConfigurationValue	NUM
   182  	iConfiguration		ICONFIG
   183  	bmAttributes		ATTRS
   184  	bMaxPower		POWER
   185  
   186  	interfaces		IFS
   187  } [packed]
   188  
   189  type usb_config_descriptor_t[NUM, IFSNUM, IFS] usb_config_descriptor_verbose_t[NUM, IFSNUM, int8, flags[usb_config_attributes, int8], int8, IFS]
   190  type usb_config_descriptor_ifaces_array_t[NUM, IFS] usb_config_descriptor_t[NUM, len[interfaces, int8], IFS]
   191  
   192  define USB_DT_INTERFACE_SIZE	9
   193  type usb_interface_descriptor_verbose_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, IIF, EXTRA, EPS] {
   194  	bLength			const[USB_DT_INTERFACE_SIZE, int8]
   195  	bDescriptorType		const[USB_DT_INTERFACE, int8]
   196  
   197  	bInterfaceNumber	IFNUM
   198  	bAlternateSetting	ALTNUM
   199  	bNumEndpoints		EPSNUM
   200  	bInterfaceClass		CLASS
   201  	bInterfaceSubClass	SUBCLASS
   202  	bInterfaceProtocol	PROTOCOL
   203  	iInterface		IIF
   204  
   205  	extra			EXTRA
   206  	endpoints		EPS
   207  } [packed]
   208  
   209  type usb_interface_descriptor_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_verbose_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, int8, EXTRA, EPS]
   210  type usb_interface_descriptor_eps_array_t[IFNUM, ALTNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_t[IFNUM, ALTNUM, len[endpoints, int8], CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS]
   211  type usb_interface_descriptor_fixed_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_verbose_t[const[IFNUM, int8], const[ALTNUM, int8], const[EPSNUM, int8], const[CLASS, int8], const[SUBCLASS, int8], const[PROTOCOL, int8], const[0, int8], EXTRA, EPS]
   212  
   213  # TODO: non-audio endpoints have USB_DT_ENDPOINT_SIZE.
   214  define USB_DT_ENDPOINT_AUDIO_SIZE	9
   215  type usb_endpoint_descriptor_verbose_t[ADDR, ATTRS, PACKET, INTERVAL, REFRESH, SYNCH, EXTRA] {
   216  	bLength			const[USB_DT_ENDPOINT_AUDIO_SIZE, int8]
   217  	bDescriptorType		const[USB_DT_ENDPOINT, int8]
   218  
   219  	bEndpointAddress	ADDR
   220  	bmAttributes		ATTRS
   221  	wMaxPacketSize		PACKET
   222  	bInterval		INTERVAL
   223  
   224  	bRefresh		REFRESH
   225  	bSynchAddress		SYNCH
   226  
   227  	extra			EXTRA
   228  } [packed]
   229  
   230  type usb_endpoint_descriptor_t[ADDR, ATTRS, EXTRA] usb_endpoint_descriptor_verbose_t[ADDR, ATTRS, flags[usb_endpoint_max_packet_sizes, int16], int8, int8, int8, EXTRA]
   231  
   232  # TODO: dummy driver has complex requirements for packet sizes, account for those:
   233  # https://elixir.bootlin.com/linux/v5.3.6/source/drivers/usb/gadget/udc/dummy_hcd.c#L497
   234  usb_endpoint_max_packet_sizes = 8, 16, 32, 64, 512, 1023, 1024
   235  
   236  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   237  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   238  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   239  
   240  # Generic USB device, configuration, interface and endpoint descriptors.
   241  
   242  # We only support one configuration per device.
   243  # bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct
   244  # and bcdDevice are patched by Go code, see sys/linux/init_vusb.go.
   245  usb_device_descriptor {
   246  	inner	usb_device_descriptor_t[0, 0, 0, 0, 0, 0, array[usb_config_descriptor, 1]]
   247  } [packed]
   248  
   249  usb_config_descriptor {
   250  	inner	usb_config_descriptor_ifaces_array_t[int8, array[usb_interface_descriptor, 1:4]]
   251  } [packed]
   252  
   253  define USB_CONFIG_ATT_ONE	(1 << 7)
   254  define USB_CONFIG_ATT_SELFPOWER	(1 << 6)
   255  define USB_CONFIG_ATT_WAKEUP	(1 << 5)
   256  define USB_CONFIG_ATT_BATTERY	(1 << 4)
   257  usb_config_attributes = USB_CONFIG_ATT_ONE, USB_CONFIG_ATT_SELFPOWER, USB_CONFIG_ATT_WAKEUP, USB_CONFIG_ATT_BATTERY
   258  
   259  # bInterfaceNumber, bInterfaceClass, bInterfaceSubClass and bInterfaceProtocol
   260  # are patched by Go code, see sys/linux/init_vusb.go.
   261  usb_interface_descriptor {
   262  	inner	usb_interface_descriptor_eps_array_t[int8, int8, const[0, int8], const[0, int8], const[0, int8], array[usb_interface_extra_descriptor, 0:2], array[usb_endpoint_descriptor, 0:16]]
   263  } [packed]
   264  
   265  usb_endpoint_descriptor {
   266  	inner	usb_endpoint_descriptor_t[flags[usb_endpoint_addresses, int8], flags[usb_endpoint_attributes, int8], array[usb_endpoint_extra_descriptor, 0:2]]
   267  } [packed]
   268  
   269  usb_endpoint_addresses = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, USB_DIR_OUT, USB_DIR_IN
   270  
   271  usb_endpoint_attributes = USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_ISOC, USB_ENDPOINT_XFER_BULK, USB_ENDPOINT_XFER_INT, USB_ENDPOINT_INTR_PERIODIC, USB_ENDPOINT_INTR_NOTIFICATION, USB_ENDPOINT_SYNC_NONE, USB_ENDPOINT_SYNC_ASYNC, USB_ENDPOINT_SYNC_ADAPTIVE, USB_ENDPOINT_SYNC_SYNC, USB_ENDPOINT_USAGE_DATA, USB_ENDPOINT_USAGE_FEEDBACK, USB_ENDPOINT_USAGE_FEEDBACK
   272  
   273  vusb_connect_descriptors {
   274  	qual_len	len[qual, int32]
   275  	qual		ptr[in, usb_qualifier_descriptor]
   276  	bos_len		len[bos, int32]
   277  	bos		ptr[in, usb_bos_descriptor]
   278  	strs_len	len[strs, int32]
   279  	strs		array[vusb_connect_string_descriptor]
   280  } [packed]
   281  
   282  vusb_connect_string_descriptor {
   283  	len	len[str, int32]
   284  	str	ptr[in, usb_string_descriptor]
   285  } [packed]
   286  
   287  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   288  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   289  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   290  
   291  # USB descriptors requested by the kernel before the SET_CONFIGURATION request.
   292  
   293  # TODO: figure out when is the USB_DT_OTG descriptor used.
   294  # TODO: figure out when is the USB_DT_INTERFACE_ASSOCIATION descriptor used.
   295  # TODO: figure out when is the USB_DT_BOS descriptor used.
   296  
   297  type usb_string_descriptor_t[DATA] {
   298  	bLength		len[parent, int8]
   299  	bDescriptorType	const[USB_DT_STRING, int8]
   300  
   301  	data		DATA
   302  } [packed]
   303  
   304  usb_string_descriptor [
   305  	lang_id	usb_string_descriptor_t[flags[usb_lang_ids, int16]]
   306  	string	usb_string_descriptor_t[array[int8, 0:256]]
   307  ] [varlen]
   308  
   309  usb_lang_ids = 0x436, 0x41c, 0x401, 0x801, 0xc01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001, 0x42b, 0x44d, 0x42c, 0x82c, 0x42d, 0x423, 0x445, 0x402, 0x455, 0x403, 0x404, 0x804, 0xc04, 0x1004, 0x1404, 0x41a, 0x405, 0x406, 0x413, 0x813, 0x409, 0x809, 0xc09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x425, 0x438, 0x429, 0x40b, 0x40c, 0x80c, 0xc0c, 0x100c, 0x140c, 0x180c, 0x437, 0x407, 0x807, 0xc07, 0x1007, 0x1407, 0x408, 0x447, 0x40d, 0x439, 0x40e, 0x40f, 0x421, 0x410, 0x810, 0x411, 0x44b, 0x860, 0x43f, 0x457, 0x412, 0x812, 0x426, 0x427, 0x827, 0x42f, 0x43e, 0x83e, 0x44c, 0x458, 0x44e, 0x861, 0x414, 0x814, 0x448, 0x415, 0x416, 0x816, 0x446, 0x418, 0x419, 0x44f, 0xc1a, 0x81a, 0x459, 0x41b, 0x424, 0x40a, 0x80a, 0xc0a, 0x100a, 0x140a, 0x180a, 0x1c0a, 0x200a, 0x240a, 0x280a, 0x2c0a, 0x300a, 0x340a, 0x380a, 0x3c0a, 0x400a, 0x440a, 0x480a, 0x4c0a, 0x500a, 0x430, 0x441, 0x41d, 0x81d, 0x449, 0x444, 0x44a, 0x41e, 0x41f, 0x422, 0x420, 0x820, 0x443, 0x843, 0x42a, 0x4ff, 0xf0ff, 0xf4ff, 0xf8ff, 0xfcff
   310  
   311  usb_qualifier_descriptor {
   312  	bLength			len[parent, int8]
   313  	bDescriptorType		const[USB_DT_DEVICE_QUALIFIER, int8]
   314  
   315  	bcdUSB			flags[usb_versions, int16]
   316  	bDeviceClass		int8
   317  	bDeviceSubClass		int8
   318  	bDeviceProtocol		int8
   319  	bMaxPacketSize0		flags[usb_device_max_packet_sizes, int8]
   320  	bNumConfigurations	int8
   321  	bRESERVED		const[0, int8]
   322  } [packed]
   323  
   324  define USB_DT_BOS_SIZE	5
   325  
   326  usb_bos_descriptor {
   327  	bLength		const[USB_DT_BOS_SIZE, int8]
   328  	bDescriptorType	const[USB_DT_BOS, int8]
   329  
   330  	wTotalLength	len[parent, int16]
   331  	bNumDeviceCaps	len[caps, int8]
   332  
   333  	caps		array[usb_dev_cap, 0:6]
   334  } [packed]
   335  
   336  usb_dev_cap [
   337  	generic		usb_generic_cap_descriptor
   338  	wireless	usb_wireless_cap_descriptor
   339  	ext_cap		usb_ext_cap_descriptor
   340  	ss_cap		usb_ss_cap_descriptor
   341  	ss_container_id	usb_ss_container_id_descriptor
   342  	ssp_cap		usb_ssp_cap_descriptor
   343  	ptm_cap		usb_ptm_cap_descriptor
   344  ] [varlen]
   345  
   346  usb_generic_cap_descriptor {
   347  	bLength			len[parent, int8]
   348  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   349  	bDevCapabilityType	flags[usb_capability_types, int8]
   350  
   351  	data			array[int8, 0:256]
   352  } [packed]
   353  
   354  define USB_CAP_TYPE_WIRELESS_USB	1
   355  define USB_CAP_TYPE_EXT	2
   356  define USB_SS_CAP_TYPE	3
   357  define USB_SSP_CAP_TYPE	0xa
   358  define CONTAINER_ID_TYPE	4
   359  define USB_PTM_CAP_TYPE	0xb
   360  usb_capability_types = USB_CAP_TYPE_WIRELESS_USB, USB_CAP_TYPE_EXT, USB_SS_CAP_TYPE, USB_SSP_CAP_TYPE, CONTAINER_ID_TYPE, USB_PTM_CAP_TYPE
   361  
   362  usb_wireless_cap_descriptor {
   363  	bLength			len[parent, int8]
   364  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   365  	bDevCapabilityType	const[USB_CAP_TYPE_WIRELESS_USB, int8]
   366  
   367  	bmAttributes		flags[usb_wireless_cap_attributes, int8]
   368  	wPHYRates		flags[usb_wireless_cap_phyrates, int16]
   369  	bmTFITXPowerInfo	int8
   370  	bmFFITXPowerInfo	int8
   371  	bmBandGroup		int16
   372  	bReserved		int8
   373  } [packed]
   374  
   375  define USB_WIRELESS_P2P_DRD	(1 << 1)
   376  define USB_WIRELESS_BEACON_MASK	(3 << 2)
   377  define USB_WIRELESS_BEACON_SELF	(1 << 2)
   378  define USB_WIRELESS_BEACON_DIRECTED	(2 << 2)
   379  define USB_WIRELESS_BEACON_NONE	(3 << 2)
   380  usb_wireless_cap_attributes = USB_WIRELESS_P2P_DRD, USB_WIRELESS_BEACON_MASK, USB_WIRELESS_BEACON_SELF, USB_WIRELESS_BEACON_DIRECTED, USB_WIRELESS_BEACON_NONE
   381  
   382  define USB_WIRELESS_PHY_53	(1 << 0)
   383  define USB_WIRELESS_PHY_80	(1 << 1)
   384  define USB_WIRELESS_PHY_107	(1 << 2)
   385  define USB_WIRELESS_PHY_160	(1 << 3)
   386  define USB_WIRELESS_PHY_200	(1 << 4)
   387  define USB_WIRELESS_PHY_320	(1 << 5)
   388  define USB_WIRELESS_PHY_400	(1 << 6)
   389  define USB_WIRELESS_PHY_480	(1 << 7)
   390  usb_wireless_cap_phyrates = USB_WIRELESS_PHY_53, USB_WIRELESS_PHY_80, USB_WIRELESS_PHY_107, USB_WIRELESS_PHY_160, USB_WIRELESS_PHY_200, USB_WIRELESS_PHY_320, USB_WIRELESS_PHY_400, USB_WIRELESS_PHY_480
   391  
   392  usb_ext_cap_descriptor {
   393  	bLength			len[parent, int8]
   394  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   395  	bDevCapabilityType	const[USB_CAP_TYPE_EXT, int8]
   396  
   397  	bmAttributes1		flags[usb_ext_cap_attributes, int32:8]
   398  	bmAttributes2		int32:4
   399  	bmAttributes3		int32:4
   400  	bmAttributes4		int32:16
   401  } [packed]
   402  
   403  define USB_LPM_SUPPORT	(1 << 1)
   404  define USB_BESL_SUPPORT	(1 << 2)
   405  define USB_BESL_BASELINE_VALID	(1 << 3)
   406  define USB_BESL_DEEP_VALID	(1 << 4)
   407  usb_ext_cap_attributes = USB_LPM_SUPPORT, USB_BESL_SUPPORT, USB_BESL_BASELINE_VALID, USB_BESL_DEEP_VALID
   408  
   409  usb_ss_cap_descriptor {
   410  	bLength			len[parent, int8]
   411  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   412  	bDevCapabilityType	const[USB_SS_CAP_TYPE, int8]
   413  
   414  	bmAttributes		flags[usb_ss_cap_attributes, int8]
   415  	wSpeedSupported		flags[usb_ss_cap_speed, int16]
   416  	bFunctionalitySupport	int8
   417  	bU1devExitLat		int8
   418  	bU2DevExitLat		int16
   419  } [packed]
   420  
   421  define USB_LTM_SUPPORT	(1 << 1)
   422  usb_ss_cap_attributes = USB_LTM_SUPPORT
   423  
   424  define USB_LOW_SPEED_OPERATION	(1)
   425  define USB_FULL_SPEED_OPERATION	(1 << 1)
   426  define USB_HIGH_SPEED_OPERATION	(1 << 2)
   427  define USB_5GBPS_OPERATION	(1 << 3)
   428  usb_ss_cap_speed = USB_LOW_SPEED_OPERATION, USB_FULL_SPEED_OPERATION, USB_HIGH_SPEED_OPERATION, USB_5GBPS_OPERATION
   429  
   430  usb_ss_container_id_descriptor {
   431  	bLength			len[parent, int8]
   432  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   433  	bDevCapabilityType	const[CONTAINER_ID_TYPE, int8]
   434  
   435  	bReserved		int8
   436  	ContainerID		array[int8, 16]
   437  } [packed]
   438  
   439  usb_ssp_cap_descriptor {
   440  	bLength				len[parent, int8]
   441  	bDescriptorType			const[USB_DT_DEVICE_CAPABILITY, int8]
   442  	bDevCapabilityType		const[USB_SSP_CAP_TYPE, int8]
   443  
   444  	bReserved			int8
   445  	bmAttributesSublinkSpeeds	len[bmSublinkSpeedAttr, int32:5]
   446  	bmAttributesSpeedIDs		int32:27
   447  	wFunctionalitySupport		flags[usb_ssp_cap_funcs, int16]
   448  	wReserved			int16
   449  	bmSublinkSpeedAttr		array[flags[usb_ssp_cap_sublink_speeds, int32], 0:6]
   450  } [packed]
   451  
   452  define USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID	(0xf)
   453  define USB_SSP_MIN_RX_LANE_COUNT	(0xf << 8)
   454  define USB_SSP_MIN_TX_LANE_COUNT	(0xf << 12)
   455  usb_ssp_cap_funcs = USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID, USB_SSP_MIN_RX_LANE_COUNT, USB_SSP_MIN_TX_LANE_COUNT
   456  
   457  define USB_SSP_SUBLINK_SPEED_SSID	(0xf)
   458  define USB_SSP_SUBLINK_SPEED_LSE	(0x3 << 4)
   459  define USB_SSP_SUBLINK_SPEED_ST	(0x3 << 6)
   460  define USB_SSP_SUBLINK_SPEED_RSVD	(0x3f << 8)
   461  define USB_SSP_SUBLINK_SPEED_LP	(0x3 << 14)
   462  define USB_SSP_SUBLINK_SPEED_LSM	(0xff << 16)
   463  usb_ssp_cap_sublink_speeds = USB_SSP_SUBLINK_SPEED_SSID, USB_SSP_SUBLINK_SPEED_LSE, USB_SSP_SUBLINK_SPEED_ST, USB_SSP_SUBLINK_SPEED_RSVD, USB_SSP_SUBLINK_SPEED_LP, USB_SSP_SUBLINK_SPEED_LSM
   464  
   465  usb_ptm_cap_descriptor {
   466  	bLength			len[parent, int8]
   467  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   468  	bDevCapabilityType	const[USB_PTM_CAP_TYPE, int8]
   469  } [packed]
   470  
   471  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   472  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   473  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   474  
   475  # Extra USB descriptors that come after an interface or an endpoint descriptor.
   476  
   477  # TODO: consider removing class specific descriptors here for described classes.
   478  usb_interface_extra_descriptor [
   479  	generic		usb_generic_descriptor
   480  	hid_hid		usb_hid_descriptor_hid
   481  	cdc_ecm		usb_cdc_header_ecm
   482  	cdc_ncm		usb_cdc_header_ncm
   483  	uac_control	uac_control_iface_extra_descriptors
   484  	uac_as		uac_as_iface_extra_descriptors
   485  ] [varlen]
   486  
   487  usb_endpoint_extra_descriptor [
   488  	generic	usb_generic_descriptor
   489  	uac_iso	uac_iso_endpoint_descriptor
   490  ] [varlen]
   491  
   492  usb_generic_descriptor {
   493  	bLength		len[parent, int8]
   494  	bDescriptorType	flags[usb_descriptor_types, int8]
   495  
   496  	data		array[int8, 0:256]
   497  } [packed]
   498  
   499  usb_descriptor_types = USB_DT_DEVICE, USB_DT_CONFIG, USB_DT_STRING, USB_DT_INTERFACE, USB_DT_ENDPOINT, USB_DT_DEVICE_QUALIFIER, USB_DT_OTHER_SPEED_CONFIG, USB_DT_INTERFACE_POWER, USB_DT_OTG, USB_DT_DEBUG, USB_DT_INTERFACE_ASSOCIATION, USB_DT_SECURITY, USB_DT_KEY, USB_DT_ENCRYPTION_TYPE, USB_DT_BOS, USB_DT_DEVICE_CAPABILITY, USB_DT_WIRELESS_ENDPOINT_COMP, USB_DT_WIRE_ADAPTER, USB_DT_RPIPE, USB_DT_CS_RADIO_CONTROL, USB_DT_PIPE_USAGE, USB_DT_SS_ENDPOINT_COMP, USB_DT_SSP_ISOC_ENDPOINT_COMP, HID_DT_HID, HID_DT_REPORT, HID_DT_PHYSICAL
   500  
   501  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   502  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   503  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   504  
   505  # USB descriptors requested after the SET_CONFIGURATION request.
   506  
   507  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   508  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   509  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   510  
   511  # Replies to USB control requests requested after the SET_CONFIGURATION request.
   512  
   513  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   514  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   515  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   516  
   517  # HID device class specific descriptions.
   518  # https://www.usb.org/sites/default/files/documents/hid1_11.pdf
   519  # https://elixir.bootlin.com/linux/latest/source/drivers/hid/usbhid/hid-core.c
   520  # https://elixir.bootlin.com/linux/latest/source/drivers/hid/hid-core.c
   521  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/hid.c
   522  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_hid.c
   523  
   524  # Connected HID devices are known to create the following /dev/ files:
   525  # /dev/hidraw#, /dev/usb/hiddev# and /dev/input/event#.
   526  
   527  syz_usb_connect$hid(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_hid], conn_descs ptr[in, vusb_connect_descriptors]) fd (timeout[3000], prog_timeout[3000])
   528  
   529  # idVendor and idProduct are patched by Go code, see sys/linux/init_vusb.go.
   530  usb_device_descriptor_hid {
   531  	inner	usb_device_descriptor_t[0, 0, 0, 0, 0, 64, array[usb_config_descriptor_hid, 1]]
   532  } [packed]
   533  
   534  usb_config_descriptor_hid {
   535  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_hid, 1]]
   536  } [packed]
   537  
   538  usb_interface_descriptor_hid {
   539  	inner	usb_interface_descriptor_t[const[0, int8], int8, int8[1:2], const[USB_CLASS_HID, int8], const[USB_INTERFACE_SUBCLASS_BOOT, int8], flags[usb_hid_protocols, int8], usb_hid_descriptor_hid, usb_endpoint_descriptors_hid]
   540  } [packed]
   541  
   542  usb_hid_protocols = USB_INTERFACE_PROTOCOL_KEYBOARD, USB_INTERFACE_PROTOCOL_MOUSE
   543  
   544  usb_endpoint_descriptors_hid {
   545  	in	usb_endpoint_descriptor_hid_in
   546  	out	array[usb_endpoint_descriptor_hid_out, 0:1]
   547  } [packed]
   548  
   549  usb_endpoint_descriptor_hid_in {
   550  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_IN_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void]
   551  } [packed]
   552  
   553  usb_endpoint_descriptor_hid_out {
   554  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_OUT_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void]
   555  } [packed]
   556  
   557  define USB_ENDPOINT_HID_ATTRIBUTES	(USB_ENDPOINT_XFER_INT)
   558  define USB_ENDPOINT_HID_IN_ADDRESS	(1 | USB_DIR_IN)
   559  define USB_ENDPOINT_HID_OUT_ADDRESS	(2)
   560  
   561  # USB HID specifications allows for multiple report and physical descriptors
   562  # to be present, but I don't see any support for them in the Linux kernel,
   563  # except for a single report descriptor.
   564  usb_hid_descriptor_hid {
   565  	bLength		len[parent, int8]
   566  	bDescriptorType	const[HID_DT_HID, int8]
   567  
   568  	bcdHID		int16
   569  	bCountryCode	int8
   570  	bNumDescriptors	const[1, int8]
   571  
   572  	report_desc	usb_hid_class_descriptor_report
   573  } [packed]
   574  
   575  usb_hid_class_descriptor_report {
   576  	bDescriptorType		const[HID_DT_REPORT, int8]
   577  	wDescriptorLength	int16[0:HID_MAX_DESCRIPTOR_SIZE]
   578  } [packed]
   579  
   580  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   581  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   582  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   583  
   584  # PRINTER device class specific descriptions.
   585  # https://www.usb.org/sites/default/files/usbprint11a021811.pdf
   586  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/class/usblp.c
   587  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/printer.c
   588  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_printer.c
   589  
   590  # Connected PRINTER devices are known to create the following /dev/ files:
   591  # /dev/usb/lp#.
   592  # TODO: write descriptions for those.
   593  
   594  # drivers/usb/class/usblp.c
   595  define USBLP_REQ_GET_ID	0x00
   596  define USBLP_REQ_GET_STATUS	0x01
   597  define USBLP_REQ_RESET	0x02
   598  define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	0x00
   599  define USBLP_FIRST_PROTOCOL	1
   600  define USBLP_LAST_PROTOCOL	3
   601  
   602  syz_usb_connect$printer(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_printer], conn_descs ptr[in, vusb_connect_descriptors]) fd (timeout[3000], prog_timeout[3000])
   603  
   604  usb_device_descriptor_printer {
   605  	inner	usb_device_descriptor_t[0, 0, 0, 0x525, 0xa4a8, 64, array[usb_config_descriptor_printer, 1]]
   606  } [packed]
   607  
   608  usb_config_descriptor_printer {
   609  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_printer, 1]]
   610  } [packed]
   611  
   612  usb_interface_descriptor_printer {
   613  	inner	usb_interface_descriptor_t[const[0, int8], int8, int8[1:2], const[USB_CLASS_PRINTER, int8], const[1, int8], int8[USBLP_FIRST_PROTOCOL:USBLP_LAST_PROTOCOL], void, usb_endpoint_descriptors_printer]
   614  } [packed]
   615  
   616  usb_endpoint_descriptors_printer {
   617  	in	usb_endpoint_descriptor_printer_out
   618  	out	array[usb_endpoint_descriptor_printer_in, 0:1]
   619  } [packed]
   620  
   621  usb_endpoint_descriptor_printer_out {
   622  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_OUT_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void]
   623  } [packed]
   624  
   625  usb_endpoint_descriptor_printer_in {
   626  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_IN_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void]
   627  } [packed]
   628  
   629  define USB_ENDPOINT_PRINTER_ATTRIBUTES	(USB_ENDPOINT_XFER_BULK)
   630  define USB_ENDPOINT_PRINTER_OUT_ADDRESS	(1)
   631  define USB_ENDPOINT_PRINTER_IN_ADDRESS	(2 | USB_DIR_IN)
   632  
   633  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   634  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   635  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   636  
   637  # CDC ECM (Ethernet) device class specific descriptions.
   638  # https://www.usb.org/document-library/class-definitions-communication-devices-12
   639  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ether.c
   640  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c
   641  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ether.c
   642  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ecm.c
   643  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_ether.c
   644  
   645  # Connected CDC ECM devices are known to create usbN network interfaces.
   646  # TODO: write descriptions for those.
   647  
   648  syz_usb_connect$cdc_ecm(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_cdc_ecm], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb (timeout[3000], prog_timeout[3000])
   649  
   650  usb_device_descriptor_cdc_ecm {
   651  	inner	usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ecm, 1]]
   652  } [packed]
   653  
   654  usb_config_descriptor_cdc_ecm {
   655  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_cdc_ecm, 1]]
   656  } [packed]
   657  
   658  define USB_CDC_SUBCLASS_ACM	0x02
   659  define USB_CDC_SUBCLASS_ETHERNET	0x06
   660  define USB_CDC_SUBCLASS_WHCM	0x08
   661  define USB_CDC_SUBCLASS_DMM	0x09
   662  define USB_CDC_SUBCLASS_MDLM	0x0a
   663  define USB_CDC_SUBCLASS_OBEX	0x0b
   664  define USB_CDC_SUBCLASS_EEM	0x0c
   665  define USB_CDC_SUBCLASS_NCM	0x0d
   666  define USB_CDC_SUBCLASS_MBIM	0x0e
   667  
   668  # Per specification CDC ECM devices have two interfaces (control and data),
   669  # but here we're merging them into one for simplicity since Linux supports that.
   670  usb_interface_descriptor_cdc_ecm {
   671  	inner	usb_interface_descriptor_t[const[0, int8], int8, int8[2:3], const[USB_CLASS_COMM, int8], const[USB_CDC_SUBCLASS_ETHERNET, int8], const[USB_CDC_PROTO_NONE, int8], usb_cdc_header_ecm, usb_endpoint_descriptors_cdc_ecm]
   672  } [packed]
   673  
   674  usb_endpoint_descriptors_cdc_ecm {
   675  	notify	array[usb_endpoint_descriptor_cdc_ecm_notify, 0:1]
   676  	in	usb_endpoint_descriptor_cdc_ecm_in
   677  	out	usb_endpoint_descriptor_cdc_ecm_out
   678  } [packed]
   679  
   680  usb_endpoint_descriptor_cdc_ecm_notify {
   681  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES, int8], void]
   682  } [packed]
   683  
   684  usb_endpoint_descriptor_cdc_ecm_in {
   685  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_IN_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void]
   686  } [packed]
   687  
   688  usb_endpoint_descriptor_cdc_ecm_out {
   689  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_OUT_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void]
   690  } [packed]
   691  
   692  define USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES	(USB_ENDPOINT_XFER_INT)
   693  define USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES	(USB_ENDPOINT_XFER_BULK)
   694  define USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS	(1 | USB_DIR_IN)
   695  define USB_ENDPOINT_CDC_ECM_IN_ADDRESS	(2 | USB_DIR_IN)
   696  define USB_ENDPOINT_CDC_ECM_OUT_ADDRESS	(3)
   697  
   698  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137
   699  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L155
   700  usb_cdc_header_ecm {
   701  	union	usb_cdc_union_desc_t[0, 0]
   702  	header	usb_cdc_header_desc
   703  	ether	usb_cdc_ether_desc
   704  
   705  	other	array[usb_cdc_header_ecm_other, 0:6]
   706  } [packed]
   707  
   708  usb_cdc_header_ecm_other [
   709  	call_mgmt		usb_cdc_call_mgmt_descriptor
   710  	acm			usb_cdc_acm_descriptor
   711  	country_functional	usb_cdc_country_functional_desc
   712  	network_terminal	usb_cdc_network_terminal_desc
   713  	dmm			usb_cdc_dmm_desc
   714  	mdlm			usb_cdc_mdlm_desc
   715  	mdlm_detail		usb_cdc_mdlm_detail_desc
   716  	obex			usb_cdc_obex_desc
   717  	ncm			usb_cdc_ncm_desc
   718  	mbim			usb_cdc_mbim_desc
   719  	mbim_extended		usb_cdc_mbim_extended_desc
   720  ] [varlen]
   721  
   722  usb_cdc_header_desc {
   723  	bLength			len[parent, int8]
   724  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   725  	bDescriptorSubType	const[USB_CDC_HEADER_TYPE, int8]
   726  
   727  	bcdCDC			int16
   728  } [packed]
   729  
   730  usb_cdc_call_mgmt_descriptor {
   731  	bLength			len[parent, int8]
   732  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   733  	bDescriptorSubType	const[USB_CDC_CALL_MANAGEMENT_TYPE, int8]
   734  
   735  	bmCapabilities		flags[usb_cdc_call_mgmt_caps, int8]
   736  	bDataInterface		int8
   737  } [packed]
   738  
   739  define USB_CDC_CALL_MGMT_CAP_CALL_MGMT	0x01
   740  define USB_CDC_CALL_MGMT_CAP_DATA_INTF	0x02
   741  usb_cdc_call_mgmt_caps = USB_CDC_CALL_MGMT_CAP_CALL_MGMT, USB_CDC_CALL_MGMT_CAP_DATA_INTF
   742  
   743  usb_cdc_acm_descriptor {
   744  	bLength			len[parent, int8]
   745  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   746  	bDescriptorSubType	const[USB_CDC_ACM_TYPE, int8]
   747  
   748  	bmCapabilities		flags[usb_cdc_acm_caps, int8]
   749  } [packed]
   750  
   751  define USB_CDC_COMM_FEATURE	0x01
   752  define USB_CDC_CAP_LINE	0x02
   753  define USB_CDC_CAP_BRK	0x04
   754  define USB_CDC_CAP_NOTIFY	0x08
   755  usb_cdc_acm_caps = USB_CDC_COMM_FEATURE, USB_CDC_CAP_LINE, USB_CDC_CAP_BRK, USB_CDC_CAP_NOTIFY
   756  
   757  type usb_cdc_union_desc_t[MASTER, SLAVE] {
   758  	bLength			len[parent, int8]
   759  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   760  	bDescriptorSubType	const[USB_CDC_UNION_TYPE, int8]
   761  
   762  	bMasterInterface0	const[MASTER, int8]
   763  	bSlaveInterface0	const[SLAVE, int8]
   764  	slave_interfaces	array[int8, 0:6]
   765  } [packed]
   766  
   767  usb_cdc_country_functional_desc {
   768  	bLength			len[parent, int8]
   769  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   770  	bDescriptorSubType	const[USB_CDC_COUNTRY_TYPE, int8]
   771  
   772  	iCountryCodeRelDate	int8
   773  	wCountyCode0		int16
   774  	country_codes		array[int16, 0:6]
   775  } [packed]
   776  
   777  usb_cdc_network_terminal_desc {
   778  	bLength			len[parent, int8]
   779  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   780  	bDescriptorSubType	const[USB_CDC_NETWORK_TERMINAL_TYPE, int8]
   781  
   782  	bEntityId		int8
   783  	iName			int8
   784  	bChannelIndex		int8
   785  	bPhysicalInterface	int8
   786  } [packed]
   787  
   788  usb_cdc_ether_desc {
   789  	bLength			len[parent, int8]
   790  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   791  	bDescriptorSubType	const[USB_CDC_ETHERNET_TYPE, int8]
   792  
   793  	iMACAddress		const[1, int8]
   794  	bmEthernetStatistics	int32
   795  	wMaxSegmentSize		int16
   796  	wNumberMCFilters	int16
   797  	bNumberPowerFilters	int8
   798  } [packed]
   799  
   800  usb_cdc_dmm_desc {
   801  	bLength			len[parent, int8]
   802  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   803  	bDescriptorSubType	const[USB_CDC_DMM_TYPE, int8]
   804  
   805  	bcdVersion		int16
   806  	wMaxCommand		int16
   807  } [packed]
   808  
   809  usb_cdc_mdlm_desc {
   810  	bLength			len[parent, int8]
   811  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   812  	bDescriptorSubType	const[USB_CDC_MDLM_TYPE, int8]
   813  
   814  	bcdVersion		int16
   815  	bGUID			usb_cdc_ecm_mbm_guid
   816  } [packed]
   817  
   818  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L61
   819  usb_cdc_ecm_mbm_guid {
   820  	id0	const[0x14f5e048ba817a3, int64]
   821  	id1	const[0x2a397ecbffc007a6, int64]
   822  } [packed]
   823  
   824  usb_cdc_mdlm_detail_desc {
   825  	bLength			len[parent, int8]
   826  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   827  	bDescriptorSubType	const[USB_CDC_MDLM_DETAIL_TYPE, int8]
   828  
   829  	bGuidDescriptorType	int8
   830  	bDetailData		array[int8, 0:256]
   831  } [packed]
   832  
   833  usb_cdc_obex_desc {
   834  	bLength			len[parent, int8]
   835  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   836  	bDescriptorSubType	const[USB_CDC_OBEX_TYPE, int8]
   837  
   838  	bcdVersion		int16
   839  } [packed]
   840  
   841  usb_cdc_ncm_desc {
   842  	bLength			len[parent, int8]
   843  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   844  	bDescriptorSubType	const[USB_CDC_NCM_TYPE, int8]
   845  
   846  	bcdNcmVersion		int16
   847  	bmNetworkCapabilities	flags[usb_cdc_ncm_ncaps, int8]
   848  } [packed]
   849  
   850  define USB_CDC_NCM_NCAP_ETH_FILTER	(1 << 0)
   851  define USB_CDC_NCM_NCAP_NET_ADDRESS	(1 << 1)
   852  define USB_CDC_NCM_NCAP_ENCAP_COMMAND	(1 << 2)
   853  define USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE	(1 << 3)
   854  define USB_CDC_NCM_NCAP_CRC_MODE	(1 << 4)
   855  define USB_CDC_NCM_NCAP_NTB_INPUT_SIZE	(1 << 5)
   856  usb_cdc_ncm_ncaps = USB_CDC_NCM_NCAP_ETH_FILTER, USB_CDC_NCM_NCAP_NET_ADDRESS, USB_CDC_NCM_NCAP_ENCAP_COMMAND, USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE, USB_CDC_NCM_NCAP_CRC_MODE, USB_CDC_NCM_NCAP_NTB_INPUT_SIZE
   857  
   858  usb_cdc_mbim_desc {
   859  	bLength			len[parent, int8]
   860  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   861  	bDescriptorSubType	const[USB_CDC_MBIM_TYPE, int8]
   862  
   863  	bcdMBIMVersion		int16
   864  	wMaxControlMessage	int16
   865  	bNumberFilters		int8
   866  	bMaxFilterSize		int8
   867  	wMaxSegmentSize		int16
   868  	bmNetworkCapabilities	int8
   869  } [packed]
   870  
   871  usb_cdc_mbim_extended_desc {
   872  	bLength				len[parent, int8]
   873  	bDescriptorType			const[USB_DT_CS_INTERFACE, int8]
   874  	bDescriptorSubType		const[USB_CDC_MBIM_EXTENDED_TYPE, int8]
   875  
   876  	bcdMBIMExtendedVersion		int16
   877  	bMaxOutstandingCommandMessages	int8
   878  	wMTU				int16
   879  } [packed]
   880  
   881  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   882  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   883  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   884  
   885  # CDC NCM class specific descriptions.
   886  # CDC NCM is based on CDC ECM, so some of the descriptions are reused.
   887  # https://www.usb.org/document-library/network-control-model-devices-specification-v10-and-errata-and-adopters-agreement
   888  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ncm.c
   889  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c
   890  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ncm.c
   891  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ncm.c
   892  
   893  syz_usb_connect$cdc_ncm(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_cdc_ncm], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb (timeout[3000], prog_timeout[3000])
   894  
   895  usb_device_descriptor_cdc_ncm {
   896  	inner	usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ncm, 1]]
   897  } [packed]
   898  
   899  usb_config_descriptor_cdc_ncm {
   900  	inner	usb_config_descriptor_t[const[1, int8], const[2, int8], usb_interface_descriptors_cdc_ncm]
   901  } [packed]
   902  
   903  define CDC_NCM_COMM_ALTSETTING_NCM	0
   904  define CDC_NCM_DATA_ALTSETTING_NCM	1
   905  
   906  usb_interface_descriptors_cdc_ncm {
   907  	control		usb_interface_descriptor_fixed_t[0, CDC_NCM_COMM_ALTSETTING_NCM, 1, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, usb_cdc_header_ncm, usb_endpoint_descriptor_cdc_ecm_notify]
   908  	data_nop	usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, void, void]
   909  	data		usb_interface_descriptor_fixed_t[1, CDC_NCM_DATA_ALTSETTING_NCM, 2, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, void, usb_endpoint_descriptors_cdc_ncm_data]
   910  } [packed]
   911  
   912  usb_endpoint_descriptors_cdc_ncm_data {
   913  	in	usb_endpoint_descriptor_cdc_ecm_in
   914  	out	usb_endpoint_descriptor_cdc_ecm_out
   915  } [packed]
   916  
   917  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137
   918  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ncm.c#L798
   919  usb_cdc_header_ncm {
   920  	union	usb_cdc_union_desc_t[0, 1]
   921  	header	usb_cdc_header_desc
   922  	ether	usb_cdc_ether_desc
   923  	ncm	usb_cdc_ncm_desc
   924  
   925  	other	array[usb_cdc_header_ncm_other, 0:6]
   926  } [packed]
   927  
   928  usb_cdc_header_ncm_other [
   929  	call_mgmt		usb_cdc_call_mgmt_descriptor
   930  	acm			usb_cdc_acm_descriptor
   931  	country_functional	usb_cdc_country_functional_desc
   932  	network_terminal	usb_cdc_network_terminal_desc
   933  	dmm			usb_cdc_dmm_desc
   934  	mdlm			usb_cdc_mdlm_desc
   935  	mdlm_detail		usb_cdc_mdlm_detail_desc
   936  	obex			usb_cdc_obex_desc
   937  	mbim			usb_cdc_mbim_desc
   938  	mbim_extended		usb_cdc_mbim_extended_desc
   939  ] [varlen]
   940  
   941  # cdc.h
   942  define USB_CDC_SEND_ENCAPSULATED_COMMAND	0x00
   943  define USB_CDC_GET_ENCAPSULATED_RESPONSE	0x01
   944  define USB_CDC_REQ_SET_LINE_CODING	0x20
   945  define USB_CDC_REQ_GET_LINE_CODING	0x21
   946  define USB_CDC_REQ_SET_CONTROL_LINE_STATE	0x22
   947  define USB_CDC_REQ_SEND_BREAK	0x23
   948  define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS	0x40
   949  define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER	0x41
   950  define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER	0x42
   951  define USB_CDC_SET_ETHERNET_PACKET_FILTER	0x43
   952  define USB_CDC_GET_ETHERNET_STATISTIC	0x44
   953  define USB_CDC_GET_NTB_PARAMETERS	0x80
   954  define USB_CDC_GET_NET_ADDRESS	0x81
   955  define USB_CDC_SET_NET_ADDRESS	0x82
   956  define USB_CDC_GET_NTB_FORMAT	0x83
   957  define USB_CDC_SET_NTB_FORMAT	0x84
   958  define USB_CDC_GET_NTB_INPUT_SIZE	0x85
   959  define USB_CDC_SET_NTB_INPUT_SIZE	0x86
   960  define USB_CDC_GET_MAX_DATAGRAM_SIZE	0x87
   961  define USB_CDC_SET_MAX_DATAGRAM_SIZE	0x88
   962  define USB_CDC_GET_CRC_MODE	0x89
   963  define USB_CDC_SET_CRC_MODE	0x8a
   964  
   965  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   966  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   967  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   968  
   969  # UAC1 device class specific descriptions.
   970  # https://www.usb.org/sites/default/files/audio10.pdf
   971  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/audio.c
   972  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1.c
   973  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1_legacy.c
   974  # https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/usb/audio.h
   975  
   976  # TODO: find out which /dev/ files are created by connected UAC1 devices and add descriptions for those.
   977  
   978  syz_usb_connect$uac1(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_uac1], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb (timeout[3000], prog_timeout[3000])
   979  
   980  usb_device_descriptor_uac1 {
   981  	inner	usb_device_descriptor_t[0, 0, 0, 0x1d6b, 0x101, 64, array[usb_config_descriptor_uac1, 1]]
   982  } [packed]
   983  
   984  usb_config_descriptor_uac1 {
   985  	inner	usb_config_descriptor_t[const[1, int8], const[3, int8], usb_interface_descriptors_uac1]
   986  } [packed]
   987  
   988  # TODO: control interface might have and optional interrupt endpoint.
   989  define USB_SUBCLASS_AUDIOCONTROL	0x01
   990  define USB_SUBCLASS_AUDIOSTREAMING	0x02
   991  
   992  usb_interface_descriptors_uac1 {
   993  	control		usb_interface_descriptor_fixed_t[0, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOCONTROL, 0, uac_control_iface_extra_descriptors, void]
   994  	as_out_alt_0	usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void]
   995  	as_out_alt_1	usb_interface_descriptor_fixed_t[1, 1, 1, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, uac_as_iface_extra_descriptors, uac_as_out_endpoint_descriptor]
   996  	as_in_alt_0	usb_interface_descriptor_fixed_t[2, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void]
   997  	as_in_alt_1	usb_interface_descriptor_fixed_t[2, 1, 1, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, uac_as_iface_extra_descriptors, uac_as_in_endpoint_descriptor]
   998  } [packed]
   999  
  1000  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1001  
  1002  # UAC uses IDs to make it possible for terminals and units to refer to each other.
  1003  # We don't have a way to describe this, so just use a limited number of ids.
  1004  type uac_id int8[1:6]
  1005  
  1006  uac_control_iface_extra_descriptors {
  1007  	header	uac1_ac_header_descriptor_2
  1008  	others	array[uac_control_iface_extra_descriptor, 0:6]
  1009  } [packed]
  1010  
  1011  uac_as_iface_extra_descriptors {
  1012  	others	array[uac_as_iface_extra_descriptor, 0:6]
  1013  } [packed]
  1014  
  1015  uac_control_iface_extra_descriptor [
  1016  	input_terminal	uac_input_terminal_descriptor
  1017  	output_terminal	uac1_output_terminal_descriptor
  1018  	mixer_unit	uac_mixer_unit_descriptor
  1019  	selector_unit	uac_selector_unit_descriptor
  1020  	feature_unit	uac_feature_unit_descriptor
  1021  	processing_unit	uac_processing_unit_descriptor
  1022  	extension_unit	uac_extension_unit_descriptor
  1023  ] [varlen]
  1024  
  1025  uac_as_iface_extra_descriptor [
  1026  	as_header			uac1_as_header_descriptor
  1027  	format_type_i_continuous	uac_format_type_i_continuous_descriptor
  1028  	format_type_i_discrete		uac_format_type_i_discrete_descriptor
  1029  	format_type_ii_discrete		uac_format_type_ii_discrete_descriptor
  1030  ] [varlen]
  1031  
  1032  define F_AUDIO_NUM_INTERFACES	2
  1033  define UAC_DT_AC_HEADER_LENGTH	(8 + F_AUDIO_NUM_INTERFACES)
  1034  
  1035  define UAC_HEADER	0x01
  1036  define UAC_INPUT_TERMINAL	0x02
  1037  define UAC_OUTPUT_TERMINAL	0x03
  1038  define UAC_MIXER_UNIT	0x04
  1039  define UAC_SELECTOR_UNIT	0x05
  1040  define UAC_FEATURE_UNIT	0x06
  1041  define UAC1_PROCESSING_UNIT	0x07
  1042  define UAC1_EXTENSION_UNIT	0x08
  1043  
  1044  uac1_ac_header_descriptor_2 {
  1045  	bLength			const[UAC_DT_AC_HEADER_LENGTH, int8]
  1046  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1047  	bDescriptorSubType	const[UAC_HEADER, int8]
  1048  
  1049  	bcdADC			int16
  1050  	wTotalLength		int8
  1051  	bInCollection		const[F_AUDIO_NUM_INTERFACES, int8]
  1052  
  1053  # These must match interfaces numbers.
  1054  	baInterfaceNr0		const[1, int8]
  1055  	baInterfaceNr1		const[2, int8]
  1056  } [packed]
  1057  
  1058  uac_input_terminal_descriptor {
  1059  	bLength			len[parent, int8]
  1060  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1061  	bDescriptorSubType	const[UAC_INPUT_TERMINAL, int8]
  1062  
  1063  	bTerminalID		uac_id
  1064  	wTerminalType		flags[uac_input_terminal_types, int16]
  1065  	bAssocTerminal		uac_id
  1066  	bNrChannels		int8
  1067  	wChannelConfig		int16
  1068  	iChannelNames		int8
  1069  	iTerminal		int8
  1070  } [packed]
  1071  
  1072  define UAC_TERMINAL_UNDEFINED	0x100
  1073  define UAC_TERMINAL_STREAMING	0x101
  1074  define UAC_TERMINAL_VENDOR_SPEC	0x1FF
  1075  
  1076  define UAC_INPUT_TERMINAL_UNDEFINED	0x200
  1077  define UAC_INPUT_TERMINAL_MICROPHONE	0x201
  1078  define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE	0x202
  1079  define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE	0x203
  1080  define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE	0x204
  1081  define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY	0x205
  1082  define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY	0x206
  1083  
  1084  define UAC_OUTPUT_TERMINAL_UNDEFINED	0x300
  1085  define UAC_OUTPUT_TERMINAL_SPEAKER	0x301
  1086  define UAC_OUTPUT_TERMINAL_HEADPHONES	0x302
  1087  define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO	0x303
  1088  define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER	0x304
  1089  define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER	0x305
  1090  define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER	0x306
  1091  define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER	0x307
  1092  
  1093  uac_input_terminal_types = UAC_TERMINAL_UNDEFINED, UAC_TERMINAL_STREAMING, UAC_TERMINAL_VENDOR_SPEC, UAC_INPUT_TERMINAL_UNDEFINED, UAC_INPUT_TERMINAL_MICROPHONE, UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE, UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE, UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE, UAC_INPUT_TERMINAL_MICROPHONE_ARRAY, UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY
  1094  
  1095  uac1_output_terminal_descriptor {
  1096  	bLength			len[parent, int8]
  1097  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1098  	bDescriptorSubType	const[UAC_OUTPUT_TERMINAL, int8]
  1099  
  1100  	bTerminalID		uac_id
  1101  	wTerminalType		flags[uac_output_terminal_types, int16]
  1102  	bAssocTerminal		uac_id
  1103  	bSourceID		uac_id
  1104  	iTerminal		int8
  1105  } [packed]
  1106  
  1107  uac_output_terminal_types = UAC_TERMINAL_UNDEFINED, UAC_TERMINAL_STREAMING, UAC_TERMINAL_VENDOR_SPEC, UAC_OUTPUT_TERMINAL_UNDEFINED, UAC_OUTPUT_TERMINAL_SPEAKER, UAC_OUTPUT_TERMINAL_HEADPHONES, UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO, UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER, UAC_OUTPUT_TERMINAL_ROOM_SPEAKER, UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER, UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER
  1108  
  1109  uac_mixer_unit_descriptor {
  1110  	bLength			len[parent, int8]
  1111  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1112  	bDescriptorSubType	const[UAC_MIXER_UNIT, int8]
  1113  
  1114  	bUnitID			uac_id
  1115  	bNrInPins		int8
  1116  	baSourceID		array[int8, 0:6]
  1117  } [packed]
  1118  
  1119  uac_selector_unit_descriptor {
  1120  	bLength			len[parent, int8]
  1121  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1122  	bDescriptorSubType	const[UAC_SELECTOR_UNIT, int8]
  1123  
  1124  	bUnitID			uac_id
  1125  	bNrInPins		int8
  1126  	baSourceID		array[int8, 0:6]
  1127  } [packed]
  1128  
  1129  uac_feature_unit_descriptor {
  1130  	bLength			len[parent, int8]
  1131  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1132  	bDescriptorSubType	const[UAC_FEATURE_UNIT, int8]
  1133  
  1134  	bUnitID			uac_id
  1135  	bSourceID		uac_id
  1136  	bControlSize		len[bmaControls, int8]
  1137  	bmaControls		array[flags[uac_feature_unit_controls, int16], 1:6]
  1138  	iFeature		int8
  1139  } [packed]
  1140  
  1141  define UAC_FU_MUTE	0x01
  1142  define UAC_FU_VOLUME	0x02
  1143  define UAC_FU_BASS	0x03
  1144  define UAC_FU_MID	0x04
  1145  define UAC_FU_TREBLE	0x05
  1146  define UAC_FU_GRAPHIC_EQUALIZER	0x06
  1147  define UAC_FU_AUTOMATIC_GAIN	0x07
  1148  define UAC_FU_DELAY	0x08
  1149  define UAC_FU_BASS_BOOST	0x09
  1150  define UAC_FU_LOUDNESS	0x0a
  1151  uac_feature_unit_controls = UAC_FU_MUTE, UAC_FU_VOLUME, UAC_FU_BASS, UAC_FU_MID, UAC_FU_TREBLE, UAC_FU_GRAPHIC_EQUALIZER, UAC_FU_AUTOMATIC_GAIN, UAC_FU_DELAY, UAC_FU_BASS_BOOST, UAC_FU_LOUDNESS
  1152  
  1153  uac_processing_unit_descriptor {
  1154  	bLength			len[parent, int8]
  1155  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1156  	bDescriptorSubType	const[UAC1_PROCESSING_UNIT, int8]
  1157  
  1158  	bUnitID			uac_id
  1159  	wProcessType		flags[uac_processing_unit_types, int16]
  1160  	bNrInPins		int8
  1161  	baSourceID		array[int8, 0:6]
  1162  } [packed]
  1163  
  1164  define UAC_PROCESS_UNDEFINED	0x00
  1165  define UAC_PROCESS_UP_DOWNMIX	0x01
  1166  define UAC_PROCESS_DOLBY_PROLOGIC	0x02
  1167  define UAC_PROCESS_STEREO_EXTENDER	0x03
  1168  define UAC_PROCESS_REVERB	0x04
  1169  define UAC_PROCESS_CHORUS	0x05
  1170  define UAC_PROCESS_DYN_RANGE_COMP	0x06
  1171  uac_processing_unit_types = UAC_PROCESS_UNDEFINED, UAC_PROCESS_UP_DOWNMIX, UAC_PROCESS_DOLBY_PROLOGIC, UAC_PROCESS_STEREO_EXTENDER, UAC_PROCESS_REVERB, UAC_PROCESS_CHORUS, UAC_PROCESS_DYN_RANGE_COMP
  1172  
  1173  uac_extension_unit_descriptor {
  1174  	bLength			len[parent, int8]
  1175  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1176  	bDescriptorSubType	const[UAC1_EXTENSION_UNIT, int8]
  1177  
  1178  	bUnitID			uac_id
  1179  	wProcessType		int16
  1180  	bNrInPins		int8
  1181  	baSourceID		array[int8, 0:6]
  1182  } [packed]
  1183  
  1184  define UAC_AS_GENERAL	0x01
  1185  define UAC_FORMAT_TYPE	0x02
  1186  define UAC_FORMAT_SPECIFIC	0x03
  1187  
  1188  uac1_as_header_descriptor {
  1189  	bLength			len[parent, int8]
  1190  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1191  	bDescriptorSubType	const[UAC_AS_GENERAL, int8]
  1192  
  1193  	bTerminalLink		int8
  1194  	bDelay			int8
  1195  	wFormatTag		flags[uac_format_types, int16]
  1196  } [packed]
  1197  
  1198  define UAC_FORMAT_TYPE_UNDEFINED	0x0
  1199  define UAC_FORMAT_TYPE_I	0x1
  1200  define UAC_FORMAT_TYPE_II	0x2
  1201  define UAC_FORMAT_TYPE_III	0x3
  1202  define UAC_EXT_FORMAT_TYPE_I	0x81
  1203  define UAC_EXT_FORMAT_TYPE_II	0x82
  1204  define UAC_EXT_FORMAT_TYPE_III	0x83
  1205  
  1206  define UAC_FORMAT_TYPE_I_UNDEFINED	0x0
  1207  define UAC_FORMAT_TYPE_I_PCM	0x1
  1208  define UAC_FORMAT_TYPE_I_PCM8	0x2
  1209  define UAC_FORMAT_TYPE_I_IEEE_FLOAT	0x3
  1210  define UAC_FORMAT_TYPE_I_ALAW	0x4
  1211  define UAC_FORMAT_TYPE_I_MULAW	0x5
  1212  define UAC_FORMAT_TYPE_II_MPEG	0x1001
  1213  define UAC_FORMAT_TYPE_II_AC3	0x1002
  1214  uac_format_types = UAC_FORMAT_TYPE_I_UNDEFINED, UAC_FORMAT_TYPE_I_PCM, UAC_FORMAT_TYPE_I_PCM8, UAC_FORMAT_TYPE_I_IEEE_FLOAT, UAC_FORMAT_TYPE_I_ALAW, UAC_FORMAT_TYPE_I_MULAW, UAC_FORMAT_TYPE_II_MPEG, UAC_FORMAT_TYPE_II_AC3
  1215  
  1216  uac_format_type_i_continuous_descriptor {
  1217  	bLength			len[parent, int8]
  1218  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1219  	bDescriptorSubType	const[UAC_FORMAT_TYPE, int8]
  1220  
  1221  	bFormatType		const[UAC_FORMAT_TYPE_I, int8]
  1222  	bNrChannels		int8
  1223  	bSubframeSize		int8[1:4]
  1224  	bBitResolution		int8
  1225  	bSamFreqType		int8
  1226  	tLowerSamFreq		array[int8, 0:3]
  1227  	tUpperSamFreq		array[int8, 0:3]
  1228  } [packed]
  1229  
  1230  uac_format_type_i_discrete_descriptor {
  1231  	bLength			len[parent, int8]
  1232  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1233  	bDescriptorSubType	const[UAC_FORMAT_TYPE, int8]
  1234  
  1235  	bFormatType		const[UAC_FORMAT_TYPE_I, int8]
  1236  	bNrChannels		int8
  1237  	bSubframeSize		int8[1:4]
  1238  	bBitResolution		int8
  1239  	bSamFreqType		int8
  1240  	tSamFreq		array[int8, 0:9]
  1241  } [packed]
  1242  
  1243  uac_format_type_ii_discrete_descriptor {
  1244  	bLength			len[parent, int8]
  1245  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1246  	bDescriptorSubType	const[UAC_FORMAT_TYPE, int8]
  1247  
  1248  	bFormatType		const[UAC_FORMAT_TYPE_II, int8]
  1249  	wMaxBitRate		int16
  1250  	wSamplesPerFrame	int16
  1251  	bSamFreqType		int8
  1252  	tSamFreq		array[int8, 0:9]
  1253  } [packed]
  1254  
  1255  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1256  
  1257  uac_as_out_endpoint_descriptor {
  1258  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_OUT_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor]
  1259  } [packed]
  1260  
  1261  uac_as_in_endpoint_descriptor {
  1262  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_IN_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor]
  1263  } [packed]
  1264  
  1265  define USB_ENDPOINT_UAC1_AS_OUT_ADDRESS	(1 | USB_DIR_OUT)
  1266  define USB_ENDPOINT_UAC1_AS_IN_ADDRESS	(2 | USB_DIR_IN)
  1267  define USB_ENDPOINT_UAC1_AS_ATTRIBUTES	(USB_ENDPOINT_SYNC_ADAPTIVE | USB_ENDPOINT_XFER_ISOC)
  1268  
  1269  define UAC_EP_GENERAL	0x01
  1270  
  1271  uac_iso_endpoint_descriptor {
  1272  	bLength			len[parent, int8]
  1273  	bDescriptorType		const[USB_DT_CS_ENDPOINT, int8]
  1274  	bDescriptorSubType	const[UAC_EP_GENERAL, int8]
  1275  
  1276  	bmAttributes		flags[uac_iso_ep_attributes, int8]
  1277  	bLockDelayUnits		int8
  1278  	wLockDelay		int16
  1279  } [packed]
  1280  
  1281  define UAC_EP_CS_ATTR_SAMPLE_RATE	0x01
  1282  define UAC_EP_CS_ATTR_PITCH_CONTROL	0x02
  1283  define UAC_EP_CS_ATTR_FILL_MAX	0x80
  1284  uac_iso_ep_attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, UAC_EP_CS_ATTR_PITCH_CONTROL, UAC_EP_CS_ATTR_FILL_MAX
  1285  
  1286  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1287  
  1288  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1289  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1290  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1291  
  1292  # TODO: describe MIDI, UAC2, UAC3
  1293  # https://www.usb.org/sites/default/files/midi10.pdf
  1294  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_midi.c
  1295  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac2.c
  1296  # https://elixir.bootlin.com/linux/latest/source/include/linux/usb/audio-v2.h
  1297  
  1298  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1299  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1300  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1301  
  1302  # ath9k driver specific descriptions.
  1303  
  1304  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1305  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1306  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #