usb network: use new descriptor infrastructure.
Switch the usb network driver over to the new descriptor infrastructure. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
4a1e1bc416
commit
30c7d32a0a
453
hw/usb-net.c
453
hw/usb-net.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "usb-desc.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "qemu-queue.h"
|
#include "qemu-queue.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
@ -89,182 +90,209 @@ enum usbstring_idx {
|
||||||
|
|
||||||
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
|
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
|
||||||
|
|
||||||
/*
|
static const USBDescStrings usb_net_stringtable = {
|
||||||
* mostly the same descriptor as the linux gadget rndis driver
|
[STRING_MANUFACTURER] = "QEMU",
|
||||||
*/
|
[STRING_PRODUCT] = "RNDIS/QEMU USB Network Device",
|
||||||
static const uint8_t qemu_net_dev_descriptor[] = {
|
[STRING_ETHADDR] = "400102030405",
|
||||||
0x12, /* u8 bLength; */
|
[STRING_DATA] = "QEMU USB Net Data Interface",
|
||||||
USB_DT_DEVICE, /* u8 bDescriptorType; Device */
|
[STRING_CONTROL] = "QEMU USB Net Control Interface",
|
||||||
0x00, 0x02, /* u16 bcdUSB; v2.0 */
|
[STRING_RNDIS_CONTROL] = "QEMU USB Net RNDIS Control Interface",
|
||||||
USB_CLASS_COMM, /* u8 bDeviceClass; */
|
[STRING_CDC] = "QEMU USB Net CDC",
|
||||||
0x00, /* u8 bDeviceSubClass; */
|
[STRING_SUBSET] = "QEMU USB Net Subset",
|
||||||
0x00, /* u8 bDeviceProtocol; [ low/full only ] */
|
[STRING_RNDIS] = "QEMU USB Net RNDIS",
|
||||||
0x40, /* u8 bMaxPacketSize0 */
|
[STRING_SERIALNUMBER] = "1",
|
||||||
RNDIS_VENDOR_NUM & 0xff, RNDIS_VENDOR_NUM >> 8, /* u16 idVendor; */
|
|
||||||
RNDIS_PRODUCT_NUM & 0xff, RNDIS_PRODUCT_NUM >> 8, /* u16 idProduct; */
|
|
||||||
0x00, 0x00, /* u16 bcdDevice */
|
|
||||||
STRING_MANUFACTURER, /* u8 iManufacturer; */
|
|
||||||
STRING_PRODUCT, /* u8 iProduct; */
|
|
||||||
STRING_SERIALNUMBER, /* u8 iSerialNumber; */
|
|
||||||
0x02, /* u8 bNumConfigurations; */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t qemu_net_rndis_config_descriptor[] = {
|
static const USBDescIface desc_iface_rndis[] = {
|
||||||
/* Configuration Descriptor */
|
{
|
||||||
0x09, /* u8 bLength */
|
/* RNDIS Control Interface */
|
||||||
USB_DT_CONFIG, /* u8 bDescriptorType */
|
.bInterfaceNumber = 0,
|
||||||
0x43, 0x00, /* le16 wTotalLength */
|
.bNumEndpoints = 1,
|
||||||
0x02, /* u8 bNumInterfaces */
|
.bInterfaceClass = USB_CLASS_COMM,
|
||||||
DEV_RNDIS_CONFIG_VALUE, /* u8 bConfigurationValue */
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
STRING_RNDIS, /* u8 iConfiguration */
|
.bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
|
||||||
0xc0, /* u8 bmAttributes */
|
.iInterface = STRING_RNDIS_CONTROL,
|
||||||
0x32, /* u8 bMaxPower */
|
.ndesc = 4,
|
||||||
/* RNDIS Control Interface */
|
.descs = (USBDescOther[]) {
|
||||||
0x09, /* u8 bLength */
|
{
|
||||||
USB_DT_INTERFACE, /* u8 bDescriptorType */
|
/* Header Descriptor */
|
||||||
0x00, /* u8 bInterfaceNumber */
|
.data = (uint8_t[]) {
|
||||||
0x00, /* u8 bAlternateSetting */
|
0x05, /* u8 bLength */
|
||||||
0x01, /* u8 bNumEndpoints */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
USB_CLASS_COMM, /* u8 bInterfaceClass */
|
USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
|
||||||
USB_CDC_SUBCLASS_ACM, /* u8 bInterfaceSubClass */
|
0x10, 0x01, /* le16 bcdCDC */
|
||||||
USB_CDC_ACM_PROTO_VENDOR, /* u8 bInterfaceProtocol */
|
},
|
||||||
STRING_RNDIS_CONTROL, /* u8 iInterface */
|
},{
|
||||||
/* Header Descriptor */
|
/* Call Management Descriptor */
|
||||||
0x05, /* u8 bLength */
|
.data = (uint8_t[]) {
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
0x05, /* u8 bLength */
|
||||||
USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
0x10, 0x01, /* le16 bcdCDC */
|
USB_CDC_CALL_MANAGEMENT_TYPE, /* u8 bDescriptorSubType */
|
||||||
/* Call Management Descriptor */
|
0x00, /* u8 bmCapabilities */
|
||||||
0x05, /* u8 bLength */
|
0x01, /* u8 bDataInterface */
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
},
|
||||||
USB_CDC_CALL_MANAGEMENT_TYPE, /* u8 bDescriptorSubType */
|
},{
|
||||||
0x00, /* u8 bmCapabilities */
|
/* ACM Descriptor */
|
||||||
0x01, /* u8 bDataInterface */
|
.data = (uint8_t[]) {
|
||||||
/* ACM Descriptor */
|
0x04, /* u8 bLength */
|
||||||
0x04, /* u8 bLength */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
USB_CDC_ACM_TYPE, /* u8 bDescriptorSubType */
|
||||||
USB_CDC_ACM_TYPE, /* u8 bDescriptorSubType */
|
0x00, /* u8 bmCapabilities */
|
||||||
0x00, /* u8 bmCapabilities */
|
},
|
||||||
/* Union Descriptor */
|
},{
|
||||||
0x05, /* u8 bLength */
|
/* Union Descriptor */
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
.data = (uint8_t[]) {
|
||||||
USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
|
0x05, /* u8 bLength */
|
||||||
0x00, /* u8 bMasterInterface0 */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
0x01, /* u8 bSlaveInterface0 */
|
USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
|
||||||
/* Status Descriptor */
|
0x00, /* u8 bMasterInterface0 */
|
||||||
0x07, /* u8 bLength */
|
0x01, /* u8 bSlaveInterface0 */
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
},
|
||||||
USB_DIR_IN | 1, /* u8 bEndpointAddress */
|
},
|
||||||
USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */
|
},
|
||||||
STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */
|
.eps = (USBDescEndpoint[]) {
|
||||||
1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */
|
{
|
||||||
/* RNDIS Data Interface */
|
.bEndpointAddress = USB_DIR_IN | 0x01,
|
||||||
0x09, /* u8 bLength */
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
USB_DT_INTERFACE, /* u8 bDescriptorType */
|
.wMaxPacketSize = STATUS_BYTECOUNT,
|
||||||
0x01, /* u8 bInterfaceNumber */
|
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
|
||||||
0x00, /* u8 bAlternateSetting */
|
},
|
||||||
0x02, /* u8 bNumEndpoints */
|
}
|
||||||
USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */
|
},{
|
||||||
0x00, /* u8 bInterfaceSubClass */
|
/* RNDIS Data Interface */
|
||||||
0x00, /* u8 bInterfaceProtocol */
|
.bInterfaceNumber = 1,
|
||||||
STRING_DATA, /* u8 iInterface */
|
.bNumEndpoints = 2,
|
||||||
/* Source Endpoint */
|
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||||
0x07, /* u8 bLength */
|
.iInterface = STRING_DATA,
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
.eps = (USBDescEndpoint[]) {
|
||||||
USB_DIR_IN | 2, /* u8 bEndpointAddress */
|
{
|
||||||
USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */
|
.bEndpointAddress = USB_DIR_IN | 0x02,
|
||||||
0x40, 0x00, /* le16 wMaxPacketSize */
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
0x00, /* u8 bInterval */
|
.wMaxPacketSize = 0x40,
|
||||||
/* Sink Endpoint */
|
},{
|
||||||
0x07, /* u8 bLength */
|
.bEndpointAddress = USB_DIR_OUT | 0x02,
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
USB_DIR_OUT | 2, /* u8 bEndpointAddress */
|
.wMaxPacketSize = 0x40,
|
||||||
USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */
|
}
|
||||||
0x40, 0x00, /* le16 wMaxPacketSize */
|
}
|
||||||
0x00 /* u8 bInterval */
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t qemu_net_cdc_config_descriptor[] = {
|
static const USBDescIface desc_iface_cdc[] = {
|
||||||
/* Configuration Descriptor */
|
{
|
||||||
0x09, /* u8 bLength */
|
/* CDC Control Interface */
|
||||||
USB_DT_CONFIG, /* u8 bDescriptorType */
|
.bInterfaceNumber = 0,
|
||||||
0x50, 0x00, /* le16 wTotalLength */
|
.bNumEndpoints = 1,
|
||||||
0x02, /* u8 bNumInterfaces */
|
.bInterfaceClass = USB_CLASS_COMM,
|
||||||
DEV_CONFIG_VALUE, /* u8 bConfigurationValue */
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
|
||||||
STRING_CDC, /* u8 iConfiguration */
|
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
|
||||||
0xc0, /* u8 bmAttributes */
|
.iInterface = STRING_CONTROL,
|
||||||
0x32, /* u8 bMaxPower */
|
.ndesc = 3,
|
||||||
/* CDC Control Interface */
|
.descs = (USBDescOther[]) {
|
||||||
0x09, /* u8 bLength */
|
{
|
||||||
USB_DT_INTERFACE, /* u8 bDescriptorType */
|
/* Header Descriptor */
|
||||||
0x00, /* u8 bInterfaceNumber */
|
.data = (uint8_t[]) {
|
||||||
0x00, /* u8 bAlternateSetting */
|
0x05, /* u8 bLength */
|
||||||
0x01, /* u8 bNumEndpoints */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
USB_CLASS_COMM, /* u8 bInterfaceClass */
|
USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
|
||||||
USB_CDC_SUBCLASS_ETHERNET, /* u8 bInterfaceSubClass */
|
0x10, 0x01, /* le16 bcdCDC */
|
||||||
USB_CDC_PROTO_NONE, /* u8 bInterfaceProtocol */
|
},
|
||||||
STRING_CONTROL, /* u8 iInterface */
|
},{
|
||||||
/* Header Descriptor */
|
/* Union Descriptor */
|
||||||
0x05, /* u8 bLength */
|
.data = (uint8_t[]) {
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
0x05, /* u8 bLength */
|
||||||
USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
0x10, 0x01, /* le16 bcdCDC */
|
USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
|
||||||
/* Union Descriptor */
|
0x00, /* u8 bMasterInterface0 */
|
||||||
0x05, /* u8 bLength */
|
0x01, /* u8 bSlaveInterface0 */
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
},
|
||||||
USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
|
},{
|
||||||
0x00, /* u8 bMasterInterface0 */
|
/* Ethernet Descriptor */
|
||||||
0x01, /* u8 bSlaveInterface0 */
|
.data = (uint8_t[]) {
|
||||||
/* Ethernet Descriptor */
|
0x0d, /* u8 bLength */
|
||||||
0x0d, /* u8 bLength */
|
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
||||||
USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
|
USB_CDC_ETHERNET_TYPE, /* u8 bDescriptorSubType */
|
||||||
USB_CDC_ETHERNET_TYPE, /* u8 bDescriptorSubType */
|
STRING_ETHADDR, /* u8 iMACAddress */
|
||||||
STRING_ETHADDR, /* u8 iMACAddress */
|
0x00, 0x00, 0x00, 0x00, /* le32 bmEthernetStatistics */
|
||||||
0x00, 0x00, 0x00, 0x00, /* le32 bmEthernetStatistics */
|
ETH_FRAME_LEN & 0xff,
|
||||||
ETH_FRAME_LEN & 0xff, ETH_FRAME_LEN >> 8, /* le16 wMaxSegmentSize */
|
ETH_FRAME_LEN >> 8, /* le16 wMaxSegmentSize */
|
||||||
0x00, 0x00, /* le16 wNumberMCFilters */
|
0x00, 0x00, /* le16 wNumberMCFilters */
|
||||||
0x00, /* u8 bNumberPowerFilters */
|
0x00, /* u8 bNumberPowerFilters */
|
||||||
/* Status Descriptor */
|
},
|
||||||
0x07, /* u8 bLength */
|
},
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
},
|
||||||
USB_DIR_IN | 1, /* u8 bEndpointAddress */
|
.eps = (USBDescEndpoint[]) {
|
||||||
USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */
|
{
|
||||||
STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */
|
.bEndpointAddress = USB_DIR_IN | 0x01,
|
||||||
1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */
|
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||||
/* CDC Data (nop) Interface */
|
.wMaxPacketSize = STATUS_BYTECOUNT,
|
||||||
0x09, /* u8 bLength */
|
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
|
||||||
USB_DT_INTERFACE, /* u8 bDescriptorType */
|
},
|
||||||
0x01, /* u8 bInterfaceNumber */
|
}
|
||||||
0x00, /* u8 bAlternateSetting */
|
},{
|
||||||
0x00, /* u8 bNumEndpoints */
|
/* CDC Data Interface (off) */
|
||||||
USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */
|
.bInterfaceNumber = 1,
|
||||||
0x00, /* u8 bInterfaceSubClass */
|
.bAlternateSetting = 0,
|
||||||
0x00, /* u8 bInterfaceProtocol */
|
.bNumEndpoints = 0,
|
||||||
0x00, /* u8 iInterface */
|
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||||
/* CDC Data Interface */
|
},{
|
||||||
0x09, /* u8 bLength */
|
/* CDC Data Interface */
|
||||||
USB_DT_INTERFACE, /* u8 bDescriptorType */
|
.bInterfaceNumber = 1,
|
||||||
0x01, /* u8 bInterfaceNumber */
|
.bAlternateSetting = 1,
|
||||||
0x01, /* u8 bAlternateSetting */
|
.bNumEndpoints = 2,
|
||||||
0x02, /* u8 bNumEndpoints */
|
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||||
USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */
|
.iInterface = STRING_DATA,
|
||||||
0x00, /* u8 bInterfaceSubClass */
|
.eps = (USBDescEndpoint[]) {
|
||||||
0x00, /* u8 bInterfaceProtocol */
|
{
|
||||||
STRING_DATA, /* u8 iInterface */
|
.bEndpointAddress = USB_DIR_IN | 0x02,
|
||||||
/* Source Endpoint */
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
0x07, /* u8 bLength */
|
.wMaxPacketSize = 0x40,
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
},{
|
||||||
USB_DIR_IN | 2, /* u8 bEndpointAddress */
|
.bEndpointAddress = USB_DIR_OUT | 0x02,
|
||||||
USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||||
0x40, 0x00, /* le16 wMaxPacketSize */
|
.wMaxPacketSize = 0x40,
|
||||||
0x00, /* u8 bInterval */
|
}
|
||||||
/* Sink Endpoint */
|
}
|
||||||
0x07, /* u8 bLength */
|
}
|
||||||
USB_DT_ENDPOINT, /* u8 bDescriptorType */
|
};
|
||||||
USB_DIR_OUT | 2, /* u8 bEndpointAddress */
|
|
||||||
USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */
|
static const USBDescDevice desc_device_net = {
|
||||||
0x40, 0x00, /* le16 wMaxPacketSize */
|
.bcdUSB = 0x0200,
|
||||||
0x00 /* u8 bInterval */
|
.bDeviceClass = USB_CLASS_COMM,
|
||||||
|
.bMaxPacketSize0 = 0x40,
|
||||||
|
.bNumConfigurations = 2,
|
||||||
|
.confs = (USBDescConfig[]) {
|
||||||
|
{
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
|
||||||
|
.iConfiguration = STRING_RNDIS,
|
||||||
|
.bmAttributes = 0xc0,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
.nif = ARRAY_SIZE(desc_iface_rndis),
|
||||||
|
.ifs = desc_iface_rndis,
|
||||||
|
},{
|
||||||
|
.bNumInterfaces = 2,
|
||||||
|
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||||
|
.iConfiguration = STRING_CDC,
|
||||||
|
.bmAttributes = 0xc0,
|
||||||
|
.bMaxPower = 0x32,
|
||||||
|
.nif = ARRAY_SIZE(desc_iface_cdc),
|
||||||
|
.ifs = desc_iface_cdc,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const USBDesc desc_net = {
|
||||||
|
.id = {
|
||||||
|
.idVendor = RNDIS_VENDOR_NUM,
|
||||||
|
.idProduct = RNDIS_PRODUCT_NUM,
|
||||||
|
.bcdDevice = 0,
|
||||||
|
.iManufacturer = STRING_MANUFACTURER,
|
||||||
|
.iProduct = STRING_PRODUCT,
|
||||||
|
.iSerialNumber = STRING_SERIALNUMBER,
|
||||||
|
},
|
||||||
|
.full = &desc_device_net,
|
||||||
|
.str = usb_net_stringtable,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1010,25 +1038,18 @@ static void usb_net_handle_reset(USBDevice *dev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const usb_net_stringtable[] = {
|
|
||||||
[STRING_MANUFACTURER] = "QEMU",
|
|
||||||
[STRING_PRODUCT] = "RNDIS/QEMU USB Network Device",
|
|
||||||
[STRING_ETHADDR] = "400102030405",
|
|
||||||
[STRING_DATA] = "QEMU USB Net Data Interface",
|
|
||||||
[STRING_CONTROL] = "QEMU USB Net Control Interface",
|
|
||||||
[STRING_RNDIS_CONTROL] = "QEMU USB Net RNDIS Control Interface",
|
|
||||||
[STRING_CDC] = "QEMU USB Net CDC",
|
|
||||||
[STRING_SUBSET] = "QEMU USB Net Subset",
|
|
||||||
[STRING_RNDIS] = "QEMU USB Net RNDIS",
|
|
||||||
[STRING_SERIALNUMBER] = "1",
|
|
||||||
};
|
|
||||||
|
|
||||||
static int usb_net_handle_control(USBDevice *dev, int request, int value,
|
static int usb_net_handle_control(USBDevice *dev, int request, int value,
|
||||||
int index, int length, uint8_t *data)
|
int index, int length, uint8_t *data)
|
||||||
{
|
{
|
||||||
USBNetState *s = (USBNetState *) dev;
|
USBNetState *s = (USBNetState *) dev;
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
|
ret = usb_desc_handle_control(dev, request, value, index, length, data);
|
||||||
|
if (ret >= 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
switch(request) {
|
switch(request) {
|
||||||
case DeviceRequest | USB_REQ_GET_STATUS:
|
case DeviceRequest | USB_REQ_GET_STATUS:
|
||||||
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
|
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
|
||||||
|
@ -1100,64 +1121,6 @@ static int usb_net_handle_control(USBDevice *dev, int request, int value,
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
|
|
||||||
switch(value >> 8) {
|
|
||||||
case USB_DT_DEVICE:
|
|
||||||
ret = sizeof(qemu_net_dev_descriptor);
|
|
||||||
memcpy(data, qemu_net_dev_descriptor, ret);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USB_DT_CONFIG:
|
|
||||||
switch (value & 0xff) {
|
|
||||||
case 0:
|
|
||||||
ret = sizeof(qemu_net_rndis_config_descriptor);
|
|
||||||
memcpy(data, qemu_net_rndis_config_descriptor, ret);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
ret = sizeof(qemu_net_cdc_config_descriptor);
|
|
||||||
memcpy(data, qemu_net_cdc_config_descriptor, ret);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
data[2] = ret & 0xff;
|
|
||||||
data[3] = ret >> 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USB_DT_STRING:
|
|
||||||
switch (value & 0xff) {
|
|
||||||
case 0:
|
|
||||||
/* language ids */
|
|
||||||
data[0] = 4;
|
|
||||||
data[1] = 3;
|
|
||||||
data[2] = 0x09;
|
|
||||||
data[3] = 0x04;
|
|
||||||
ret = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STRING_ETHADDR:
|
|
||||||
ret = set_usb_string(data, s->usbstring_mac);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (ARRAY_SIZE(usb_net_stringtable) > (value & 0xff)) {
|
|
||||||
ret = set_usb_string(data,
|
|
||||||
usb_net_stringtable[value & 0xff]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
|
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
|
||||||
data[0] = s->rndis ? DEV_RNDIS_CONFIG_VALUE : DEV_CONFIG_VALUE;
|
data[0] = s->rndis ? DEV_RNDIS_CONFIG_VALUE : DEV_CONFIG_VALUE;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -1463,6 +1426,7 @@ static int usb_net_initfn(USBDevice *dev)
|
||||||
s->conf.macaddr.a[3],
|
s->conf.macaddr.a[3],
|
||||||
s->conf.macaddr.a[4],
|
s->conf.macaddr.a[4],
|
||||||
s->conf.macaddr.a[5]);
|
s->conf.macaddr.a[5]);
|
||||||
|
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
|
||||||
|
|
||||||
add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
|
add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1500,6 +1464,7 @@ static struct USBDeviceInfo net_info = {
|
||||||
.qdev.name = "usb-net",
|
.qdev.name = "usb-net",
|
||||||
.qdev.fw_name = "network",
|
.qdev.fw_name = "network",
|
||||||
.qdev.size = sizeof(USBNetState),
|
.qdev.size = sizeof(USBNetState),
|
||||||
|
.usb_desc = &desc_net,
|
||||||
.init = usb_net_initfn,
|
.init = usb_net_initfn,
|
||||||
.handle_packet = usb_generic_handle_packet,
|
.handle_packet = usb_generic_handle_packet,
|
||||||
.handle_reset = usb_net_handle_reset,
|
.handle_reset = usb_net_handle_reset,
|
||||||
|
|
Loading…
Reference in a new issue