qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

desc.h (8629B)


      1 #ifndef QEMU_HW_USB_DESC_H
      2 #define QEMU_HW_USB_DESC_H
      3 
      4 #include <wchar.h>
      5 
      6 /* binary representation */
      7 typedef struct USBDescriptor {
      8     uint8_t                   bLength;
      9     uint8_t                   bDescriptorType;
     10     union {
     11         struct {
     12             uint8_t           bcdUSB_lo;
     13             uint8_t           bcdUSB_hi;
     14             uint8_t           bDeviceClass;
     15             uint8_t           bDeviceSubClass;
     16             uint8_t           bDeviceProtocol;
     17             uint8_t           bMaxPacketSize0;
     18             uint8_t           idVendor_lo;
     19             uint8_t           idVendor_hi;
     20             uint8_t           idProduct_lo;
     21             uint8_t           idProduct_hi;
     22             uint8_t           bcdDevice_lo;
     23             uint8_t           bcdDevice_hi;
     24             uint8_t           iManufacturer;
     25             uint8_t           iProduct;
     26             uint8_t           iSerialNumber;
     27             uint8_t           bNumConfigurations;
     28         } device;
     29         struct {
     30             uint8_t           bcdUSB_lo;
     31             uint8_t           bcdUSB_hi;
     32             uint8_t           bDeviceClass;
     33             uint8_t           bDeviceSubClass;
     34             uint8_t           bDeviceProtocol;
     35             uint8_t           bMaxPacketSize0;
     36             uint8_t           bNumConfigurations;
     37             uint8_t           bReserved;
     38         } device_qualifier;
     39         struct {
     40             uint8_t           wTotalLength_lo;
     41             uint8_t           wTotalLength_hi;
     42             uint8_t           bNumInterfaces;
     43             uint8_t           bConfigurationValue;
     44             uint8_t           iConfiguration;
     45             uint8_t           bmAttributes;
     46             uint8_t           bMaxPower;
     47         } config;
     48         struct {
     49             uint8_t           bInterfaceNumber;
     50             uint8_t           bAlternateSetting;
     51             uint8_t           bNumEndpoints;
     52             uint8_t           bInterfaceClass;
     53             uint8_t           bInterfaceSubClass;
     54             uint8_t           bInterfaceProtocol;
     55             uint8_t           iInterface;
     56         } interface;
     57         struct {
     58             uint8_t           bEndpointAddress;
     59             uint8_t           bmAttributes;
     60             uint8_t           wMaxPacketSize_lo;
     61             uint8_t           wMaxPacketSize_hi;
     62             uint8_t           bInterval;
     63             uint8_t           bRefresh;        /* only audio ep */
     64             uint8_t           bSynchAddress;   /* only audio ep */
     65         } endpoint;
     66         struct {
     67             uint8_t           bMaxBurst;
     68             uint8_t           bmAttributes;
     69             uint8_t           wBytesPerInterval_lo;
     70             uint8_t           wBytesPerInterval_hi;
     71         } super_endpoint;
     72         struct {
     73             uint8_t           wTotalLength_lo;
     74             uint8_t           wTotalLength_hi;
     75             uint8_t           bNumDeviceCaps;
     76         } bos;
     77         struct {
     78             uint8_t           bDevCapabilityType;
     79             union {
     80                 struct {
     81                     uint8_t   bmAttributes_1;
     82                     uint8_t   bmAttributes_2;
     83                     uint8_t   bmAttributes_3;
     84                     uint8_t   bmAttributes_4;
     85                 } usb2_ext;
     86                 struct {
     87                     uint8_t   bmAttributes;
     88                     uint8_t   wSpeedsSupported_lo;
     89                     uint8_t   wSpeedsSupported_hi;
     90                     uint8_t   bFunctionalitySupport;
     91                     uint8_t   bU1DevExitLat;
     92                     uint8_t   wU2DevExitLat_lo;
     93                     uint8_t   wU2DevExitLat_hi;
     94                 } super;
     95             } u;
     96         } cap;
     97     } u;
     98 } QEMU_PACKED USBDescriptor;
     99 
    100 struct USBDescID {
    101     uint16_t                  idVendor;
    102     uint16_t                  idProduct;
    103     uint16_t                  bcdDevice;
    104     uint8_t                   iManufacturer;
    105     uint8_t                   iProduct;
    106     uint8_t                   iSerialNumber;
    107 };
    108 
    109 struct USBDescDevice {
    110     uint16_t                  bcdUSB;
    111     uint8_t                   bDeviceClass;
    112     uint8_t                   bDeviceSubClass;
    113     uint8_t                   bDeviceProtocol;
    114     uint8_t                   bMaxPacketSize0;
    115     uint8_t                   bNumConfigurations;
    116 
    117     const USBDescConfig       *confs;
    118 };
    119 
    120 struct USBDescConfig {
    121     uint8_t                   bNumInterfaces;
    122     uint8_t                   bConfigurationValue;
    123     uint8_t                   iConfiguration;
    124     uint8_t                   bmAttributes;
    125     uint8_t                   bMaxPower;
    126 
    127     /* grouped interfaces */
    128     uint8_t                   nif_groups;
    129     const USBDescIfaceAssoc   *if_groups;
    130 
    131     /* "normal" interfaces */
    132     uint8_t                   nif;
    133     const USBDescIface        *ifs;
    134 };
    135 
    136 /* conceptually an Interface Association Descriptor, and related interfaces */
    137 struct USBDescIfaceAssoc {
    138     uint8_t                   bFirstInterface;
    139     uint8_t                   bInterfaceCount;
    140     uint8_t                   bFunctionClass;
    141     uint8_t                   bFunctionSubClass;
    142     uint8_t                   bFunctionProtocol;
    143     uint8_t                   iFunction;
    144 
    145     uint8_t                   nif;
    146     const USBDescIface        *ifs;
    147 };
    148 
    149 struct USBDescIface {
    150     uint8_t                   bInterfaceNumber;
    151     uint8_t                   bAlternateSetting;
    152     uint8_t                   bNumEndpoints;
    153     uint8_t                   bInterfaceClass;
    154     uint8_t                   bInterfaceSubClass;
    155     uint8_t                   bInterfaceProtocol;
    156     uint8_t                   iInterface;
    157 
    158     uint8_t                   ndesc;
    159     USBDescOther              *descs;
    160     USBDescEndpoint           *eps;
    161 };
    162 
    163 struct USBDescEndpoint {
    164     uint8_t                   bEndpointAddress;
    165     uint8_t                   bmAttributes;
    166     uint16_t                  wMaxPacketSize;
    167     uint8_t                   bInterval;
    168     uint8_t                   bRefresh;
    169     uint8_t                   bSynchAddress;
    170 
    171     uint8_t                   is_audio; /* has bRefresh + bSynchAddress */
    172     uint8_t                   *extra;
    173 
    174     /* superspeed endpoint companion */
    175     uint8_t                   bMaxBurst;
    176     uint8_t                   bmAttributes_super;
    177     uint16_t                  wBytesPerInterval;
    178 };
    179 
    180 struct USBDescOther {
    181     uint8_t                   length;
    182     const uint8_t             *data;
    183 };
    184 
    185 struct USBDescMSOS {
    186     const char                *CompatibleID;
    187     const wchar_t             *Label;
    188     bool                      SelectiveSuspendEnabled;
    189 };
    190 
    191 typedef const char *USBDescStrings[256];
    192 
    193 struct USBDesc {
    194     USBDescID                 id;
    195     const USBDescDevice       *full;
    196     const USBDescDevice       *high;
    197     const USBDescDevice       *super;
    198     const char* const         *str;
    199     const USBDescMSOS         *msos;
    200 };
    201 
    202 #define USB_DESC_MAX_LEN    8192
    203 #define USB_DESC_FLAG_SUPER (1 << 1)
    204 
    205 /* little helpers */
    206 static inline uint8_t usb_lo(uint16_t val)
    207 {
    208     return val & 0xff;
    209 }
    210 
    211 static inline uint8_t usb_hi(uint16_t val)
    212 {
    213     return (val >> 8) & 0xff;
    214 }
    215 
    216 /* generate usb packages from structs */
    217 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
    218                     bool msos, uint8_t *dest, size_t len);
    219 int usb_desc_device_qualifier(const USBDescDevice *dev,
    220                               uint8_t *dest, size_t len);
    221 int usb_desc_config(const USBDescConfig *conf, int flags,
    222                     uint8_t *dest, size_t len);
    223 int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
    224                          uint8_t *dest, size_t len);
    225 int usb_desc_iface(const USBDescIface *iface, int flags,
    226                    uint8_t *dest, size_t len);
    227 int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
    228                       uint8_t *dest, size_t len);
    229 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
    230 int usb_desc_msos(const USBDesc *desc, USBPacket *p,
    231                   int index, uint8_t *dest, size_t len);
    232 
    233 /* control message emulation helpers */
    234 void usb_desc_init(USBDevice *dev);
    235 void usb_desc_attach(USBDevice *dev);
    236 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
    237 void usb_desc_create_serial(USBDevice *dev);
    238 const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
    239 int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
    240 int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
    241         int value, uint8_t *dest, size_t len);
    242 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
    243         int request, int value, int index, int length, uint8_t *data);
    244 
    245 #endif /* QEMU_HW_USB_DESC_H */