usb: add support for microsoft os descriptors
This patch adds support for special usb descriptors used by microsoft windows. They allow more fine-grained control over driver binding and adding entries to the registry for configuration. As this is a guest-visible change the "msos-desc" compat property has been added to turn this off for 1.7 + older Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
1cf892ca26
commit
5319dc7b42
|
@ -393,6 +393,10 @@ static QEMUMachine pc_i440fx_machine_v1_7 = {
|
||||||
PC_I440FX_1_7_MACHINE_OPTIONS,
|
PC_I440FX_1_7_MACHINE_OPTIONS,
|
||||||
.name = "pc-i440fx-1.7",
|
.name = "pc-i440fx-1.7",
|
||||||
.init = pc_init_pci_1_7,
|
.init = pc_init_pci_1_7,
|
||||||
|
.compat_props = (GlobalProperty[]) {
|
||||||
|
PC_COMPAT_1_7,
|
||||||
|
{ /* end of list */ }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
|
#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# usb subsystem core
|
# usb subsystem core
|
||||||
common-obj-y += core.o combined-packet.o bus.o desc.o
|
common-obj-y += core.o combined-packet.o bus.o desc.o desc-msos.o
|
||||||
common-obj-y += libhw.o
|
common-obj-y += libhw.o
|
||||||
|
|
||||||
# usb host adapters
|
# usb host adapters
|
||||||
|
|
|
@ -16,6 +16,8 @@ static Property usb_props[] = {
|
||||||
DEFINE_PROP_STRING("serial", USBDevice, serial),
|
DEFINE_PROP_STRING("serial", USBDevice, serial),
|
||||||
DEFINE_PROP_BIT("full-path", USBDevice, flags,
|
DEFINE_PROP_BIT("full-path", USBDevice, flags,
|
||||||
USB_DEV_FLAG_FULL_PATH, true),
|
USB_DEV_FLAG_FULL_PATH, true),
|
||||||
|
DEFINE_PROP_BIT("msos-desc", USBDevice, flags,
|
||||||
|
USB_DEV_FLAG_MSOS_DESC_ENABLE, true),
|
||||||
DEFINE_PROP_END_OF_LIST()
|
DEFINE_PROP_END_OF_LIST()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
#include "hw/usb.h"
|
||||||
|
#include "hw/usb/desc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Microsoft OS Descriptors
|
||||||
|
*
|
||||||
|
* Windows tries to fetch some special descriptors with informations
|
||||||
|
* specifically for windows. Presence is indicated using a special
|
||||||
|
* string @ index 0xee. There are two kinds of descriptors:
|
||||||
|
*
|
||||||
|
* compatid descriptor
|
||||||
|
* Used to bind drivers, if usb class isn't specific enougth.
|
||||||
|
* Used for PTP/MTP for example (both share the same usb class).
|
||||||
|
*
|
||||||
|
* properties descriptor
|
||||||
|
* Does carry registry entries. They show up in
|
||||||
|
* HLM\SYSTEM\CurrentControlSet\Enum\USB\<devid>\<serial>\Device Parameters
|
||||||
|
*
|
||||||
|
* Note that Windows caches the stuff it got in the registry, so when
|
||||||
|
* playing with this you have to delete registry subtrees to make
|
||||||
|
* windows query the device again:
|
||||||
|
* HLM\SYSTEM\CurrentControlSet\Control\usbflags
|
||||||
|
* HLM\SYSTEM\CurrentControlSet\Enum\USB
|
||||||
|
* Windows will complain it can't delete entries on the second one.
|
||||||
|
* It has deleted everything it had permissions too, which is enouth
|
||||||
|
* as this includes "Device Parameters".
|
||||||
|
*
|
||||||
|
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff537430.aspx
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
typedef struct msos_compat_hdr {
|
||||||
|
uint32_t dwLength;
|
||||||
|
uint8_t bcdVersion_lo;
|
||||||
|
uint8_t bcdVersion_hi;
|
||||||
|
uint8_t wIndex_lo;
|
||||||
|
uint8_t wIndex_hi;
|
||||||
|
uint8_t bCount;
|
||||||
|
uint8_t reserved[7];
|
||||||
|
} QEMU_PACKED msos_compat_hdr;
|
||||||
|
|
||||||
|
typedef struct msos_compat_func {
|
||||||
|
uint8_t bFirstInterfaceNumber;
|
||||||
|
uint8_t reserved_1;
|
||||||
|
uint8_t compatibleId[8];
|
||||||
|
uint8_t subCompatibleId[8];
|
||||||
|
uint8_t reserved_2[6];
|
||||||
|
} QEMU_PACKED msos_compat_func;
|
||||||
|
|
||||||
|
static int usb_desc_msos_compat(const USBDesc *desc, uint8_t *dest)
|
||||||
|
{
|
||||||
|
msos_compat_hdr *hdr = (void *)dest;
|
||||||
|
msos_compat_func *func;
|
||||||
|
int length = sizeof(*hdr);
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
func = (void *)(dest + length);
|
||||||
|
func->bFirstInterfaceNumber = 0;
|
||||||
|
func->reserved_1 = 0x01;
|
||||||
|
length += sizeof(*func);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
hdr->dwLength = cpu_to_le32(length);
|
||||||
|
hdr->bcdVersion_lo = 0x00;
|
||||||
|
hdr->bcdVersion_hi = 0x01;
|
||||||
|
hdr->wIndex_lo = 0x04;
|
||||||
|
hdr->wIndex_hi = 0x00;
|
||||||
|
hdr->bCount = count;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
typedef struct msos_prop_hdr {
|
||||||
|
uint32_t dwLength;
|
||||||
|
uint8_t bcdVersion_lo;
|
||||||
|
uint8_t bcdVersion_hi;
|
||||||
|
uint8_t wIndex_lo;
|
||||||
|
uint8_t wIndex_hi;
|
||||||
|
uint8_t wCount_lo;
|
||||||
|
uint8_t wCount_hi;
|
||||||
|
} QEMU_PACKED msos_prop_hdr;
|
||||||
|
|
||||||
|
typedef struct msos_prop {
|
||||||
|
uint32_t dwLength;
|
||||||
|
uint32_t dwPropertyDataType;
|
||||||
|
uint8_t dwPropertyNameLength_lo;
|
||||||
|
uint8_t dwPropertyNameLength_hi;
|
||||||
|
uint8_t bPropertyName[];
|
||||||
|
} QEMU_PACKED msos_prop;
|
||||||
|
|
||||||
|
typedef struct msos_prop_data {
|
||||||
|
uint32_t dwPropertyDataLength;
|
||||||
|
uint8_t bPropertyData[];
|
||||||
|
} QEMU_PACKED msos_prop_data;
|
||||||
|
|
||||||
|
typedef enum msos_prop_type {
|
||||||
|
MSOS_REG_SZ = 1,
|
||||||
|
MSOS_REG_EXPAND_SZ = 2,
|
||||||
|
MSOS_REG_BINARY = 3,
|
||||||
|
MSOS_REG_DWORD_LE = 4,
|
||||||
|
MSOS_REG_DWORD_BE = 5,
|
||||||
|
MSOS_REG_LINK = 6,
|
||||||
|
MSOS_REG_MULTI_SZ = 7,
|
||||||
|
} msos_prop_type;
|
||||||
|
|
||||||
|
static int usb_desc_msos_prop_name(struct msos_prop *prop,
|
||||||
|
const wchar_t *name)
|
||||||
|
{
|
||||||
|
int length = wcslen(name) + 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
prop->dwPropertyNameLength_lo = usb_lo(length*2);
|
||||||
|
prop->dwPropertyNameLength_hi = usb_hi(length*2);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
prop->bPropertyName[i*2] = usb_lo(name[i]);
|
||||||
|
prop->bPropertyName[i*2+1] = usb_hi(name[i]);
|
||||||
|
}
|
||||||
|
return length*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_desc_msos_prop_str(uint8_t *dest, msos_prop_type type,
|
||||||
|
const wchar_t *name, const wchar_t *value)
|
||||||
|
{
|
||||||
|
struct msos_prop *prop = (void *)dest;
|
||||||
|
struct msos_prop_data *data;
|
||||||
|
int length = sizeof(*prop);
|
||||||
|
int i, vlen = wcslen(value) + 1;
|
||||||
|
|
||||||
|
prop->dwPropertyDataType = cpu_to_le32(type);
|
||||||
|
length += usb_desc_msos_prop_name(prop, name);
|
||||||
|
data = (void *)(dest + length);
|
||||||
|
|
||||||
|
data->dwPropertyDataLength = cpu_to_le32(vlen*2);
|
||||||
|
length += sizeof(*prop);
|
||||||
|
|
||||||
|
for (i = 0; i < vlen; i++) {
|
||||||
|
data->bPropertyData[i*2] = usb_lo(value[i]);
|
||||||
|
data->bPropertyData[i*2+1] = usb_hi(value[i]);
|
||||||
|
}
|
||||||
|
length += vlen*2;
|
||||||
|
|
||||||
|
prop->dwLength = cpu_to_le32(length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_desc_msos_prop_dword(uint8_t *dest, const wchar_t *name,
|
||||||
|
uint32_t value)
|
||||||
|
{
|
||||||
|
struct msos_prop *prop = (void *)dest;
|
||||||
|
struct msos_prop_data *data;
|
||||||
|
int length = sizeof(*prop);
|
||||||
|
|
||||||
|
prop->dwPropertyDataType = cpu_to_le32(MSOS_REG_DWORD_LE);
|
||||||
|
length += usb_desc_msos_prop_name(prop, name);
|
||||||
|
data = (void *)(dest + length);
|
||||||
|
|
||||||
|
data->dwPropertyDataLength = cpu_to_le32(4);
|
||||||
|
data->bPropertyData[0] = (value) & 0xff;
|
||||||
|
data->bPropertyData[1] = (value >> 8) & 0xff;
|
||||||
|
data->bPropertyData[2] = (value >> 16) & 0xff;
|
||||||
|
data->bPropertyData[3] = (value >> 24) & 0xff;
|
||||||
|
length += sizeof(*prop) + 4;
|
||||||
|
|
||||||
|
prop->dwLength = cpu_to_le32(length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_desc_msos_prop(const USBDesc *desc, uint8_t *dest)
|
||||||
|
{
|
||||||
|
msos_prop_hdr *hdr = (void *)dest;
|
||||||
|
int length = sizeof(*hdr);
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (desc->msos->Label) {
|
||||||
|
/*
|
||||||
|
* Given as example in the specs. Havn't figured yet where
|
||||||
|
* this label shows up in the windows gui.
|
||||||
|
*/
|
||||||
|
length += usb_desc_msos_prop_str(dest+length, MSOS_REG_SZ,
|
||||||
|
L"Label", desc->msos->Label);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc->msos->SelectiveSuspendEnabled) {
|
||||||
|
/*
|
||||||
|
* Signaling remote wakeup capability in the standard usb
|
||||||
|
* descriptors isn't enouth to make windows actually use it.
|
||||||
|
* This is the "Yes, we really mean it" registy entry to flip
|
||||||
|
* the switch in the windows drivers.
|
||||||
|
*/
|
||||||
|
length += usb_desc_msos_prop_dword(dest+length,
|
||||||
|
L"SelectiveSuspendEnabled", 1);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr->dwLength = cpu_to_le32(length);
|
||||||
|
hdr->bcdVersion_lo = 0x00;
|
||||||
|
hdr->bcdVersion_hi = 0x01;
|
||||||
|
hdr->wIndex_lo = 0x05;
|
||||||
|
hdr->wIndex_hi = 0x00;
|
||||||
|
hdr->wCount_lo = usb_lo(count);
|
||||||
|
hdr->wCount_hi = usb_hi(count);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
int usb_desc_msos(const USBDesc *desc, USBPacket *p,
|
||||||
|
int index, uint8_t *dest, size_t len)
|
||||||
|
{
|
||||||
|
void *buf = g_malloc0(4096);
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 0x0004:
|
||||||
|
length = usb_desc_msos_compat(desc, buf);
|
||||||
|
break;
|
||||||
|
case 0x0005:
|
||||||
|
length = usb_desc_msos_prop(desc, buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > len) {
|
||||||
|
length = len;
|
||||||
|
}
|
||||||
|
memcpy(dest, buf, length);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
p->actual_length = length;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
||||||
uint8_t *dest, size_t len)
|
bool msos, uint8_t *dest, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t bLength = 0x12;
|
uint8_t bLength = 0x12;
|
||||||
USBDescriptor *d = (void *)dest;
|
USBDescriptor *d = (void *)dest;
|
||||||
|
@ -19,8 +19,18 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
||||||
d->bLength = bLength;
|
d->bLength = bLength;
|
||||||
d->bDescriptorType = USB_DT_DEVICE;
|
d->bDescriptorType = USB_DT_DEVICE;
|
||||||
|
|
||||||
d->u.device.bcdUSB_lo = usb_lo(dev->bcdUSB);
|
if (msos && dev->bcdUSB < 0x0200) {
|
||||||
d->u.device.bcdUSB_hi = usb_hi(dev->bcdUSB);
|
/*
|
||||||
|
* Version 2.0+ required for microsoft os descriptors to work.
|
||||||
|
* Done this way so msos-desc compat property will handle both
|
||||||
|
* the version and the new descriptors being present.
|
||||||
|
*/
|
||||||
|
d->u.device.bcdUSB_lo = usb_lo(0x0200);
|
||||||
|
d->u.device.bcdUSB_hi = usb_hi(0x0200);
|
||||||
|
} else {
|
||||||
|
d->u.device.bcdUSB_lo = usb_lo(dev->bcdUSB);
|
||||||
|
d->u.device.bcdUSB_hi = usb_hi(dev->bcdUSB);
|
||||||
|
}
|
||||||
d->u.device.bDeviceClass = dev->bDeviceClass;
|
d->u.device.bDeviceClass = dev->bDeviceClass;
|
||||||
d->u.device.bDeviceSubClass = dev->bDeviceSubClass;
|
d->u.device.bDeviceSubClass = dev->bDeviceSubClass;
|
||||||
d->u.device.bDeviceProtocol = dev->bDeviceProtocol;
|
d->u.device.bDeviceProtocol = dev->bDeviceProtocol;
|
||||||
|
@ -499,6 +509,10 @@ void usb_desc_init(USBDevice *dev)
|
||||||
if (desc->super) {
|
if (desc->super) {
|
||||||
dev->speedmask |= USB_SPEED_MASK_SUPER;
|
dev->speedmask |= USB_SPEED_MASK_SUPER;
|
||||||
}
|
}
|
||||||
|
if (desc->msos && (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_ENABLE))) {
|
||||||
|
dev->flags |= (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE);
|
||||||
|
usb_desc_set_string(dev, 0xee, "MSFT100Q");
|
||||||
|
}
|
||||||
usb_desc_setdefaults(dev);
|
usb_desc_setdefaults(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,6 +640,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
|
||||||
int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
|
int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
|
||||||
int value, uint8_t *dest, size_t len)
|
int value, uint8_t *dest, size_t len)
|
||||||
{
|
{
|
||||||
|
bool msos = (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE));
|
||||||
const USBDesc *desc = usb_device_get_usb_desc(dev);
|
const USBDesc *desc = usb_device_get_usb_desc(dev);
|
||||||
const USBDescDevice *other_dev;
|
const USBDescDevice *other_dev;
|
||||||
uint8_t buf[256];
|
uint8_t buf[256];
|
||||||
|
@ -646,7 +661,7 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case USB_DT_DEVICE:
|
case USB_DT_DEVICE:
|
||||||
ret = usb_desc_device(&desc->id, dev->device, buf, sizeof(buf));
|
ret = usb_desc_device(&desc->id, dev->device, msos, buf, sizeof(buf));
|
||||||
trace_usb_desc_device(dev->addr, len, ret);
|
trace_usb_desc_device(dev->addr, len, ret);
|
||||||
break;
|
break;
|
||||||
case USB_DT_CONFIG:
|
case USB_DT_CONFIG:
|
||||||
|
@ -703,6 +718,7 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
|
||||||
int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||||
int request, int value, int index, int length, uint8_t *data)
|
int request, int value, int index, int length, uint8_t *data)
|
||||||
{
|
{
|
||||||
|
bool msos = (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE));
|
||||||
const USBDesc *desc = usb_device_get_usb_desc(dev);
|
const USBDesc *desc = usb_device_get_usb_desc(dev);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
@ -782,6 +798,19 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
|
||||||
trace_usb_set_interface(dev->addr, index, value, ret);
|
trace_usb_set_interface(dev->addr, index, value, ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VendorDeviceRequest | 'Q':
|
||||||
|
if (msos) {
|
||||||
|
ret = usb_desc_msos(desc, p, index, data, length);
|
||||||
|
trace_usb_desc_msos(dev->addr, index, length, ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VendorInterfaceRequest | 'Q':
|
||||||
|
if (msos) {
|
||||||
|
ret = usb_desc_msos(desc, p, index, data, length);
|
||||||
|
trace_usb_desc_msos(dev->addr, index, length, ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define QEMU_HW_USB_DESC_H
|
#define QEMU_HW_USB_DESC_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
/* binary representation */
|
/* binary representation */
|
||||||
typedef struct USBDescriptor {
|
typedef struct USBDescriptor {
|
||||||
|
@ -182,6 +183,11 @@ struct USBDescOther {
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct USBDescMSOS {
|
||||||
|
const wchar_t *Label;
|
||||||
|
bool SelectiveSuspendEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
typedef const char *USBDescStrings[256];
|
typedef const char *USBDescStrings[256];
|
||||||
|
|
||||||
struct USBDesc {
|
struct USBDesc {
|
||||||
|
@ -190,6 +196,7 @@ struct USBDesc {
|
||||||
const USBDescDevice *high;
|
const USBDescDevice *high;
|
||||||
const USBDescDevice *super;
|
const USBDescDevice *super;
|
||||||
const char* const *str;
|
const char* const *str;
|
||||||
|
const USBDescMSOS *msos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USB_DESC_FLAG_SUPER (1 << 1)
|
#define USB_DESC_FLAG_SUPER (1 << 1)
|
||||||
|
@ -207,7 +214,7 @@ static inline uint8_t usb_hi(uint16_t val)
|
||||||
|
|
||||||
/* generate usb packages from structs */
|
/* generate usb packages from structs */
|
||||||
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
||||||
uint8_t *dest, size_t len);
|
bool msos, uint8_t *dest, size_t len);
|
||||||
int usb_desc_device_qualifier(const USBDescDevice *dev,
|
int usb_desc_device_qualifier(const USBDescDevice *dev,
|
||||||
uint8_t *dest, size_t len);
|
uint8_t *dest, size_t len);
|
||||||
int usb_desc_config(const USBDescConfig *conf, int flags,
|
int usb_desc_config(const USBDescConfig *conf, int flags,
|
||||||
|
@ -219,6 +226,8 @@ int usb_desc_iface(const USBDescIface *iface, int flags,
|
||||||
int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
|
int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
|
||||||
uint8_t *dest, size_t len);
|
uint8_t *dest, size_t len);
|
||||||
int usb_desc_other(const USBDescOther *desc, 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 */
|
/* control message emulation helpers */
|
||||||
void usb_desc_init(USBDevice *dev);
|
void usb_desc_init(USBDevice *dev);
|
||||||
|
|
|
@ -241,6 +241,7 @@ uint16_t pvpanic_port(void);
|
||||||
int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
||||||
|
|
||||||
#define PC_Q35_COMPAT_1_7 \
|
#define PC_Q35_COMPAT_1_7 \
|
||||||
|
PC_COMPAT_1_7, \
|
||||||
{\
|
{\
|
||||||
.driver = "hpet",\
|
.driver = "hpet",\
|
||||||
.property = HPET_INTCAP,\
|
.property = HPET_INTCAP,\
|
||||||
|
@ -259,7 +260,15 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
||||||
PC_COMPAT_1_4, \
|
PC_COMPAT_1_4, \
|
||||||
PC_Q35_COMPAT_1_5
|
PC_Q35_COMPAT_1_5
|
||||||
|
|
||||||
|
#define PC_COMPAT_1_7 \
|
||||||
|
{\
|
||||||
|
.driver = TYPE_USB_DEVICE,\
|
||||||
|
.property = "msos-desc",\
|
||||||
|
.value = "no",\
|
||||||
|
}
|
||||||
|
|
||||||
#define PC_COMPAT_1_6 \
|
#define PC_COMPAT_1_6 \
|
||||||
|
PC_COMPAT_1_7, \
|
||||||
{\
|
{\
|
||||||
.driver = "e1000",\
|
.driver = "e1000",\
|
||||||
.property = "mitigation",\
|
.property = "mitigation",\
|
||||||
|
|
|
@ -182,6 +182,7 @@ typedef struct USBDescIface USBDescIface;
|
||||||
typedef struct USBDescEndpoint USBDescEndpoint;
|
typedef struct USBDescEndpoint USBDescEndpoint;
|
||||||
typedef struct USBDescOther USBDescOther;
|
typedef struct USBDescOther USBDescOther;
|
||||||
typedef struct USBDescString USBDescString;
|
typedef struct USBDescString USBDescString;
|
||||||
|
typedef struct USBDescMSOS USBDescMSOS;
|
||||||
|
|
||||||
struct USBDescString {
|
struct USBDescString {
|
||||||
uint8_t index;
|
uint8_t index;
|
||||||
|
@ -208,6 +209,8 @@ struct USBEndpoint {
|
||||||
enum USBDeviceFlags {
|
enum USBDeviceFlags {
|
||||||
USB_DEV_FLAG_FULL_PATH,
|
USB_DEV_FLAG_FULL_PATH,
|
||||||
USB_DEV_FLAG_IS_HOST,
|
USB_DEV_FLAG_IS_HOST,
|
||||||
|
USB_DEV_FLAG_MSOS_DESC_ENABLE,
|
||||||
|
USB_DEV_FLAG_MSOS_DESC_IN_USE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* definition of a USB device */
|
/* definition of a USB device */
|
||||||
|
|
|
@ -402,6 +402,7 @@ usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d,
|
||||||
usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
|
usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
|
||||||
usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
|
usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
|
||||||
usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d"
|
usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d"
|
||||||
|
usb_desc_msos(int addr, int index, int len, int ret) "dev %d msos, index 0x%x, len %d, ret %d"
|
||||||
usb_set_addr(int addr) "dev %d"
|
usb_set_addr(int addr) "dev %d"
|
||||||
usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
|
usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
|
||||||
usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
|
usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
|
||||||
|
|
Loading…
Reference in New Issue