github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/sys/linux/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  include <linux/types.h>
     5  include <linux/byteorder/generic.h>
     6  
     7  include <uapi/linux/usb/ch9.h>
     8  include <uapi/linux/usb/ch11.h>
     9  
    10  include <uapi/linux/usb/audio.h>
    11  include <uapi/linux/hid.h>
    12  include <linux/hid.h>
    13  include <uapi/linux/usb/cdc.h>
    14  include <uapi/linux/if_ether.h>
    15  include <linux/interrupt.h>
    16  include <linux/usb/cdc_ncm.h>
    17  include <drivers/net/usb/asix.h>
    18  
    19  # This is a special fd for USB fuzzing and should only be used with syz_usb_* pseudo-syscalls.
    20  # We don't inherit it from the fd resource, to discourage syzkaller calling raw ioctls on it.
    21  resource fd_usb[int32]: -1
    22  
    23  # These are generic pseudo-syscalls for emulating arbitrary USB devices.
    24  # They are mostly targeted to cover the enumeration process.
    25  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])
    26  syz_usb_control_io(fd fd_usb, descs ptr[in, vusb_descriptors], resps ptr[in, vusb_responses]) (timeout[300])
    27  syz_usb_ep_write(fd fd_usb, ep int8, len len[data], data ptr[in, array[int8, 0:256]]) (timeout[300])
    28  syz_usb_ep_read(fd fd_usb, ep int8, len len[data], data buffer[out]) (timeout[300])
    29  syz_usb_disconnect(fd fd_usb) (timeout[300])
    30  
    31  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
    32  
    33  # TODO: consider patching idVendor and idProduct for all class specific descriptions in Go code to cover more drivers.
    34  # TODO: custom syz_usb_ep_write() descriptions for all class specific descriptions.
    35  # TODO: consider adding custom vusb_connect_descriptors definitions to all class specific descriptions.
    36  
    37  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    38  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    39  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    40  
    41  type usb_device_descriptor_verbose_t[USB, CLASS, SUBCLASS, PROTOCOL, PACKET, VENDOR, PRODUCT, DEVICE, CFS] {
    42  	bLength			const[USB_DT_DEVICE_SIZE, int8]
    43  	bDescriptorType		const[USB_DT_DEVICE, int8]
    44  
    45  	bcdUSB			USB
    46  	bDeviceClass		const[CLASS, int8]
    47  	bDeviceSubClass		const[SUBCLASS, int8]
    48  	bDeviceProtocol		const[PROTOCOL, int8]
    49  	bMaxPacketSize0		PACKET
    50  	idVendor		const[VENDOR, int16]
    51  	idProduct		const[PRODUCT, int16]
    52  	bcdDevice		const[DEVICE, int16]
    53  	iManufacturer		const[1, int8]
    54  	iProduct		const[2, int8]
    55  	iSerialNumber		const[3, int8]
    56  	bNumConfigurations	len[configs, int8]
    57  
    58  	configs			CFS
    59  } [packed]
    60  
    61  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]
    62  type usb_device_descriptor_fixed_t[USB, CLASS, SUBCLASS, PROTOCOL, PACKET, VENDOR, PRODUCT, DEVICE, CFS] usb_device_descriptor_verbose_t[const[USB, int16], CLASS, SUBCLASS, PROTOCOL, const[PACKET, int8], VENDOR, PRODUCT, DEVICE, CFS]
    63  
    64  usb_versions = 0x110, 0x200, 0x201, 0x250, 0x300, 0x310
    65  
    66  # https://elixir.bootlin.com/linux/v5.1.7/source/drivers/usb/core/hub.c#L4661
    67  usb_device_max_packet_sizes = 8, 16, 32, 64, 255
    68  
    69  type usb_config_descriptor_verbose_t[NUM, IFSNUM, ICONFIG, ATTRS, POWER, IFS] {
    70  	bLength			const[USB_DT_CONFIG_SIZE, int8]
    71  	bDescriptorType		const[USB_DT_CONFIG, int8]
    72  
    73  	wTotalLength		len[parent, int16]
    74  	bNumInterfaces		IFSNUM
    75  	bConfigurationValue	NUM
    76  	iConfiguration		ICONFIG
    77  	bmAttributes		ATTRS
    78  	bMaxPower		POWER
    79  
    80  	interfaces		IFS
    81  } [packed]
    82  
    83  type usb_config_descriptor_t[NUM, IFSNUM, IFS] usb_config_descriptor_verbose_t[NUM, IFSNUM, int8, flags[usb_config_attributes, int8], int8, IFS]
    84  type usb_config_descriptor_ifaces_array_t[NUM, IFS] usb_config_descriptor_t[NUM, len[interfaces, int8], IFS]
    85  type usb_config_descriptor_fixed_t[NUM, IFSNUM, ATTRS, POWER, IFS] usb_config_descriptor_verbose_t[const[NUM, int8], const[IFSNUM, int8], const[0, int8], const[ATTRS, int8], const[POWER, int8], IFS]
    86  
    87  type usb_interface_descriptor_verbose_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, IIF, EXTRA, EPS] {
    88  	bLength			const[USB_DT_INTERFACE_SIZE, int8]
    89  	bDescriptorType		const[USB_DT_INTERFACE, int8]
    90  
    91  	bInterfaceNumber	IFNUM
    92  	bAlternateSetting	ALTNUM
    93  	bNumEndpoints		EPSNUM
    94  	bInterfaceClass		CLASS
    95  	bInterfaceSubClass	SUBCLASS
    96  	bInterfaceProtocol	PROTOCOL
    97  	iInterface		IIF
    98  
    99  	extra			EXTRA
   100  	endpoints		EPS
   101  } [packed]
   102  
   103  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]
   104  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]
   105  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]
   106  
   107  # TODO: non-audio endpoints have USB_DT_ENDPOINT_SIZE.
   108  type usb_endpoint_descriptor_verbose_t[ADDR, ATTRS, PACKET, INTERVAL, REFRESH, SYNCH, EXTRA] {
   109  	bLength			const[USB_DT_ENDPOINT_AUDIO_SIZE, int8]
   110  	bDescriptorType		const[USB_DT_ENDPOINT, int8]
   111  
   112  	bEndpointAddress	ADDR
   113  	bmAttributes		ATTRS
   114  	wMaxPacketSize		PACKET
   115  	bInterval		INTERVAL
   116  
   117  	bRefresh		REFRESH
   118  	bSynchAddress		SYNCH
   119  
   120  	extra			EXTRA
   121  } [packed]
   122  
   123  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]
   124  type usb_endpoint_descriptor_fixed_t[ADDR, ATTRS, PACKET, INTERVAL, EXTRA] usb_endpoint_descriptor_verbose_t[const[ADDR, int8], const[ATTRS, int8], const[PACKET, int16], const[INTERVAL, int8], const[0, int8], const[0, int8], EXTRA]
   125  
   126  # TODO: dummy driver has complex requirements for packet sizes, account for those:
   127  # https://elixir.bootlin.com/linux/v5.3.6/source/drivers/usb/gadget/udc/dummy_hcd.c#L497
   128  usb_endpoint_max_packet_sizes = 8, 16, 32, 64, 512, 1023, 1024
   129  
   130  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   131  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   132  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   133  
   134  # Generic USB device, configuration, interface and endpoint descriptors.
   135  
   136  # We only support one configuration per device.
   137  # bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct
   138  # and bcdDevice are patched by Go code, see sys/linux/init_vusb.go.
   139  usb_device_descriptor {
   140  	inner	usb_device_descriptor_t[0, 0, 0, 0, 0, 0, array[usb_config_descriptor, 1]]
   141  } [packed]
   142  
   143  usb_config_descriptor {
   144  	inner	usb_config_descriptor_ifaces_array_t[int8, array[usb_interface_descriptor, 1:4]]
   145  } [packed]
   146  
   147  usb_config_attributes = USB_CONFIG_ATT_ONE, USB_CONFIG_ATT_SELFPOWER, USB_CONFIG_ATT_WAKEUP, USB_CONFIG_ATT_BATTERY
   148  
   149  # bInterfaceNumber, bInterfaceClass, bInterfaceSubClass and bInterfaceProtocol
   150  # are patched by Go code, see sys/linux/init_vusb.go.
   151  usb_interface_descriptor {
   152  	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]]
   153  } [packed]
   154  
   155  usb_endpoint_descriptor {
   156  	inner	usb_endpoint_descriptor_t[flags[usb_endpoint_addresses, int8], flags[usb_endpoint_attributes, int8], array[usb_endpoint_extra_descriptor, 0:2]]
   157  } [packed]
   158  
   159  usb_endpoint_addresses = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, USB_DIR_OUT, USB_DIR_IN
   160  
   161  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
   162  
   163  vusb_connect_descriptors {
   164  	qual_len	len[qual, int32]
   165  	qual		ptr[in, usb_qualifier_descriptor]
   166  	bos_len		len[bos, int32]
   167  	bos		ptr[in, usb_bos_descriptor]
   168  	strs_len	len[strs, int32]
   169  	strs		array[vusb_connect_string_descriptor]
   170  } [packed]
   171  
   172  vusb_connect_string_descriptor {
   173  	len	len[str, int32]
   174  	str	ptr[in, usb_string_descriptor]
   175  } [packed]
   176  
   177  vusb_descriptors {
   178  	len	len[parent, int32]
   179  	generic	ptr[in, vusb_descriptor_generic]
   180  
   181  	string	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]]
   182  	bos	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_BOS, usb_bos_descriptor]]
   183  
   184  	hub_hs	ptr[in, vusb_descriptor_t[USB_TYPE_CLASS, USB_DT_HUB, usb_hub_descriptor_hs]]
   185  	hub_ss	ptr[in, vusb_descriptor_t[USB_TYPE_CLASS, USB_DT_SS_HUB, usb_hub_descriptor_ss]]
   186  } [packed]
   187  
   188  vusb_descriptor_generic {
   189  	req_type	flags[usb_request_types, int8]
   190  	desc_type	flags[usb_descriptor_types, int8]
   191  	len		bytesize[data, int32]
   192  	data		usb_generic_descriptor
   193  } [packed]
   194  
   195  usb_request_types = USB_TYPE_STANDARD, USB_TYPE_CLASS, USB_TYPE_VENDOR
   196  
   197  type vusb_descriptor_t[CLASS, REQ, DATA] {
   198  	type	const[CLASS, int8]
   199  	req	const[REQ, int8]
   200  	len	bytesize[data, int32]
   201  	data	DATA
   202  } [packed]
   203  
   204  # TODO: consider doing lookups based on USB_RECIP values.
   205  vusb_responses {
   206  	len				len[parent, int32]
   207  	generic				ptr[in, vusb_response_generic]
   208  
   209  	get_interface			ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
   210  	get_configuration		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
   211  
   212  # TODO: move these into custom descriptions for hub class when they are added.
   213  	hub_USB_REQ_GET_STATUS_hub	ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_REQ_GET_STATUS, usb_hub_status]]
   214  	hub_USB_REQ_GET_STATUS_port	ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_REQ_GET_STATUS, usb_port_status]]
   215  
   216  # TODO: move these into custom descriptions for asix driver when they are added.
   217  	asix_AX_CMD_READ_MII_REG	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MII_REG, int16]]
   218  	asix_AX_CMD_STATMNGSTS_REG	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_STATMNGSTS_REG, int8]]
   219  	asix_AX_CMD_READ_EEPROM		ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_EEPROM, array[int8, 2]]]
   220  	asix_AX_CMD_READ_RX_CTL		ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_RX_CTL, int16]]
   221  	asix_AX_CMD_READ_NODE_ID	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_NODE_ID, mac_addr]]
   222  	asix_AX88172_CMD_READ_NODE_ID	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX88172_CMD_READ_NODE_ID, mac_addr]]
   223  	asix_AX_CMD_READ_PHY_ID		ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_PHY_ID, array[int8, 2]]]
   224  	asix_AX_CMD_READ_MEDIUM_STATUS	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MEDIUM_STATUS, int16]]
   225  	asix_AX_CMD_READ_MONITOR_MODE	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MONITOR_MODE, int8]]
   226  	asix_AX_CMD_READ_GPIOS		ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_GPIOS, int8]]
   227  	asix_AX_CMD_SW_PHY_STATUS	ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_SW_PHY_STATUS, int8]]
   228  } [packed]
   229  
   230  vusb_response_generic {
   231  	type	flags[usb_request_types, int8]
   232  	req	flags[usb_requests, int8]
   233  	len	bytesize[data, int32]
   234  	data	array[int8, 0:256]
   235  } [packed]
   236  
   237  usb_requests = USB_REQ_GET_STATUS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE, USB_REQ_SET_ADDRESS, USB_REQ_GET_DESCRIPTOR, USB_REQ_SET_DESCRIPTOR, USB_REQ_GET_CONFIGURATION, USB_REQ_SET_CONFIGURATION, USB_REQ_GET_INTERFACE, USB_REQ_SET_INTERFACE, USB_REQ_SYNCH_FRAME, USB_REQ_SET_SEL, USB_REQ_SET_ISOCH_DELAY, USB_REQ_SET_ENCRYPTION, USB_REQ_GET_ENCRYPTION, USB_REQ_RPIPE_ABORT, USB_REQ_SET_HANDSHAKE, USB_REQ_RPIPE_RESET, USB_REQ_GET_HANDSHAKE, USB_REQ_SET_CONNECTION, USB_REQ_SET_SECURITY_DATA, USB_REQ_GET_SECURITY_DATA, USB_REQ_SET_WUSB_DATA, USB_REQ_LOOPBACK_DATA_WRITE, USB_REQ_LOOPBACK_DATA_READ, USB_REQ_SET_INTERFACE_DS, USB_REQ_GET_PARTNER_PDO, USB_REQ_GET_BATTERY_STATUS, USB_REQ_SET_PDO, USB_REQ_GET_VDM, USB_REQ_SEND_VDM
   238  
   239  type vusb_response_t[CLASS, REQ, DATA] {
   240  	type	const[CLASS, int8]
   241  	req	const[REQ, int8]
   242  	len	bytesize[data, int32]
   243  	data	DATA
   244  } [packed]
   245  
   246  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   247  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   248  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   249  
   250  # USB descriptors requested by the kernel before the SET_CONFIGURATION request.
   251  
   252  # TODO: figure out when is the USB_DT_OTG descriptor used.
   253  # TODO: figure out when is the USB_DT_INTERFACE_ASSOCIATION descriptor used.
   254  # TODO: figure out when is the USB_DT_BOS descriptor used.
   255  
   256  type usb_string_descriptor_t[DATA] {
   257  	bLength		len[parent, int8]
   258  	bDescriptorType	const[USB_DT_STRING, int8]
   259  
   260  	data		DATA
   261  } [packed]
   262  
   263  usb_string_descriptor [
   264  	lang_id	usb_string_descriptor_t[flags[usb_lang_ids, int16]]
   265  	string	usb_string_descriptor_t[array[int8, 0:256]]
   266  ] [varlen]
   267  
   268  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
   269  
   270  usb_qualifier_descriptor {
   271  	bLength			len[parent, int8]
   272  	bDescriptorType		const[USB_DT_DEVICE_QUALIFIER, int8]
   273  
   274  	bcdUSB			flags[usb_versions, int16]
   275  	bDeviceClass		int8
   276  	bDeviceSubClass		int8
   277  	bDeviceProtocol		int8
   278  	bMaxPacketSize0		flags[usb_device_max_packet_sizes, int8]
   279  	bNumConfigurations	int8
   280  	bRESERVED		const[0, int8]
   281  } [packed]
   282  
   283  usb_bos_descriptor {
   284  	bLength		const[USB_DT_BOS_SIZE, int8]
   285  	bDescriptorType	const[USB_DT_BOS, int8]
   286  
   287  	wTotalLength	len[parent, int16]
   288  	bNumDeviceCaps	len[caps, int8]
   289  
   290  	caps		array[usb_dev_cap, 0:6]
   291  } [packed]
   292  
   293  usb_dev_cap [
   294  	generic		usb_generic_cap_descriptor
   295  	wireless	usb_wireless_cap_descriptor
   296  	ext_cap		usb_ext_cap_descriptor
   297  	ss_cap		usb_ss_cap_descriptor
   298  	ss_container_id	usb_ss_container_id_descriptor
   299  	ssp_cap		usb_ssp_cap_descriptor
   300  	ptm_cap		usb_ptm_cap_descriptor
   301  ] [varlen]
   302  
   303  usb_generic_cap_descriptor {
   304  	bLength			len[parent, int8]
   305  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   306  	bDevCapabilityType	flags[usb_capability_types, int8]
   307  
   308  	data			array[int8, 0:256]
   309  } [packed]
   310  
   311  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
   312  
   313  usb_wireless_cap_descriptor {
   314  	bLength			len[parent, int8]
   315  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   316  	bDevCapabilityType	const[USB_CAP_TYPE_WIRELESS_USB, int8]
   317  
   318  	bmAttributes		flags[usb_wireless_cap_attributes, int8]
   319  	wPHYRates		flags[usb_wireless_cap_phyrates, int16]
   320  	bmTFITXPowerInfo	int8
   321  	bmFFITXPowerInfo	int8
   322  	bmBandGroup		int16
   323  	bReserved		int8
   324  } [packed]
   325  
   326  usb_wireless_cap_attributes = USB_WIRELESS_P2P_DRD, USB_WIRELESS_BEACON_MASK, USB_WIRELESS_BEACON_SELF, USB_WIRELESS_BEACON_DIRECTED, USB_WIRELESS_BEACON_NONE
   327  
   328  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
   329  
   330  usb_ext_cap_descriptor {
   331  	bLength			len[parent, int8]
   332  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   333  	bDevCapabilityType	const[USB_CAP_TYPE_EXT, int8]
   334  
   335  	bmAttributes1		flags[usb_ext_cap_attributes, int32:8]
   336  	bmAttributes2		int32:4
   337  	bmAttributes3		int32:4
   338  	bmAttributes4		int32:16
   339  } [packed]
   340  
   341  usb_ext_cap_attributes = USB_LPM_SUPPORT, USB_BESL_SUPPORT, USB_BESL_BASELINE_VALID, USB_BESL_DEEP_VALID
   342  
   343  usb_ss_cap_descriptor {
   344  	bLength			len[parent, int8]
   345  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   346  	bDevCapabilityType	const[USB_SS_CAP_TYPE, int8]
   347  
   348  	bmAttributes		flags[usb_ss_cap_attributes, int8]
   349  	wSpeedSupported		flags[usb_ss_cap_speed, int16]
   350  	bFunctionalitySupport	int8
   351  	bU1devExitLat		int8
   352  	bU2DevExitLat		int16
   353  } [packed]
   354  
   355  usb_ss_cap_attributes = USB_LTM_SUPPORT
   356  
   357  usb_ss_cap_speed = USB_LOW_SPEED_OPERATION, USB_FULL_SPEED_OPERATION, USB_HIGH_SPEED_OPERATION, USB_5GBPS_OPERATION
   358  
   359  usb_ss_container_id_descriptor {
   360  	bLength			len[parent, int8]
   361  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   362  	bDevCapabilityType	const[CONTAINER_ID_TYPE, int8]
   363  
   364  	bReserved		int8
   365  	ContainerID		array[int8, 16]
   366  } [packed]
   367  
   368  usb_ssp_cap_descriptor {
   369  	bLength				len[parent, int8]
   370  	bDescriptorType			const[USB_DT_DEVICE_CAPABILITY, int8]
   371  	bDevCapabilityType		const[USB_SSP_CAP_TYPE, int8]
   372  
   373  	bReserved			int8
   374  	bmAttributesSublinkSpeeds	len[bmSublinkSpeedAttr, int32:5]
   375  	bmAttributesSpeedIDs		int32:27
   376  	wFunctionalitySupport		flags[usb_ssp_cap_funcs, int16]
   377  	wReserved			int16
   378  	bmSublinkSpeedAttr		array[flags[usb_ssp_cap_sublink_speeds, int32], 0:6]
   379  } [packed]
   380  
   381  usb_ssp_cap_funcs = USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID, USB_SSP_MIN_RX_LANE_COUNT, USB_SSP_MIN_TX_LANE_COUNT
   382  
   383  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
   384  
   385  usb_ptm_cap_descriptor {
   386  	bLength			len[parent, int8]
   387  	bDescriptorType		const[USB_DT_DEVICE_CAPABILITY, int8]
   388  	bDevCapabilityType	const[USB_PTM_CAP_TYPE, int8]
   389  } [packed]
   390  
   391  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   392  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   393  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   394  
   395  # Extra USB descriptors that come after an interface or an endpoint descriptor.
   396  
   397  # TODO: consider removing class specific descriptors here for described classes.
   398  usb_interface_extra_descriptor [
   399  	generic		usb_generic_descriptor
   400  	hid_hid		usb_hid_descriptor_hid
   401  	cdc_ecm		usb_cdc_header_ecm
   402  	cdc_ncm		usb_cdc_header_ncm
   403  	uac_control	uac_control_iface_extra_descriptors
   404  	uac_as		uac_as_iface_extra_descriptors
   405  ] [varlen]
   406  
   407  usb_endpoint_extra_descriptor [
   408  	generic	usb_generic_descriptor
   409  	uac_iso	uac_iso_endpoint_descriptor
   410  ] [varlen]
   411  
   412  usb_generic_descriptor {
   413  	bLength		len[parent, int8]
   414  	bDescriptorType	flags[usb_descriptor_types, int8]
   415  
   416  	data		array[int8, 0:256]
   417  } [packed]
   418  
   419  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
   420  
   421  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   422  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   423  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   424  
   425  # USB descriptors requested after the SET_CONFIGURATION request.
   426  
   427  usb_hub_descriptor_hs {
   428  	bDescLength		len[parent, int8]
   429  	bDescriptorType		const[USB_DT_HUB, int8]
   430  
   431  	bNbrPorts		int8
   432  	wHubCharacteristics	flags[usb_hub_characteristics, int16]
   433  	bPwrOn2PwrGood		int8
   434  	bHubContrCurrent	int8
   435  
   436  	DeviceRemovable		array[int8, USB_HUB_PORTS_BITS]
   437  	PortPwrCtrlMask		array[int8, USB_HUB_PORTS_BITS]
   438  } [packed]
   439  
   440  usb_hub_descriptor_ss {
   441  	bDescLength		len[parent, int8]
   442  	bDescriptorType		const[USB_DT_SS_HUB, int8]
   443  
   444  	bNbrPorts		int8
   445  	wHubCharacteristics	flags[usb_hub_characteristics, int16]
   446  	bPwrOn2PwrGood		int8
   447  	bHubContrCurrent	int8
   448  
   449  	bHubHdrDecLat		int8
   450  	wHubDelay		int16
   451  	DeviceRemovable		int16
   452  } [packed]
   453  
   454  define USB_HUB_PORTS_BITS	((USB_MAXCHILDREN + 1 + 7) / 8)
   455  
   456  usb_hub_characteristics = HUB_CHAR_LPSM, HUB_CHAR_COMMON_LPSM, HUB_CHAR_INDV_PORT_LPSM, HUB_CHAR_NO_LPSM, HUB_CHAR_COMPOUND, HUB_CHAR_OCPM, HUB_CHAR_COMMON_OCPM, HUB_CHAR_INDV_PORT_OCPM, HUB_CHAR_NO_OCPM, HUB_CHAR_TTTT, HUB_CHAR_PORTIND
   457  
   458  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   459  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   460  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   461  
   462  # Replies to USB control requests requested after the SET_CONFIGURATION request.
   463  
   464  usb_port_status {
   465  	wPortStatus	flags[usb_port_status_flags, int16]
   466  	wPortChange	flags[usb_port_change_flags, int16]
   467  	dwExtPortStatus	array[flags[usb_ext_port_status_flags, int32], 0:1]
   468  } [packed]
   469  
   470  usb_port_status_flags = USB_PORT_STAT_CONNECTION, USB_PORT_STAT_ENABLE, USB_PORT_STAT_SUSPEND, USB_PORT_STAT_OVERCURRENT, USB_PORT_STAT_RESET, USB_PORT_STAT_L1, USB_PORT_STAT_POWER, USB_PORT_STAT_LOW_SPEED, USB_PORT_STAT_HIGH_SPEED, USB_PORT_STAT_TEST, USB_PORT_STAT_INDICATOR, USB_PORT_STAT_LINK_STATE, USB_SS_PORT_STAT_POWER, USB_SS_PORT_STAT_SPEED, USB_PORT_STAT_SPEED_5GBPS, USB_SS_PORT_LS_U0, USB_SS_PORT_LS_U1, USB_SS_PORT_LS_U2, USB_SS_PORT_LS_U3, USB_SS_PORT_LS_SS_DISABLED, USB_SS_PORT_LS_RX_DETECT, USB_SS_PORT_LS_SS_INACTIVE, USB_SS_PORT_LS_POLLING, USB_SS_PORT_LS_RECOVERY, USB_SS_PORT_LS_HOT_RESET, USB_SS_PORT_LS_COMP_MOD, USB_SS_PORT_LS_LOOPBACK
   471  
   472  usb_port_change_flags = USB_PORT_STAT_C_CONNECTION, USB_PORT_STAT_C_ENABLE, USB_PORT_STAT_C_SUSPEND, USB_PORT_STAT_C_OVERCURRENT, USB_PORT_STAT_C_RESET, USB_PORT_STAT_C_L1, USB_PORT_STAT_C_BH_RESET, USB_PORT_STAT_C_LINK_STATE, USB_PORT_STAT_C_CONFIG_ERROR
   473  
   474  usb_ext_port_status_flags = USB_EXT_PORT_STAT_RX_SPEED_ID, USB_EXT_PORT_STAT_TX_SPEED_ID, USB_EXT_PORT_STAT_RX_LANES, USB_EXT_PORT_STAT_TX_LANES
   475  
   476  usb_hub_status {
   477  	wHubStatus	flags[usb_hub_status_flags, int16]
   478  	wHubChange	flags[usb_hub_change_flags, int16]
   479  } [packed]
   480  
   481  usb_hub_status_flags = HUB_STATUS_LOCAL_POWER, HUB_STATUS_OVERCURRENT
   482  
   483  usb_hub_change_flags = HUB_CHANGE_LOCAL_POWER, HUB_CHANGE_OVERCURRENT
   484  
   485  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   486  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   487  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   488  
   489  # HID device class specific descriptions.
   490  # https://www.usb.org/sites/default/files/documents/hid1_11.pdf
   491  # https://elixir.bootlin.com/linux/latest/source/drivers/hid/usbhid/hid-core.c
   492  # https://elixir.bootlin.com/linux/latest/source/drivers/hid/hid-core.c
   493  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/hid.c
   494  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_hid.c
   495  
   496  # Connected HID devices are known to create the following /dev/ files:
   497  # /dev/hidraw#, /dev/usb/hiddev# and /dev/input/event#.
   498  
   499  resource fd_usb_hid[fd_usb]
   500  
   501  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_usb_hid (timeout[3000], prog_timeout[3000])
   502  syz_usb_control_io$hid(fd fd_usb_hid, descs ptr[in, vusb_descriptors_hid], resps ptr[in, vusb_responses_hid]) (timeout[300])
   503  
   504  # idVendor and idProduct are patched by Go code, see sys/linux/init_vusb.go.
   505  usb_device_descriptor_hid {
   506  	inner	usb_device_descriptor_t[0, 0, 0, 0, 0, 64, array[usb_config_descriptor_hid, 1]]
   507  } [packed]
   508  
   509  usb_config_descriptor_hid {
   510  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_hid, 1]]
   511  } [packed]
   512  
   513  usb_interface_descriptor_hid {
   514  	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]
   515  } [packed]
   516  
   517  usb_hid_protocols = USB_INTERFACE_PROTOCOL_KEYBOARD, USB_INTERFACE_PROTOCOL_MOUSE
   518  
   519  usb_endpoint_descriptors_hid {
   520  	in	usb_endpoint_descriptor_hid_in
   521  	out	array[usb_endpoint_descriptor_hid_out, 0:1]
   522  } [packed]
   523  
   524  usb_endpoint_descriptor_hid_in {
   525  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_IN_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void]
   526  } [packed]
   527  
   528  usb_endpoint_descriptor_hid_out {
   529  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_OUT_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void]
   530  } [packed]
   531  
   532  define USB_ENDPOINT_HID_ATTRIBUTES	(USB_ENDPOINT_XFER_INT)
   533  define USB_ENDPOINT_HID_IN_ADDRESS	(1 | USB_DIR_IN)
   534  define USB_ENDPOINT_HID_OUT_ADDRESS	(2)
   535  
   536  vusb_descriptors_hid {
   537  	len		len[parent, int32]
   538  	generic		ptr[in, vusb_descriptor_generic]
   539  
   540  	USB_DT_STRING	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]]
   541  
   542  # For unknown reasons these are requested as USB_TYPE_STANDARD and not as USB_TYPE_CLASS.
   543  # Linux doesn't request HID_DT_HID, but some hosts might do that.
   544  	HID_DT_REPORT	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, HID_DT_REPORT, hid_descriptor_report]]
   545  	HID_DT_HID	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, HID_DT_HID, usb_hid_descriptor_hid]]
   546  } [packed]
   547  
   548  vusb_responses_hid {
   549  	len				len[parent, int32]
   550  	generic				ptr[in, vusb_response_generic]
   551  
   552  	USB_REQ_GET_INTERFACE		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
   553  	USB_REQ_GET_CONFIGURATION	ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
   554  
   555  	HID_REQ_GET_REPORT		ptr[in, vusb_response_t[USB_TYPE_CLASS, HID_REQ_GET_REPORT, array[int8, 0:256]]]
   556  	HID_REQ_GET_PROTOCOL		ptr[in, vusb_response_t[USB_TYPE_CLASS, HID_REQ_GET_PROTOCOL, int8]]
   557  } [packed]
   558  
   559  # USB HID specifications allows for multiple report and physical descriptors
   560  # to be present, but I don't see any support for them in the Linux kernel,
   561  # except for a single report descriptor.
   562  usb_hid_descriptor_hid {
   563  	bLength		len[parent, int8]
   564  	bDescriptorType	const[HID_DT_HID, int8]
   565  
   566  	bcdHID		int16
   567  	bCountryCode	int8
   568  	bNumDescriptors	const[1, int8]
   569  
   570  	report_desc	usb_hid_class_descriptor_report
   571  } [packed]
   572  
   573  usb_hid_class_descriptor_report {
   574  	bDescriptorType		const[HID_DT_REPORT, int8]
   575  	wDescriptorLength	int16[0:HID_MAX_DESCRIPTOR_SIZE]
   576  } [packed]
   577  
   578  # TODO: it's hard to describe the REPORT descriptor structure via syzkaller
   579  # descriptions, so consider generating it in Go code.
   580  # TODO: the length of REPORT descriptor must match the value in HID descriptor.
   581  # TODO: there are vendor specific REPORT descriptor formats (Logitech HID++).
   582  
   583  # Linux HID stack doesn't support long items.
   584  hid_descriptor_report {
   585  	items	array[hid_report_item_short]
   586  } [packed]
   587  
   588  type hid_report_item_short_012_t[TYPE, TAGS] {
   589  	bSize	len[data, int8:2]
   590  	bType	const[TYPE, int8:2]
   591  	bTag	flags[TAGS, int8:4]
   592  	data	array[int8, 0:2]
   593  } [packed]
   594  
   595  type hid_report_item_short_4_t[TYPE, TAGS] {
   596  	bSize	const[3, int8:2]
   597  	bType	const[TYPE, int8:2]
   598  	bTag	flags[TAGS, int8:4]
   599  	data	array[int8, 4]
   600  } [packed]
   601  
   602  type hid_report_item_short_t[TYPE, TAGS] [
   603  	item_012	hid_report_item_short_012_t[TYPE, TAGS]
   604  	item_4		hid_report_item_short_4_t[TYPE, TAGS]
   605  ] [varlen]
   606  
   607  hid_report_item_short [
   608  	main	hid_report_item_short_t[HID_ITEM_TYPE_MAIN, hid_report_item_main_tags]
   609  	global	hid_report_item_short_t[HID_ITEM_TYPE_GLOBAL, hid_report_item_global_tags]
   610  	local	hid_report_item_short_t[HID_ITEM_TYPE_LOCAL, hid_report_item_local_tags]
   611  ] [varlen]
   612  
   613  hid_report_item_main_tags = HID_MAIN_ITEM_TAG_INPUT, HID_MAIN_ITEM_TAG_OUTPUT, HID_MAIN_ITEM_TAG_FEATURE, HID_MAIN_ITEM_TAG_BEGIN_COLLECTION, HID_MAIN_ITEM_TAG_END_COLLECTION
   614  hid_report_item_global_tags = HID_GLOBAL_ITEM_TAG_USAGE_PAGE, HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM, HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM, HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM, HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM, HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT, HID_GLOBAL_ITEM_TAG_UNIT, HID_GLOBAL_ITEM_TAG_REPORT_SIZE, HID_GLOBAL_ITEM_TAG_REPORT_ID, HID_GLOBAL_ITEM_TAG_REPORT_COUNT, HID_GLOBAL_ITEM_TAG_PUSH, HID_GLOBAL_ITEM_TAG_POP
   615  hid_report_item_local_tags = HID_LOCAL_ITEM_TAG_USAGE, HID_LOCAL_ITEM_TAG_USAGE_MINIMUM, HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM, HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX, HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM, HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM, HID_LOCAL_ITEM_TAG_STRING_INDEX, HID_LOCAL_ITEM_TAG_STRING_MINIMUM, HID_LOCAL_ITEM_TAG_STRING_MAXIMUM, HID_LOCAL_ITEM_TAG_DELIMITER
   616  
   617  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   618  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   619  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   620  
   621  # PRINTER device class specific descriptions.
   622  # https://www.usb.org/sites/default/files/usbprint11a021811.pdf
   623  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/class/usblp.c
   624  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/printer.c
   625  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_printer.c
   626  
   627  # Connected PRINTER devices are known to create the following /dev/ files:
   628  # /dev/usb/lp#.
   629  # TODO: write descriptions for those.
   630  
   631  # drivers/usb/class/usblp.c
   632  define USBLP_REQ_GET_ID	0x00
   633  define USBLP_REQ_GET_STATUS	0x01
   634  define USBLP_REQ_RESET	0x02
   635  define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	0x00
   636  define USBLP_FIRST_PROTOCOL	1
   637  define USBLP_LAST_PROTOCOL	3
   638  
   639  resource fd_usb_printer[fd_usb]
   640  
   641  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_usb_printer (timeout[3000], prog_timeout[3000])
   642  syz_usb_control_io$printer(fd fd_usb_printer, descs ptr[in, vusb_descriptors_printer], resps ptr[in, vusb_responses_printer]) (timeout[300])
   643  
   644  usb_device_descriptor_printer {
   645  	inner	usb_device_descriptor_t[0, 0, 0, 0x525, 0xa4a8, 64, array[usb_config_descriptor_printer, 1]]
   646  } [packed]
   647  
   648  usb_config_descriptor_printer {
   649  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_printer, 1]]
   650  } [packed]
   651  
   652  usb_interface_descriptor_printer {
   653  	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]
   654  } [packed]
   655  
   656  usb_endpoint_descriptors_printer {
   657  	in	usb_endpoint_descriptor_printer_out
   658  	out	array[usb_endpoint_descriptor_printer_in, 0:1]
   659  } [packed]
   660  
   661  usb_endpoint_descriptor_printer_out {
   662  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_OUT_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void]
   663  } [packed]
   664  
   665  usb_endpoint_descriptor_printer_in {
   666  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_IN_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void]
   667  } [packed]
   668  
   669  define USB_ENDPOINT_PRINTER_ATTRIBUTES	(USB_ENDPOINT_XFER_BULK)
   670  define USB_ENDPOINT_PRINTER_OUT_ADDRESS	(1)
   671  define USB_ENDPOINT_PRINTER_IN_ADDRESS	(2 | USB_DIR_IN)
   672  
   673  vusb_descriptors_printer {
   674  	len		len[parent, int32]
   675  	generic		ptr[in, vusb_descriptor_generic]
   676  
   677  	USB_DT_STRING	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]]
   678  } [packed]
   679  
   680  vusb_responses_printer {
   681  	len					len[parent, int32]
   682  	generic					ptr[in, vusb_response_generic]
   683  
   684  	USB_REQ_GET_INTERFACE			ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
   685  	USB_REQ_GET_CONFIGURATION		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
   686  
   687  	USBLP_REQ_GET_ID			ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_GET_ID, usb_printer_get_id_response]]
   688  	USBLP_REQ_GET_STATUS			ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_GET_STATUS, int8]]
   689  	USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST	ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, int8]]
   690  } [packed]
   691  
   692  usb_printer_get_id_response {
   693  	length	len[id, int16be]
   694  	id	array[int8, 0:256]
   695  } [packed]
   696  
   697  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   698  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   699  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   700  
   701  # CDC ECM (Ethernet) device class specific descriptions.
   702  # https://www.usb.org/document-library/class-definitions-communication-devices-12
   703  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ether.c
   704  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c
   705  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ether.c
   706  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ecm.c
   707  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_ether.c
   708  
   709  # Connected CDC ECM devices are known to create usbN network interfaces.
   710  # TODO: write descriptions for those.
   711  
   712  resource fd_usb_cdc_ecm[fd_usb]
   713  
   714  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_cdc_ecm (timeout[3000], prog_timeout[3000])
   715  syz_usb_control_io$cdc_ecm(fd fd_usb_cdc_ecm, descs ptr[in, vusb_descriptors_cdc_ecm], resps ptr[in, vusb_responses_cdc_ecm]) (timeout[300])
   716  
   717  usb_device_descriptor_cdc_ecm {
   718  	inner	usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ecm, 1]]
   719  } [packed]
   720  
   721  usb_config_descriptor_cdc_ecm {
   722  	inner	usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_cdc_ecm, 1]]
   723  } [packed]
   724  
   725  # Per specification CDC ECM devices have two interfaces (control and data),
   726  # but here we're merging them into one for simplicity since Linux supports that.
   727  usb_interface_descriptor_cdc_ecm {
   728  	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]
   729  } [packed]
   730  
   731  usb_endpoint_descriptors_cdc_ecm {
   732  	notify	array[usb_endpoint_descriptor_cdc_ecm_notify, 0:1]
   733  	in	usb_endpoint_descriptor_cdc_ecm_in
   734  	out	usb_endpoint_descriptor_cdc_ecm_out
   735  } [packed]
   736  
   737  usb_endpoint_descriptor_cdc_ecm_notify {
   738  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES, int8], void]
   739  } [packed]
   740  
   741  usb_endpoint_descriptor_cdc_ecm_in {
   742  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_IN_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void]
   743  } [packed]
   744  
   745  usb_endpoint_descriptor_cdc_ecm_out {
   746  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_OUT_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void]
   747  } [packed]
   748  
   749  define USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES	(USB_ENDPOINT_XFER_INT)
   750  define USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES	(USB_ENDPOINT_XFER_BULK)
   751  define USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS	(1 | USB_DIR_IN)
   752  define USB_ENDPOINT_CDC_ECM_IN_ADDRESS	(2 | USB_DIR_IN)
   753  define USB_ENDPOINT_CDC_ECM_OUT_ADDRESS	(3)
   754  
   755  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137
   756  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L155
   757  usb_cdc_header_ecm {
   758  	union	usb_cdc_union_desc_t[0, 0]
   759  	header	usb_cdc_header_desc
   760  	ether	usb_cdc_ether_desc
   761  
   762  	other	array[usb_cdc_header_ecm_other, 0:6]
   763  } [packed]
   764  
   765  usb_cdc_header_ecm_other [
   766  	call_mgmt		usb_cdc_call_mgmt_descriptor
   767  	acm			usb_cdc_acm_descriptor
   768  	country_functional	usb_cdc_country_functional_desc
   769  	network_terminal	usb_cdc_network_terminal_desc
   770  	dmm			usb_cdc_dmm_desc
   771  	mdlm			usb_cdc_mdlm_desc
   772  	mdlm_detail		usb_cdc_mdlm_detail_desc
   773  	obex			usb_cdc_obex_desc
   774  	ncm			usb_cdc_ncm_desc
   775  	mbim			usb_cdc_mbim_desc
   776  	mbim_extended		usb_cdc_mbim_extended_desc
   777  ] [varlen]
   778  
   779  usb_cdc_header_desc {
   780  	bLength			len[parent, int8]
   781  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   782  	bDescriptorSubType	const[USB_CDC_HEADER_TYPE, int8]
   783  
   784  	bcdCDC			int16
   785  } [packed]
   786  
   787  usb_cdc_call_mgmt_descriptor {
   788  	bLength			len[parent, int8]
   789  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   790  	bDescriptorSubType	const[USB_CDC_CALL_MANAGEMENT_TYPE, int8]
   791  
   792  	bmCapabilities		flags[usb_cdc_call_mgmt_caps, int8]
   793  	bDataInterface		int8
   794  } [packed]
   795  
   796  usb_cdc_call_mgmt_caps = USB_CDC_CALL_MGMT_CAP_CALL_MGMT, USB_CDC_CALL_MGMT_CAP_DATA_INTF
   797  
   798  usb_cdc_acm_descriptor {
   799  	bLength			len[parent, int8]
   800  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   801  	bDescriptorSubType	const[USB_CDC_ACM_TYPE, int8]
   802  
   803  	bmCapabilities		flags[usb_cdc_acm_caps, int8]
   804  } [packed]
   805  
   806  usb_cdc_acm_caps = USB_CDC_COMM_FEATURE, USB_CDC_CAP_LINE, USB_CDC_CAP_BRK, USB_CDC_CAP_NOTIFY
   807  
   808  type usb_cdc_union_desc_t[MASTER, SLAVE] {
   809  	bLength			len[parent, int8]
   810  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   811  	bDescriptorSubType	const[USB_CDC_UNION_TYPE, int8]
   812  
   813  	bMasterInterface0	const[MASTER, int8]
   814  	bSlaveInterface0	const[SLAVE, int8]
   815  	slave_interfaces	array[int8, 0:6]
   816  } [packed]
   817  
   818  usb_cdc_country_functional_desc {
   819  	bLength			len[parent, int8]
   820  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   821  	bDescriptorSubType	const[USB_CDC_COUNTRY_TYPE, int8]
   822  
   823  	iCountryCodeRelDate	int8
   824  	wCountyCode0		int16
   825  	country_codes		array[int16, 0:6]
   826  } [packed]
   827  
   828  usb_cdc_network_terminal_desc {
   829  	bLength			len[parent, int8]
   830  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   831  	bDescriptorSubType	const[USB_CDC_NETWORK_TERMINAL_TYPE, int8]
   832  
   833  	bEntityId		int8
   834  	iName			int8
   835  	bChannelIndex		int8
   836  	bPhysicalInterface	int8
   837  } [packed]
   838  
   839  usb_cdc_ether_desc {
   840  	bLength			len[parent, int8]
   841  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   842  	bDescriptorSubType	const[USB_CDC_ETHERNET_TYPE, int8]
   843  
   844  	iMACAddress		const[1, int8]
   845  	bmEthernetStatistics	int32
   846  	wMaxSegmentSize		int16
   847  	wNumberMCFilters	int16
   848  	bNumberPowerFilters	int8
   849  } [packed]
   850  
   851  usb_cdc_dmm_desc {
   852  	bLength			len[parent, int8]
   853  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   854  	bDescriptorSubType	const[USB_CDC_DMM_TYPE, int8]
   855  
   856  	bcdVersion		int16
   857  	wMaxCommand		int16
   858  } [packed]
   859  
   860  usb_cdc_mdlm_desc {
   861  	bLength			len[parent, int8]
   862  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   863  	bDescriptorSubType	const[USB_CDC_MDLM_TYPE, int8]
   864  
   865  	bcdVersion		int16
   866  	bGUID			usb_cdc_ecm_mbm_guid
   867  } [packed]
   868  
   869  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L61
   870  usb_cdc_ecm_mbm_guid {
   871  	id0	const[0x14f5e048ba817a3, int64]
   872  	id1	const[0x2a397ecbffc007a6, int64]
   873  } [packed]
   874  
   875  usb_cdc_mdlm_detail_desc {
   876  	bLength			len[parent, int8]
   877  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   878  	bDescriptorSubType	const[USB_CDC_MDLM_DETAIL_TYPE, int8]
   879  
   880  	bGuidDescriptorType	int8
   881  	bDetailData		array[int8, 0:256]
   882  } [packed]
   883  
   884  usb_cdc_obex_desc {
   885  	bLength			len[parent, int8]
   886  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   887  	bDescriptorSubType	const[USB_CDC_OBEX_TYPE, int8]
   888  
   889  	bcdVersion		int16
   890  } [packed]
   891  
   892  usb_cdc_ncm_desc {
   893  	bLength			len[parent, int8]
   894  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   895  	bDescriptorSubType	const[USB_CDC_NCM_TYPE, int8]
   896  
   897  	bcdNcmVersion		int16
   898  	bmNetworkCapabilities	flags[usb_cdc_ncm_ncaps, int8]
   899  } [packed]
   900  
   901  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
   902  
   903  usb_cdc_mbim_desc {
   904  	bLength			len[parent, int8]
   905  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
   906  	bDescriptorSubType	const[USB_CDC_MBIM_TYPE, int8]
   907  
   908  	bcdMBIMVersion		int16
   909  	wMaxControlMessage	int16
   910  	bNumberFilters		int8
   911  	bMaxFilterSize		int8
   912  	wMaxSegmentSize		int16
   913  	bmNetworkCapabilities	int8
   914  } [packed]
   915  
   916  usb_cdc_mbim_extended_desc {
   917  	bLength				len[parent, int8]
   918  	bDescriptorType			const[USB_DT_CS_INTERFACE, int8]
   919  	bDescriptorSubType		const[USB_CDC_MBIM_EXTENDED_TYPE, int8]
   920  
   921  	bcdMBIMExtendedVersion		int16
   922  	bMaxOutstandingCommandMessages	int8
   923  	wMTU				int16
   924  } [packed]
   925  
   926  vusb_descriptors_cdc_ecm {
   927  	len		len[parent, int32]
   928  	generic		ptr[in, vusb_descriptor_generic]
   929  
   930  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/usbnet.c#L147
   931  	USB_DT_STRING	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor_t[usb_cdc_ecm_mac]]]
   932  } [packed]
   933  
   934  usb_cdc_ecm_mac {
   935  # This is a UTF16 encoded string "424242424242".
   936  	data0	const[0x3400320034003200, int64be]
   937  	data1	const[0x3400320034003200, int64be]
   938  	data2	const[0x3400320034003200, int64be]
   939  } [packed]
   940  
   941  vusb_responses_cdc_ecm {
   942  	len				len[parent, int32]
   943  	generic				ptr[in, vusb_response_generic]
   944  
   945  	USB_REQ_GET_INTERFACE		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
   946  	USB_REQ_GET_CONFIGURATION	ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
   947  } [packed]
   948  
   949  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   950  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   951  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   952  
   953  # CDC NCM class specific descriptions.
   954  # CDC NCM is based on CDC ECM, so some of the descriptions are reused.
   955  # https://www.usb.org/document-library/network-control-model-devices-specification-v10-and-errata-and-adopters-agreement
   956  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ncm.c
   957  # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c
   958  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ncm.c
   959  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ncm.c
   960  
   961  resource fd_usb_cdc_ncm[fd_usb]
   962  
   963  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_cdc_ncm (timeout[3000], prog_timeout[3000])
   964  syz_usb_control_io$cdc_ncm(fd fd_usb_cdc_ncm, descs ptr[in, vusb_descriptors_cdc_ncm], resps ptr[in, vusb_responses_cdc_ncm]) (timeout[300])
   965  
   966  usb_device_descriptor_cdc_ncm {
   967  	inner	usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ncm, 1]]
   968  } [packed]
   969  
   970  usb_config_descriptor_cdc_ncm {
   971  	inner	usb_config_descriptor_t[const[1, int8], const[2, int8], usb_interface_descriptors_cdc_ncm]
   972  } [packed]
   973  
   974  usb_interface_descriptors_cdc_ncm {
   975  	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]
   976  	data_nop	usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, void, void]
   977  	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]
   978  } [packed]
   979  
   980  usb_endpoint_descriptors_cdc_ncm_data {
   981  	in	usb_endpoint_descriptor_cdc_ecm_in
   982  	out	usb_endpoint_descriptor_cdc_ecm_out
   983  } [packed]
   984  
   985  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137
   986  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ncm.c#L798
   987  usb_cdc_header_ncm {
   988  	union	usb_cdc_union_desc_t[0, 1]
   989  	header	usb_cdc_header_desc
   990  	ether	usb_cdc_ether_desc
   991  	ncm	usb_cdc_ncm_desc
   992  
   993  	other	array[usb_cdc_header_ncm_other, 0:6]
   994  } [packed]
   995  
   996  usb_cdc_header_ncm_other [
   997  	call_mgmt		usb_cdc_call_mgmt_descriptor
   998  	acm			usb_cdc_acm_descriptor
   999  	country_functional	usb_cdc_country_functional_desc
  1000  	network_terminal	usb_cdc_network_terminal_desc
  1001  	dmm			usb_cdc_dmm_desc
  1002  	mdlm			usb_cdc_mdlm_desc
  1003  	mdlm_detail		usb_cdc_mdlm_detail_desc
  1004  	obex			usb_cdc_obex_desc
  1005  	mbim			usb_cdc_mbim_desc
  1006  	mbim_extended		usb_cdc_mbim_extended_desc
  1007  ] [varlen]
  1008  
  1009  vusb_descriptors_cdc_ncm {
  1010  	len		len[parent, int32]
  1011  	generic		ptr[in, vusb_descriptor_generic]
  1012  
  1013  # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/usbnet.c#L147
  1014  	USB_DT_STRING	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor_t[usb_cdc_ecm_mac]]]
  1015  } [packed]
  1016  
  1017  vusb_responses_cdc_ncm {
  1018  	len				len[parent, int32]
  1019  	generic				ptr[in, vusb_response_generic]
  1020  
  1021  	USB_REQ_GET_INTERFACE		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
  1022  	USB_REQ_GET_CONFIGURATION	ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
  1023  
  1024  	USB_CDC_GET_NTB_PARAMETERS	ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_PARAMETERS, usb_cdc_ncm_ntb_parameters]]
  1025  	USB_CDC_GET_NTB_INPUT_SIZE	ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_INPUT_SIZE, int32]]
  1026  	USB_CDC_GET_NTB_FORMAT		ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_FORMAT, int16[0:1]]]
  1027  	USB_CDC_GET_MAX_DATAGRAM_SIZE	ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_MAX_DATAGRAM_SIZE, int16]]
  1028  	USB_CDC_GET_CRC_MODE		ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_CRC_MODE, int16[0:1]]]
  1029  } [packed]
  1030  
  1031  usb_cdc_ncm_ntb_parameters {
  1032  	wLength			int16
  1033  	bmNtbFormatsSupported	int16
  1034  	dwNtbInMaxSize		int32
  1035  	wNdpInDivisor		int16
  1036  	wNdpInPayloadRemainder	int16
  1037  	wNdpInAlignment		int16
  1038  	wPadding1		int16
  1039  	dwNtbOutMaxSize		int32
  1040  	wNdpOutDivisor		int16
  1041  	wNdpOutPayloadRemainder	int16
  1042  	wNdpOutAlignment	int16
  1043  	wNtbOutMaxDatagrams	int16
  1044  } [packed]
  1045  
  1046  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1047  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1048  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1049  
  1050  # UAC1 device class specific descriptions.
  1051  # https://www.usb.org/sites/default/files/audio10.pdf
  1052  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/audio.c
  1053  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1.c
  1054  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1_legacy.c
  1055  # https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/usb/audio.h
  1056  
  1057  # TODO: find out which /dev/ files are created by connected UAC1 devices and add descriptions for those.
  1058  
  1059  resource fd_usb_uac1[fd_usb]
  1060  
  1061  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_uac1 (timeout[3000], prog_timeout[3000])
  1062  syz_usb_control_io$uac1(fd fd_usb_uac1, descs ptr[in, vusb_descriptors_uac1], resps ptr[in, vusb_responses_uac1]) (timeout[300])
  1063  
  1064  usb_device_descriptor_uac1 {
  1065  	inner	usb_device_descriptor_t[0, 0, 0, 0x1d6b, 0x101, 64, array[usb_config_descriptor_uac1, 1]]
  1066  } [packed]
  1067  
  1068  usb_config_descriptor_uac1 {
  1069  	inner	usb_config_descriptor_t[const[1, int8], const[3, int8], usb_interface_descriptors_uac1]
  1070  } [packed]
  1071  
  1072  # TODO: control interface might have and optional interrupt endpoint.
  1073  usb_interface_descriptors_uac1 {
  1074  	control		usb_interface_descriptor_fixed_t[0, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOCONTROL, 0, uac_control_iface_extra_descriptors, void]
  1075  	as_out_alt_0	usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void]
  1076  	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]
  1077  	as_in_alt_0	usb_interface_descriptor_fixed_t[2, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void]
  1078  	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]
  1079  } [packed]
  1080  
  1081  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1082  
  1083  # UAC uses IDs to make it possible for terminals and units to refer to each other.
  1084  # We don't have a way to describe this, so just use a limited number of ids.
  1085  type uac_id int8[1:6]
  1086  
  1087  uac_control_iface_extra_descriptors {
  1088  	header	uac1_ac_header_descriptor_2
  1089  	others	array[uac_control_iface_extra_descriptor, 0:6]
  1090  } [packed]
  1091  
  1092  uac_as_iface_extra_descriptors {
  1093  	others	array[uac_as_iface_extra_descriptor, 0:6]
  1094  } [packed]
  1095  
  1096  uac_control_iface_extra_descriptor [
  1097  	input_terminal	uac_input_terminal_descriptor
  1098  	output_terminal	uac1_output_terminal_descriptor
  1099  	mixer_unit	uac_mixer_unit_descriptor
  1100  	selector_unit	uac_selector_unit_descriptor
  1101  	feature_unit	uac_feature_unit_descriptor
  1102  	processing_unit	uac_processing_unit_descriptor
  1103  	extension_unit	uac_extension_unit_descriptor
  1104  ] [varlen]
  1105  
  1106  uac_as_iface_extra_descriptor [
  1107  	as_header			uac1_as_header_descriptor
  1108  	format_type_i_continuous	uac_format_type_i_continuous_descriptor
  1109  	format_type_i_discrete		uac_format_type_i_discrete_descriptor
  1110  	format_type_ii_discrete		uac_format_type_ii_discrete_descriptor
  1111  ] [varlen]
  1112  
  1113  define F_AUDIO_NUM_INTERFACES	2
  1114  define UAC_DT_AC_HEADER_LENGTH	UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES)
  1115  
  1116  uac1_ac_header_descriptor_2 {
  1117  	bLength			const[UAC_DT_AC_HEADER_LENGTH, int8]
  1118  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1119  	bDescriptorSubType	const[UAC_HEADER, int8]
  1120  
  1121  	bcdADC			int16
  1122  	wTotalLength		int8
  1123  	bInCollection		const[F_AUDIO_NUM_INTERFACES, int8]
  1124  
  1125  # These must match interfaces numbers.
  1126  	baInterfaceNr0		const[1, int8]
  1127  	baInterfaceNr1		const[2, int8]
  1128  } [packed]
  1129  
  1130  uac_input_terminal_descriptor {
  1131  	bLength			len[parent, int8]
  1132  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1133  	bDescriptorSubType	const[UAC_INPUT_TERMINAL, int8]
  1134  
  1135  	bTerminalID		uac_id
  1136  	wTerminalType		flags[uac_input_terminal_types, int16]
  1137  	bAssocTerminal		uac_id
  1138  	bNrChannels		int8
  1139  	wChannelConfig		int16
  1140  	iChannelNames		int8
  1141  	iTerminal		int8
  1142  } [packed]
  1143  
  1144  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
  1145  
  1146  uac1_output_terminal_descriptor {
  1147  	bLength			len[parent, int8]
  1148  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1149  	bDescriptorSubType	const[UAC_OUTPUT_TERMINAL, int8]
  1150  
  1151  	bTerminalID		uac_id
  1152  	wTerminalType		flags[uac_output_terminal_types, int16]
  1153  	bAssocTerminal		uac_id
  1154  	bSourceID		uac_id
  1155  	iTerminal		int8
  1156  } [packed]
  1157  
  1158  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
  1159  
  1160  uac_mixer_unit_descriptor {
  1161  	bLength			len[parent, int8]
  1162  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1163  	bDescriptorSubType	const[UAC_MIXER_UNIT, int8]
  1164  
  1165  	bUnitID			uac_id
  1166  	bNrInPins		int8
  1167  	baSourceID		array[int8, 0:6]
  1168  } [packed]
  1169  
  1170  uac_selector_unit_descriptor {
  1171  	bLength			len[parent, int8]
  1172  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1173  	bDescriptorSubType	const[UAC_SELECTOR_UNIT, int8]
  1174  
  1175  	bUnitID			uac_id
  1176  	bNrInPins		int8
  1177  	baSourceID		array[int8, 0:6]
  1178  } [packed]
  1179  
  1180  uac_feature_unit_descriptor {
  1181  	bLength			len[parent, int8]
  1182  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1183  	bDescriptorSubType	const[UAC_FEATURE_UNIT, int8]
  1184  
  1185  	bUnitID			uac_id
  1186  	bSourceID		uac_id
  1187  	bControlSize		len[bmaControls, int8]
  1188  	bmaControls		array[flags[uac_feature_unit_controls, int16], 1:6]
  1189  	iFeature		int8
  1190  } [packed]
  1191  
  1192  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
  1193  
  1194  uac_processing_unit_descriptor {
  1195  	bLength			len[parent, int8]
  1196  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1197  	bDescriptorSubType	const[UAC1_PROCESSING_UNIT, int8]
  1198  
  1199  	bUnitID			uac_id
  1200  	wProcessType		flags[uac_processing_unit_types, int16]
  1201  	bNrInPins		int8
  1202  	baSourceID		array[int8, 0:6]
  1203  } [packed]
  1204  
  1205  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
  1206  
  1207  uac_extension_unit_descriptor {
  1208  	bLength			len[parent, int8]
  1209  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1210  	bDescriptorSubType	const[UAC1_EXTENSION_UNIT, int8]
  1211  
  1212  	bUnitID			uac_id
  1213  	wProcessType		int16
  1214  	bNrInPins		int8
  1215  	baSourceID		array[int8, 0:6]
  1216  } [packed]
  1217  
  1218  uac1_as_header_descriptor {
  1219  	bLength			len[parent, int8]
  1220  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1221  	bDescriptorSubType	const[UAC_AS_GENERAL, int8]
  1222  
  1223  	bTerminalLink		int8
  1224  	bDelay			int8
  1225  	wFormatTag		flags[uac_format_types, int16]
  1226  } [packed]
  1227  
  1228  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
  1229  
  1230  uac_format_type_i_continuous_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  	tLowerSamFreq		array[int8, 0:3]
  1241  	tUpperSamFreq		array[int8, 0:3]
  1242  } [packed]
  1243  
  1244  uac_format_type_i_discrete_descriptor {
  1245  	bLength			len[parent, int8]
  1246  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1247  	bDescriptorSubType	const[UAC_FORMAT_TYPE, int8]
  1248  
  1249  	bFormatType		const[UAC_FORMAT_TYPE_I, int8]
  1250  	bNrChannels		int8
  1251  	bSubframeSize		int8[1:4]
  1252  	bBitResolution		int8
  1253  	bSamFreqType		int8
  1254  	tSamFreq		array[int8, 0:9]
  1255  } [packed]
  1256  
  1257  uac_format_type_ii_discrete_descriptor {
  1258  	bLength			len[parent, int8]
  1259  	bDescriptorType		const[USB_DT_CS_INTERFACE, int8]
  1260  	bDescriptorSubType	const[UAC_FORMAT_TYPE, int8]
  1261  
  1262  	bFormatType		const[UAC_FORMAT_TYPE_II, int8]
  1263  	wMaxBitRate		int16
  1264  	wSamplesPerFrame	int16
  1265  	bSamFreqType		int8
  1266  	tSamFreq		array[int8, 0:9]
  1267  } [packed]
  1268  
  1269  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1270  
  1271  uac_as_out_endpoint_descriptor {
  1272  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_OUT_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor]
  1273  } [packed]
  1274  
  1275  uac_as_in_endpoint_descriptor {
  1276  	inner	usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_IN_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor]
  1277  } [packed]
  1278  
  1279  define USB_ENDPOINT_UAC1_AS_OUT_ADDRESS	(1 | USB_DIR_OUT)
  1280  define USB_ENDPOINT_UAC1_AS_IN_ADDRESS	(2 | USB_DIR_IN)
  1281  define USB_ENDPOINT_UAC1_AS_ATTRIBUTES	(USB_ENDPOINT_SYNC_ADAPTIVE | USB_ENDPOINT_XFER_ISOC)
  1282  
  1283  uac_iso_endpoint_descriptor {
  1284  	bLength			len[parent, int8]
  1285  	bDescriptorType		const[USB_DT_CS_ENDPOINT, int8]
  1286  	bDescriptorSubType	const[UAC_EP_GENERAL, int8]
  1287  
  1288  	bmAttributes		flags[uac_iso_ep_attributes, int8]
  1289  	bLockDelayUnits		int8
  1290  	wLockDelay		int16
  1291  } [packed]
  1292  
  1293  uac_iso_ep_attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, UAC_EP_CS_ATTR_PITCH_CONTROL, UAC_EP_CS_ATTR_FILL_MAX
  1294  
  1295  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1296  
  1297  vusb_descriptors_uac1 {
  1298  	len		len[parent, int32]
  1299  	generic		ptr[in, vusb_descriptor_generic]
  1300  
  1301  	USB_DT_STRING	ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]]
  1302  } [packed]
  1303  
  1304  vusb_responses_uac1 {
  1305  	len				len[parent, int32]
  1306  	generic				ptr[in, vusb_response_generic]
  1307  
  1308  	USB_REQ_GET_INTERFACE		ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]]
  1309  	USB_REQ_GET_CONFIGURATION	ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]]
  1310  
  1311  	audio_UAC_GET_CUR		ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_CUR, array[int8, 1:3]]]
  1312  	audio_UAC_GET_MIN		ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MIN, array[int8, 1:3]]]
  1313  	audio_UAC_GET_MAX		ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MAX, array[int8, 1:3]]]
  1314  	audio_UAC_GET_RES		ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_RES, array[int8, 1:4]]]
  1315  	audio_UAC_GET_MEM		ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MEM, array[int8, 3]]]
  1316  } [packed]
  1317  
  1318  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1319  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1320  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1321  
  1322  # TODO: describe MIDI, UAC2, UAC3
  1323  # https://www.usb.org/sites/default/files/midi10.pdf
  1324  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_midi.c
  1325  # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac2.c
  1326  # https://elixir.bootlin.com/linux/latest/source/include/linux/usb/audio-v2.h
  1327  
  1328  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1329  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1330  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1331  
  1332  # ath9k driver specific descriptions.
  1333  
  1334  include <drivers/net/wireless/ath/ath9k/htc_hst.h>
  1335  include <drivers/net/wireless/ath/ath9k/hif_usb.h>
  1336  
  1337  define USB_ENDPOINT_ATH9K_BULK_OUT_ADDRESS	(1)
  1338  define USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS	(2 | USB_DIR_IN)
  1339  define USB_ENDPOINT_ATH9K_INT_IN_ADDRESS	(3 | USB_DIR_IN)
  1340  define USB_ENDPOINT_ATH9K_INT_OUT_ADDRESS	(4)
  1341  define USB_ENDPOINT_ATH9K_BULK_EXTRA1_ADDRESS	(5)
  1342  define USB_ENDPOINT_ATH9K_BULK_EXTRA2_ADDRESS	(6)
  1343  
  1344  resource fd_usb_ath9k[fd_usb]
  1345  
  1346  syz_usb_connect_ath9k(speed const[USB_SPEED_HIGH], dev_len len[dev], dev ptr[in, usb_device_descriptor_ath9k], conn_descs const[0]) fd_usb_ath9k (timeout[3000], prog_timeout[3000])
  1347  syz_usb_ep_write$ath9k_ep1(fd fd_usb_ath9k, ep const[USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS], len bytesize[data], data ptr[in, ath9k_bulk_frame]) (timeout[300])
  1348  syz_usb_ep_write$ath9k_ep2(fd fd_usb_ath9k, ep const[USB_ENDPOINT_ATH9K_INT_IN_ADDRESS], len bytesize[data], data ptr[in, htc_frame]) (timeout[300])
  1349  
  1350  usb_device_descriptor_ath9k {
  1351  	inner	usb_device_descriptor_fixed_t[0x200, USB_CLASS_VENDOR_SPEC, USB_SUBCLASS_VENDOR_SPEC, 0xff, 64, 0xcf3, 0x9271, 0x108, array[usb_config_descriptor_ath9k, 1]]
  1352  } [packed]
  1353  
  1354  usb_config_descriptor_ath9k {
  1355  	inner	usb_config_descriptor_fixed_t[1, 1, USB_CONFIG_ATT_ONE, 250, usb_interface_descriptor_ath9k]
  1356  } [packed]
  1357  
  1358  usb_interface_descriptor_ath9k {
  1359  	iface	usb_interface_descriptor_fixed_t[0, 0, 6, USB_CLASS_VENDOR_SPEC, 0, 0, void, usb_endpoint_descriptors_ath9k]
  1360  } [packed]
  1361  
  1362  usb_endpoint_descriptors_ath9k {
  1363  	bulk_out	usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_OUT_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void]
  1364  	bulk_in		usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void]
  1365  	int_in		usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_INT_IN_ADDRESS, USB_ENDPOINT_ATH9K_INT_ATTRIBUTES, 64, 1, void]
  1366  	int_out		usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_INT_OUT_ADDRESS, USB_ENDPOINT_ATH9K_INT_ATTRIBUTES, 64, 1, void]
  1367  	bulk_extra1	usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_EXTRA1_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void]
  1368  	bulk_extra2	usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_EXTRA2_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void]
  1369  } [packed]
  1370  
  1371  define USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES	(USB_ENDPOINT_XFER_BULK)
  1372  define USB_ENDPOINT_ATH9K_INT_ATTRIBUTES	(USB_ENDPOINT_XFER_INT)
  1373  
  1374  ath9k_bulk_frame {
  1375  	packets	array[ath9k_bulk_packet]
  1376  } [packed]
  1377  
  1378  ath9k_bulk_packet {
  1379  	pkt_len	len[data, int16]
  1380  	pkt_tag	const[ATH_USB_RX_STREAM_MODE_TAG, int16]
  1381  	data	array[int8]
  1382  } [packed, align[4]]
  1383  
  1384  htc_frame [
  1385  	ready		htc_ready_frame
  1386  	conn_svc_rsp	htc_conn_svc_rsp_frame
  1387  	generic		htc_generic_frame
  1388  ] [varlen]
  1389  
  1390  # This is actually wrong, as the driver is buggy and doesn't skip the header
  1391  # before processing the frame payload, but let's leave it like thise for now.
  1392  htc_ready_frame {
  1393  	endpoint_id	const[0, int8]
  1394  	flags		const[0, int8]
  1395  	payload_len	len[payload, int16be]
  1396  	control		array[int8, 4]
  1397  	payload		htc_ready_msg
  1398  } [packed]
  1399  
  1400  htc_ready_msg {
  1401  	message_id	const[HTC_MSG_READY_ID, int16be]
  1402  	credits		int16be
  1403  	credit_size	int16be
  1404  	max_endpoints	int8
  1405  	pad		int8
  1406  } [packed]
  1407  
  1408  htc_conn_svc_rsp_frame {
  1409  	endpoint_id	const[0, int8]
  1410  	flags		const[0, int8]
  1411  	payload_len	len[payload, int16be]
  1412  	control		array[int8, 4]
  1413  	payload		htc_conn_svc_rspmsg
  1414  } [packed]
  1415  
  1416  htc_conn_svc_rspmsg {
  1417  	message_id	const[HTC_MSG_CONNECT_SERVICE_RESPONSE_ID, int16be]
  1418  	service_id	flags[htc_svcs, int16be]
  1419  	status		const[HTC_SERVICE_SUCCESS, int8]
  1420  	endpoint_id	int8
  1421  	max_msg_len	int16be
  1422  	svc_meta_len	int8
  1423  	pad		int8
  1424  } [packed]
  1425  
  1426  htc_svcs = HTC_CTRL_RSVD_SVC, HTC_LOOPBACK_RSVD_SVC, WMI_CONTROL_SVC, WMI_BEACON_SVC, WMI_CAB_SVC, WMI_UAPSD_SVC, WMI_MGMT_SVC, WMI_DATA_VO_SVC, WMI_DATA_VI_SVC, WMI_DATA_BE_SVC, WMI_DATA_BE_SVC
  1427  
  1428  htc_generic_frame {
  1429  	endpoint_id	int8[0:8]
  1430  	flags		flags[htc_frame_flags, int8]
  1431  	payload_len	len[payload, int16be]
  1432  	control		array[int8, 4]
  1433  	payload		array[int8, 0:256]
  1434  } [packed]
  1435  
  1436  htc_frame_flags = HTC_FLAGS_RECV_TRAILER
  1437  
  1438  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1439  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1440  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #