123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #ifndef QEMU_HW_USB_DESC_H
- #define QEMU_HW_USB_DESC_H
- #include <wchar.h>
- /* binary representation */
- typedef struct USBDescriptor {
- uint8_t bLength;
- uint8_t bDescriptorType;
- union {
- struct {
- uint8_t bcdUSB_lo;
- uint8_t bcdUSB_hi;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t bMaxPacketSize0;
- uint8_t idVendor_lo;
- uint8_t idVendor_hi;
- uint8_t idProduct_lo;
- uint8_t idProduct_hi;
- uint8_t bcdDevice_lo;
- uint8_t bcdDevice_hi;
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
- uint8_t bNumConfigurations;
- } device;
- struct {
- uint8_t bcdUSB_lo;
- uint8_t bcdUSB_hi;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t bMaxPacketSize0;
- uint8_t bNumConfigurations;
- uint8_t bReserved;
- } device_qualifier;
- struct {
- uint8_t wTotalLength_lo;
- uint8_t wTotalLength_hi;
- uint8_t bNumInterfaces;
- uint8_t bConfigurationValue;
- uint8_t iConfiguration;
- uint8_t bmAttributes;
- uint8_t bMaxPower;
- } config;
- struct {
- uint8_t bInterfaceNumber;
- uint8_t bAlternateSetting;
- uint8_t bNumEndpoints;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t iInterface;
- } interface;
- struct {
- uint8_t bEndpointAddress;
- uint8_t bmAttributes;
- uint8_t wMaxPacketSize_lo;
- uint8_t wMaxPacketSize_hi;
- uint8_t bInterval;
- uint8_t bRefresh; /* only audio ep */
- uint8_t bSynchAddress; /* only audio ep */
- } endpoint;
- struct {
- uint8_t bMaxBurst;
- uint8_t bmAttributes;
- uint8_t wBytesPerInterval_lo;
- uint8_t wBytesPerInterval_hi;
- } super_endpoint;
- struct {
- uint8_t wTotalLength_lo;
- uint8_t wTotalLength_hi;
- uint8_t bNumDeviceCaps;
- } bos;
- struct {
- uint8_t bDevCapabilityType;
- union {
- struct {
- uint8_t bmAttributes_1;
- uint8_t bmAttributes_2;
- uint8_t bmAttributes_3;
- uint8_t bmAttributes_4;
- } usb2_ext;
- struct {
- uint8_t bmAttributes;
- uint8_t wSpeedsSupported_lo;
- uint8_t wSpeedsSupported_hi;
- uint8_t bFunctionalitySupport;
- uint8_t bU1DevExitLat;
- uint8_t wU2DevExitLat_lo;
- uint8_t wU2DevExitLat_hi;
- } super;
- } u;
- } cap;
- } u;
- } QEMU_PACKED USBDescriptor;
- struct USBDescID {
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice;
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
- };
- struct USBDescDevice {
- uint16_t bcdUSB;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t bMaxPacketSize0;
- uint8_t bNumConfigurations;
- const USBDescConfig *confs;
- };
- struct USBDescConfig {
- uint8_t bNumInterfaces;
- uint8_t bConfigurationValue;
- uint8_t iConfiguration;
- uint8_t bmAttributes;
- uint8_t bMaxPower;
- /* grouped interfaces */
- uint8_t nif_groups;
- const USBDescIfaceAssoc *if_groups;
- /* "normal" interfaces */
- uint8_t nif;
- const USBDescIface *ifs;
- };
- /* conceptually an Interface Association Descriptor, and releated interfaces */
- struct USBDescIfaceAssoc {
- uint8_t bFirstInterface;
- uint8_t bInterfaceCount;
- uint8_t bFunctionClass;
- uint8_t bFunctionSubClass;
- uint8_t bFunctionProtocol;
- uint8_t iFunction;
- uint8_t nif;
- const USBDescIface *ifs;
- };
- struct USBDescIface {
- uint8_t bInterfaceNumber;
- uint8_t bAlternateSetting;
- uint8_t bNumEndpoints;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t iInterface;
- uint8_t ndesc;
- USBDescOther *descs;
- USBDescEndpoint *eps;
- };
- struct USBDescEndpoint {
- uint8_t bEndpointAddress;
- uint8_t bmAttributes;
- uint16_t wMaxPacketSize;
- uint8_t bInterval;
- uint8_t bRefresh;
- uint8_t bSynchAddress;
- uint8_t is_audio; /* has bRefresh + bSynchAddress */
- uint8_t *extra;
- /* superspeed endpoint companion */
- uint8_t bMaxBurst;
- uint8_t bmAttributes_super;
- uint16_t wBytesPerInterval;
- };
- struct USBDescOther {
- uint8_t length;
- const uint8_t *data;
- };
- struct USBDescMSOS {
- const char *CompatibleID;
- const wchar_t *Label;
- bool SelectiveSuspendEnabled;
- };
- typedef const char *USBDescStrings[256];
- struct USBDesc {
- USBDescID id;
- const USBDescDevice *full;
- const USBDescDevice *high;
- const USBDescDevice *super;
- const char* const *str;
- const USBDescMSOS *msos;
- };
- #define USB_DESC_FLAG_SUPER (1 << 1)
- /* little helpers */
- static inline uint8_t usb_lo(uint16_t val)
- {
- return val & 0xff;
- }
- static inline uint8_t usb_hi(uint16_t val)
- {
- return (val >> 8) & 0xff;
- }
- /* generate usb packages from structs */
- int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
- bool msos, uint8_t *dest, size_t len);
- int usb_desc_device_qualifier(const USBDescDevice *dev,
- uint8_t *dest, size_t len);
- int usb_desc_config(const USBDescConfig *conf, int flags,
- uint8_t *dest, size_t len);
- int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
- uint8_t *dest, size_t len);
- int usb_desc_iface(const USBDescIface *iface, int flags,
- uint8_t *dest, size_t len);
- int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
- uint8_t *dest, size_t len);
- int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
- int usb_desc_msos(const USBDesc *desc, USBPacket *p,
- int index, uint8_t *dest, size_t len);
- /* control message emulation helpers */
- void usb_desc_init(USBDevice *dev);
- void usb_desc_attach(USBDevice *dev);
- void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
- void usb_desc_create_serial(USBDevice *dev);
- const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
- int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
- int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
- int value, uint8_t *dest, size_t len);
- int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
- int request, int value, int index, int length, uint8_t *data);
- #endif /* QEMU_HW_USB_DESC_H */
|