// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
// clang-format off
#include <endian.h>
#include <stdint.h>
#include <zircon/compiler.h>
__BEGIN_CDECLS;
// maximum number of endpoints per device
#define USB_MAX_EPS 32
/* Request Types */
#define USB_DIR_OUT (0 << 7)
#define USB_DIR_IN (1 << 7)
#define USB_DIR_MASK (1 << 7)
#define USB_TYPE_STANDARD (0 << 5)
#define USB_TYPE_CLASS (1 << 5)
#define USB_TYPE_VENDOR (2 << 5)
#define USB_TYPE_MASK (3 << 5)
#define USB_RECIP_DEVICE (0 << 0)
#define USB_RECIP_INTERFACE (1 << 0)
#define USB_RECIP_ENDPOINT (2 << 0)
#define USB_RECIP_OTHER (3 << 0)
#define USB_RECIP_MASK (0x1f << 0)
/* 1.0 Request Values */
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
/* USB device/interface classes */
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_COMM 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGING 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MSC 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC 0x0a
#define USB_CLASS_CCID 0x0b
#define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAGNOSTIC 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_VENDOR 0xFf
#define USB_SUBCLASS_MSC_SCSI 0x06
#define USB_PROTOCOL_MSC_BULK_ONLY 0x50
/* Descriptor Types */
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08
#define USB_DT_INTERFACE_ASSOCIATION 0x0b
#define USB_DT_HID 0x21
#define USB_DT_HIDREPORT 0x22
#define USB_DT_HIDPHYSICAL 0x23
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
#define USB_DT_SS_EP_COMPANION 0x30
#define USB_DT_SS_ISOCH_EP_COMPANION 0x31
/* USB device feature selectors */
#define USB_DEVICE_SELF_POWERED 0x00
#define USB_DEVICE_REMOTE_WAKEUP 0x01
#define USB_DEVICE_TEST_MODE 0x02
/* Configuration attributes (bmAttributes) */
#define USB_CONFIGURATION_REMOTE_WAKEUP 0x20
#define USB_CONFIGURATION_SELF_POWERED 0x40
#define USB_CONFIGURATION_RESERVED_7 0x80 // This bit must be set
/* Endpoint direction (bEndpointAddress) */
#define USB_ENDPOINT_IN 0x80
#define USB_ENDPOINT_OUT 0x00
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_ENDPOINT_NUM_MASK 0x1F
/* Endpoint types (bmAttributes) */
#define USB_ENDPOINT_CONTROL 0x00
#define USB_ENDPOINT_ISOCHRONOUS 0x01
#define USB_ENDPOINT_BULK 0x02
#define USB_ENDPOINT_INTERRUPT 0x03
#define USB_ENDPOINT_TYPE_MASK 0x03
/* Endpoint synchronization type (bmAttributes) */
#define USB_ENDPOINT_NO_SYNCHRONIZATION 0x00
#define USB_ENDPOINT_ASYNCHRONOUS 0x04
#define USB_ENDPOINT_ADAPTIVE 0x08
#define USB_ENDPOINT_SYNCHRONOUS 0x0C
#define USB_ENDPOINT_SYNCHRONIZATION_MASK 0x0C
/* Endpoint usage type (bmAttributes) */
#define USB_ENDPOINT_DATA 0x00
#define USB_ENDPOINT_FEEDBACK 0x10
#define USB_ENDPOINT_IMPLICIT_FEEDBACK 0x20
#define USB_ENDPOINT_USAGE_MASK 0x30
#define USB_ENDPOINT_HALT 0x00
// Values in this set match those used in XHCI and other parts of the USB specification
#define USB_SPEED_UNDEFINED 0
#define USB_SPEED_FULL 1
#define USB_SPEED_LOW 2
#define USB_SPEED_HIGH 3
#define USB_SPEED_SUPER 4
typedef uint32_t usb_speed_t;
/* general USB defines */
typedef struct {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__ ((packed)) usb_setup_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
} __attribute__ ((packed)) usb_descriptor_header_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_DEVICE
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __attribute__ ((packed)) usb_device_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_CONFIG
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} __attribute__ ((packed)) usb_configuration_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_STRING
uint8_t bString[];
} __attribute__ ((packed)) usb_string_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_INTERFACE
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} __attribute__ ((packed)) usb_interface_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_ENDPOINT
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __attribute__ ((packed)) usb_endpoint_descriptor_t;
#define usb_ep_direction(ep) ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
#define usb_ep_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_TYPE_MASK)
#define usb_ep_sync_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_SYNCHRONIZATION_MASK)
// max packet size is in bits 10..0
#define usb_ep_max_packet(ep) (le16toh((ep)->wMaxPacketSize) & 0x07FF)
// for high speed interrupt and isochronous endpoints, additional transactions per microframe
// are in bits 12..11
#define usb_ep_add_mf_transactions(ep) ((le16toh((ep)->wMaxPacketSize) >> 11) & 3)
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_SS_EP_COMPANION
uint8_t bMaxBurst;
uint8_t bmAttributes;
uint16_t wBytesPerInterval;
} __attribute__ ((packed)) usb_ss_ep_comp_descriptor_t;
#define usb_ss_ep_comp_isoc_mult(ep) ((ep)->bmAttributes & 0x3)
#define usb_ss_ep_comp_isoc_comp(ep) (!!((ep)->bmAttributes & 0x80))
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_SS_ISOCH_EP_COMPANION
uint16_t wReserved;
uint32_t dwBytesPerInterval;
} __attribute__ ((packed)) usb_ss_isoch_ep_comp_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_INTERFACE_ASSOCIATION
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} __attribute__ ((packed)) usb_interface_assoc_descriptor_t;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
uint8_t bDescriptorSubType;
} __attribute__ ((packed)) usb_cs_interface_descriptor_t;
__END_CDECLS;