Merge remote-tracking branch 'kraxel/usb.46' into staging
* kraxel/usb.46: (21 commits) usb-ehci: drop assert() usb-redir: Notify our peer when we reject a device due to a speed mismatch usb-ehci: Drop unused sofv value usb-host: rewrite usb_linux_update_endp_table usb: use USBDescriptor for endpoint descriptors. usb: use USBDescriptor for interface descriptors. usb: use USBDescriptor for config descriptors. usb: use USBDescriptor for device qualifier descriptors. usb: add USBDescriptor, use for device descriptors. usb-ehci: frindex always is a 14 bits counter usb-ehci: fix ehci_child_detach usb-hub: add tracepoints usb_packet_set_state: handle p->ep == NULL usb-host: add property to turn off pipelining usb-host: add usb packet to request tracepoints usb-host: trace canceled requests usb-host: trace emulated requests Add bootindex support to usb-host and usb-redir usb-uhci: queuing fix usb-uhci: stop queue filling when we find a in-flight td ...
This commit is contained in:
commit
b26d712ecc
|
@ -377,6 +377,10 @@ static QEMUMachine pc_machine_v1_1 = {
|
|||
.driver = "apic",\
|
||||
.property = "vapic",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "USB",\
|
||||
.property = "full-path",\
|
||||
.value = "no",\
|
||||
}
|
||||
|
||||
static QEMUMachine pc_machine_v1_0 = {
|
||||
|
|
5
hw/usb.h
5
hw/usb.h
|
@ -182,12 +182,17 @@ struct USBEndpoint {
|
|||
QTAILQ_HEAD(, USBPacket) queue;
|
||||
};
|
||||
|
||||
enum USBDeviceFlags {
|
||||
USB_DEV_FLAG_FULL_PATH,
|
||||
};
|
||||
|
||||
/* definition of a USB device */
|
||||
struct USBDevice {
|
||||
DeviceState qdev;
|
||||
USBPort *port;
|
||||
char *port_path;
|
||||
void *opaque;
|
||||
uint32_t flags;
|
||||
|
||||
/* Actual connected speed */
|
||||
int speed;
|
||||
|
|
15
hw/usb/bus.c
15
hw/usb/bus.c
|
@ -19,6 +19,8 @@ static struct BusInfo usb_bus_info = {
|
|||
.get_fw_dev_path = usb_get_fw_dev_path,
|
||||
.props = (Property[]) {
|
||||
DEFINE_PROP_STRING("port", USBDevice, port_path),
|
||||
DEFINE_PROP_BIT("full-path", USBDevice, flags,
|
||||
USB_DEV_FLAG_FULL_PATH, true),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
@ -460,7 +462,20 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
|
|||
static char *usb_get_dev_path(DeviceState *qdev)
|
||||
{
|
||||
USBDevice *dev = USB_DEVICE(qdev);
|
||||
DeviceState *hcd = qdev->parent_bus->parent;
|
||||
char *id = NULL;
|
||||
|
||||
if ((dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) &&
|
||||
hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
|
||||
id = hcd->parent_bus->info->get_dev_path(hcd);
|
||||
}
|
||||
if (id) {
|
||||
char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
|
||||
g_free(id);
|
||||
return ret;
|
||||
} else {
|
||||
return g_strdup(dev->port->path);
|
||||
}
|
||||
}
|
||||
|
||||
static char *usb_get_fw_dev_path(DeviceState *qdev)
|
||||
|
|
|
@ -484,12 +484,17 @@ void usb_packet_check_state(USBPacket *p, USBPacketState expected)
|
|||
|
||||
void usb_packet_set_state(USBPacket *p, USBPacketState state)
|
||||
{
|
||||
if (p->ep) {
|
||||
USBDevice *dev = p->ep->dev;
|
||||
USBBus *bus = usb_bus_from_device(dev);
|
||||
|
||||
trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, p,
|
||||
usb_packet_state_name(p->state),
|
||||
usb_packet_state_name(state));
|
||||
} else {
|
||||
trace_usb_packet_state_change(-1, "", -1, p,
|
||||
usb_packet_state_name(p->state),
|
||||
usb_packet_state_name(state));
|
||||
}
|
||||
p->state = state;
|
||||
}
|
||||
|
||||
|
|
120
hw/usb/desc.c
120
hw/usb/desc.c
|
@ -18,32 +18,33 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
|
|||
uint8_t *dest, size_t len)
|
||||
{
|
||||
uint8_t bLength = 0x12;
|
||||
USBDescriptor *d = (void *)dest;
|
||||
|
||||
if (len < bLength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest[0x00] = bLength;
|
||||
dest[0x01] = USB_DT_DEVICE;
|
||||
d->bLength = bLength;
|
||||
d->bDescriptorType = USB_DT_DEVICE;
|
||||
|
||||
dest[0x02] = usb_lo(dev->bcdUSB);
|
||||
dest[0x03] = usb_hi(dev->bcdUSB);
|
||||
dest[0x04] = dev->bDeviceClass;
|
||||
dest[0x05] = dev->bDeviceSubClass;
|
||||
dest[0x06] = dev->bDeviceProtocol;
|
||||
dest[0x07] = dev->bMaxPacketSize0;
|
||||
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.bDeviceSubClass = dev->bDeviceSubClass;
|
||||
d->u.device.bDeviceProtocol = dev->bDeviceProtocol;
|
||||
d->u.device.bMaxPacketSize0 = dev->bMaxPacketSize0;
|
||||
|
||||
dest[0x08] = usb_lo(id->idVendor);
|
||||
dest[0x09] = usb_hi(id->idVendor);
|
||||
dest[0x0a] = usb_lo(id->idProduct);
|
||||
dest[0x0b] = usb_hi(id->idProduct);
|
||||
dest[0x0c] = usb_lo(id->bcdDevice);
|
||||
dest[0x0d] = usb_hi(id->bcdDevice);
|
||||
dest[0x0e] = id->iManufacturer;
|
||||
dest[0x0f] = id->iProduct;
|
||||
dest[0x10] = id->iSerialNumber;
|
||||
d->u.device.idVendor_lo = usb_lo(id->idVendor);
|
||||
d->u.device.idVendor_hi = usb_hi(id->idVendor);
|
||||
d->u.device.idProduct_lo = usb_lo(id->idProduct);
|
||||
d->u.device.idProduct_hi = usb_hi(id->idProduct);
|
||||
d->u.device.bcdDevice_lo = usb_lo(id->bcdDevice);
|
||||
d->u.device.bcdDevice_hi = usb_hi(id->bcdDevice);
|
||||
d->u.device.iManufacturer = id->iManufacturer;
|
||||
d->u.device.iProduct = id->iProduct;
|
||||
d->u.device.iSerialNumber = id->iSerialNumber;
|
||||
|
||||
dest[0x11] = dev->bNumConfigurations;
|
||||
d->u.device.bNumConfigurations = dev->bNumConfigurations;
|
||||
|
||||
return bLength;
|
||||
}
|
||||
|
@ -52,22 +53,23 @@ int usb_desc_device_qualifier(const USBDescDevice *dev,
|
|||
uint8_t *dest, size_t len)
|
||||
{
|
||||
uint8_t bLength = 0x0a;
|
||||
USBDescriptor *d = (void *)dest;
|
||||
|
||||
if (len < bLength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest[0x00] = bLength;
|
||||
dest[0x01] = USB_DT_DEVICE_QUALIFIER;
|
||||
d->bLength = bLength;
|
||||
d->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
|
||||
|
||||
dest[0x02] = usb_lo(dev->bcdUSB);
|
||||
dest[0x03] = usb_hi(dev->bcdUSB);
|
||||
dest[0x04] = dev->bDeviceClass;
|
||||
dest[0x05] = dev->bDeviceSubClass;
|
||||
dest[0x06] = dev->bDeviceProtocol;
|
||||
dest[0x07] = dev->bMaxPacketSize0;
|
||||
dest[0x08] = dev->bNumConfigurations;
|
||||
dest[0x09] = 0; /* reserved */
|
||||
d->u.device_qualifier.bcdUSB_lo = usb_lo(dev->bcdUSB);
|
||||
d->u.device_qualifier.bcdUSB_hi = usb_hi(dev->bcdUSB);
|
||||
d->u.device_qualifier.bDeviceClass = dev->bDeviceClass;
|
||||
d->u.device_qualifier.bDeviceSubClass = dev->bDeviceSubClass;
|
||||
d->u.device_qualifier.bDeviceProtocol = dev->bDeviceProtocol;
|
||||
d->u.device_qualifier.bMaxPacketSize0 = dev->bMaxPacketSize0;
|
||||
d->u.device_qualifier.bNumConfigurations = dev->bNumConfigurations;
|
||||
d->u.device_qualifier.bReserved = 0;
|
||||
|
||||
return bLength;
|
||||
}
|
||||
|
@ -76,22 +78,24 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len)
|
|||
{
|
||||
uint8_t bLength = 0x09;
|
||||
uint16_t wTotalLength = 0;
|
||||
USBDescriptor *d = (void *)dest;
|
||||
int i, rc;
|
||||
|
||||
if (len < bLength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest[0x00] = bLength;
|
||||
dest[0x01] = USB_DT_CONFIG;
|
||||
dest[0x04] = conf->bNumInterfaces;
|
||||
dest[0x05] = conf->bConfigurationValue;
|
||||
dest[0x06] = conf->iConfiguration;
|
||||
dest[0x07] = conf->bmAttributes;
|
||||
dest[0x08] = conf->bMaxPower;
|
||||
d->bLength = bLength;
|
||||
d->bDescriptorType = USB_DT_CONFIG;
|
||||
|
||||
d->u.config.bNumInterfaces = conf->bNumInterfaces;
|
||||
d->u.config.bConfigurationValue = conf->bConfigurationValue;
|
||||
d->u.config.iConfiguration = conf->iConfiguration;
|
||||
d->u.config.bmAttributes = conf->bmAttributes;
|
||||
d->u.config.bMaxPower = conf->bMaxPower;
|
||||
wTotalLength += bLength;
|
||||
|
||||
/* handle grouped interfaces if any*/
|
||||
/* handle grouped interfaces if any */
|
||||
for (i = 0; i < conf->nif_groups; i++) {
|
||||
rc = usb_desc_iface_group(&(conf->if_groups[i]),
|
||||
dest + wTotalLength,
|
||||
|
@ -111,8 +115,8 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len)
|
|||
wTotalLength += rc;
|
||||
}
|
||||
|
||||
dest[0x02] = usb_lo(wTotalLength);
|
||||
dest[0x03] = usb_hi(wTotalLength);
|
||||
d->u.config.wTotalLength_lo = usb_lo(wTotalLength);
|
||||
d->u.config.wTotalLength_hi = usb_hi(wTotalLength);
|
||||
return wTotalLength;
|
||||
}
|
||||
|
||||
|
@ -155,20 +159,22 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len)
|
|||
{
|
||||
uint8_t bLength = 0x09;
|
||||
int i, rc, pos = 0;
|
||||
USBDescriptor *d = (void *)dest;
|
||||
|
||||
if (len < bLength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest[0x00] = bLength;
|
||||
dest[0x01] = USB_DT_INTERFACE;
|
||||
dest[0x02] = iface->bInterfaceNumber;
|
||||
dest[0x03] = iface->bAlternateSetting;
|
||||
dest[0x04] = iface->bNumEndpoints;
|
||||
dest[0x05] = iface->bInterfaceClass;
|
||||
dest[0x06] = iface->bInterfaceSubClass;
|
||||
dest[0x07] = iface->bInterfaceProtocol;
|
||||
dest[0x08] = iface->iInterface;
|
||||
d->bLength = bLength;
|
||||
d->bDescriptorType = USB_DT_INTERFACE;
|
||||
|
||||
d->u.interface.bInterfaceNumber = iface->bInterfaceNumber;
|
||||
d->u.interface.bAlternateSetting = iface->bAlternateSetting;
|
||||
d->u.interface.bNumEndpoints = iface->bNumEndpoints;
|
||||
d->u.interface.bInterfaceClass = iface->bInterfaceClass;
|
||||
d->u.interface.bInterfaceSubClass = iface->bInterfaceSubClass;
|
||||
d->u.interface.bInterfaceProtocol = iface->bInterfaceProtocol;
|
||||
d->u.interface.iInterface = iface->iInterface;
|
||||
pos += bLength;
|
||||
|
||||
for (i = 0; i < iface->ndesc; i++) {
|
||||
|
@ -194,21 +200,23 @@ int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len)
|
|||
{
|
||||
uint8_t bLength = ep->is_audio ? 0x09 : 0x07;
|
||||
uint8_t extralen = ep->extra ? ep->extra[0] : 0;
|
||||
USBDescriptor *d = (void *)dest;
|
||||
|
||||
if (len < bLength + extralen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest[0x00] = bLength;
|
||||
dest[0x01] = USB_DT_ENDPOINT;
|
||||
dest[0x02] = ep->bEndpointAddress;
|
||||
dest[0x03] = ep->bmAttributes;
|
||||
dest[0x04] = usb_lo(ep->wMaxPacketSize);
|
||||
dest[0x05] = usb_hi(ep->wMaxPacketSize);
|
||||
dest[0x06] = ep->bInterval;
|
||||
d->bLength = bLength;
|
||||
d->bDescriptorType = USB_DT_ENDPOINT;
|
||||
|
||||
d->u.endpoint.bEndpointAddress = ep->bEndpointAddress;
|
||||
d->u.endpoint.bmAttributes = ep->bmAttributes;
|
||||
d->u.endpoint.wMaxPacketSize_lo = usb_lo(ep->wMaxPacketSize);
|
||||
d->u.endpoint.wMaxPacketSize_hi = usb_hi(ep->wMaxPacketSize);
|
||||
d->u.endpoint.bInterval = ep->bInterval;
|
||||
if (ep->is_audio) {
|
||||
dest[0x07] = ep->bRefresh;
|
||||
dest[0x08] = ep->bSynchAddress;
|
||||
d->u.endpoint.bRefresh = ep->bRefresh;
|
||||
d->u.endpoint.bSynchAddress = ep->bSynchAddress;
|
||||
}
|
||||
if (ep->extra) {
|
||||
memcpy(dest + bLength, ep->extra, extralen);
|
||||
|
|
|
@ -3,6 +3,69 @@
|
|||
|
||||
#include <inttypes.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;
|
||||
} u;
|
||||
} QEMU_PACKED USBDescriptor;
|
||||
|
||||
struct USBDescID {
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
|
|
|
@ -22,11 +22,10 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "trace.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#define NUM_PORTS 8
|
||||
|
||||
typedef struct USBHubPort {
|
||||
|
@ -157,6 +156,7 @@ static void usb_hub_attach(USBPort *port1)
|
|||
USBHubState *s = port1->opaque;
|
||||
USBHubPort *port = &s->ports[port1->index];
|
||||
|
||||
trace_usb_hub_attach(s->dev.addr, port1->index + 1);
|
||||
port->wPortStatus |= PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (port->port.dev->speed == USB_SPEED_LOW) {
|
||||
|
@ -172,6 +172,7 @@ static void usb_hub_detach(USBPort *port1)
|
|||
USBHubState *s = port1->opaque;
|
||||
USBHubPort *port = &s->ports[port1->index];
|
||||
|
||||
trace_usb_hub_detach(s->dev.addr, port1->index + 1);
|
||||
usb_wakeup(s->intr);
|
||||
|
||||
/* Let upstream know the device on this port is gone */
|
||||
|
@ -247,6 +248,7 @@ static void usb_hub_handle_reset(USBDevice *dev)
|
|||
USBHubPort *port;
|
||||
int i;
|
||||
|
||||
trace_usb_hub_reset(s->dev.addr);
|
||||
for (i = 0; i < NUM_PORTS; i++) {
|
||||
port = s->ports + i;
|
||||
port->wPortStatus = PORT_STAT_POWER;
|
||||
|
@ -261,12 +263,39 @@ static void usb_hub_handle_reset(USBDevice *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *feature_name(int feature)
|
||||
{
|
||||
static const char *name[] = {
|
||||
[PORT_CONNECTION] = "connection",
|
||||
[PORT_ENABLE] = "enable",
|
||||
[PORT_SUSPEND] = "suspend",
|
||||
[PORT_OVERCURRENT] = "overcurrent",
|
||||
[PORT_RESET] = "reset",
|
||||
[PORT_POWER] = "power",
|
||||
[PORT_LOWSPEED] = "lowspeed",
|
||||
[PORT_HIGHSPEED] = "highspeed",
|
||||
[PORT_C_CONNECTION] = "change connection",
|
||||
[PORT_C_ENABLE] = "change enable",
|
||||
[PORT_C_SUSPEND] = "change suspend",
|
||||
[PORT_C_OVERCURRENT] = "change overcurrent",
|
||||
[PORT_C_RESET] = "change reset",
|
||||
[PORT_TEST] = "test",
|
||||
[PORT_INDICATOR] = "indicator",
|
||||
};
|
||||
if (feature < 0 || feature >= ARRAY_SIZE(name)) {
|
||||
return "?";
|
||||
}
|
||||
return name[feature] ?: "?";
|
||||
}
|
||||
|
||||
static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
|
||||
int request, int value, int index, int length, uint8_t *data)
|
||||
{
|
||||
USBHubState *s = (USBHubState *)dev;
|
||||
int ret;
|
||||
|
||||
trace_usb_hub_control(s->dev.addr, request, value, index, length);
|
||||
|
||||
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
|
@ -295,6 +324,9 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
|
|||
goto fail;
|
||||
}
|
||||
port = &s->ports[n];
|
||||
trace_usb_hub_get_port_status(s->dev.addr, index,
|
||||
port->wPortStatus,
|
||||
port->wPortChange);
|
||||
data[0] = port->wPortStatus;
|
||||
data[1] = port->wPortStatus >> 8;
|
||||
data[2] = port->wPortChange;
|
||||
|
@ -315,6 +347,10 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
|
|||
unsigned int n = index - 1;
|
||||
USBHubPort *port;
|
||||
USBDevice *dev;
|
||||
|
||||
trace_usb_hub_set_port_feature(s->dev.addr, index,
|
||||
feature_name(value));
|
||||
|
||||
if (n >= NUM_PORTS) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -345,6 +381,9 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
|
|||
unsigned int n = index - 1;
|
||||
USBHubPort *port;
|
||||
|
||||
trace_usb_hub_clear_port_feature(s->dev.addr, index,
|
||||
feature_name(value));
|
||||
|
||||
if (n >= NUM_PORTS) {
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -403,7 +403,6 @@ struct EHCIState {
|
|||
/*
|
||||
* Internal states, shadow registers, etc
|
||||
*/
|
||||
uint32_t sofv;
|
||||
QEMUTimer *frame_timer;
|
||||
int attach_poll_counter;
|
||||
int astate; // Current state in asynchronous schedule
|
||||
|
@ -797,7 +796,6 @@ static void ehci_child_detach(USBPort *port, USBDevice *child)
|
|||
if (portsc & PORTSC_POWNER) {
|
||||
USBPort *companion = s->companion_ports[port->index];
|
||||
companion->ops->child_detach(companion, child);
|
||||
companion->dev = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1103,10 +1101,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
|
|||
val &= USBINTR_MASK;
|
||||
break;
|
||||
|
||||
case FRINDEX:
|
||||
s->sofv = val >> 3;
|
||||
break;
|
||||
|
||||
case CONFIGFLAG:
|
||||
val &= 0x1;
|
||||
if (val) {
|
||||
|
@ -2015,7 +2009,6 @@ static void ehci_advance_state(EHCIState *ehci,
|
|||
fprintf(stderr, "processing error - resetting ehci HC\n");
|
||||
ehci_reset(ehci);
|
||||
again = 0;
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
while (again);
|
||||
|
@ -2150,13 +2143,14 @@ static void ehci_frame_timer(void *opaque)
|
|||
if ( !(ehci->usbsts & USBSTS_HALT)) {
|
||||
ehci->frindex += 8;
|
||||
|
||||
if (ehci->frindex > 0x00001fff) {
|
||||
ehci->frindex = 0;
|
||||
if (ehci->frindex == 0x00002000) {
|
||||
ehci_set_interrupt(ehci, USBSTS_FLR);
|
||||
}
|
||||
|
||||
ehci->sofv = (ehci->frindex - 1) >> 3;
|
||||
ehci->sofv &= 0x000003ff;
|
||||
if (ehci->frindex == 0x00004000) {
|
||||
ehci_set_interrupt(ehci, USBSTS_FLR);
|
||||
ehci->frindex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (frames - i > ehci->maxframes) {
|
||||
|
|
|
@ -795,7 +795,8 @@ out:
|
|||
return TD_RESULT_NEXT_QH;
|
||||
}
|
||||
|
||||
static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
|
||||
static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
|
||||
uint32_t *int_mask, bool queuing)
|
||||
{
|
||||
UHCIAsync *async;
|
||||
int len = 0, max_len;
|
||||
|
@ -814,6 +815,12 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
|
|||
|
||||
if (!async->done)
|
||||
return TD_RESULT_ASYNC_CONT;
|
||||
if (queuing) {
|
||||
/* we are busy filling the queue, we are not prepared
|
||||
to consume completed packages then, just leave them
|
||||
in async state */
|
||||
return TD_RESULT_ASYNC_CONT;
|
||||
}
|
||||
|
||||
uhci_async_unlink(async);
|
||||
goto done;
|
||||
|
@ -964,7 +971,10 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
|
|||
break;
|
||||
}
|
||||
trace_usb_uhci_td_queue(plink & ~0xf, ptd.ctrl, ptd.token);
|
||||
ret = uhci_handle_td(s, plink, &ptd, &int_mask);
|
||||
ret = uhci_handle_td(s, plink, &ptd, &int_mask, true);
|
||||
if (ret == TD_RESULT_ASYNC_CONT) {
|
||||
break;
|
||||
}
|
||||
assert(ret == TD_RESULT_ASYNC_START);
|
||||
assert(int_mask == 0);
|
||||
plink = ptd.link;
|
||||
|
@ -1045,7 +1055,7 @@ static void uhci_process_frame(UHCIState *s)
|
|||
trace_usb_uhci_td_load(curr_qh & ~0xf, link & ~0xf, td.ctrl, td.token);
|
||||
|
||||
old_td_ctrl = td.ctrl;
|
||||
ret = uhci_handle_td(s, link, &td, &int_mask);
|
||||
ret = uhci_handle_td(s, link, &td, &int_mask, false);
|
||||
if (old_td_ctrl != td.ctrl) {
|
||||
/* update the status bits of the TD */
|
||||
val = cpu_to_le32(td.ctrl);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <linux/usbdevice_fs.h>
|
||||
#include <linux/version.h>
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
|
||||
/* We redefine it to avoid version problems */
|
||||
struct usb_ctrltransfer {
|
||||
|
@ -94,6 +95,10 @@ struct USBAutoFilter {
|
|||
uint32_t product_id;
|
||||
};
|
||||
|
||||
enum USBHostDeviceOptions {
|
||||
USB_HOST_OPT_PIPELINE,
|
||||
};
|
||||
|
||||
typedef struct USBHostDevice {
|
||||
USBDevice dev;
|
||||
int fd;
|
||||
|
@ -104,6 +109,7 @@ typedef struct USBHostDevice {
|
|||
int descr_len;
|
||||
int closing;
|
||||
uint32_t iso_urb_count;
|
||||
uint32_t options;
|
||||
Notifier exit;
|
||||
|
||||
struct endp_data ep_in[USB_MAX_ENDPOINTS];
|
||||
|
@ -115,6 +121,7 @@ typedef struct USBHostDevice {
|
|||
int addr;
|
||||
char port[MAX_PORTLEN];
|
||||
struct USBAutoFilter match;
|
||||
int32_t bootindex;
|
||||
int seen, errcount;
|
||||
|
||||
QTAILQ_ENTRY(USBHostDevice) next;
|
||||
|
@ -374,10 +381,10 @@ static void async_complete(void *opaque)
|
|||
}
|
||||
|
||||
if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p->result);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p, p->result);
|
||||
usb_generic_async_ctrl_complete(&s->dev, p);
|
||||
} else if (!aurb->more) {
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p->result);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p, p->result);
|
||||
usb_packet_complete(&s->dev, p);
|
||||
}
|
||||
}
|
||||
|
@ -391,12 +398,14 @@ static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
|
|||
USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
|
||||
AsyncURB *aurb;
|
||||
|
||||
trace_usb_host_req_canceled(s->bus_num, s->addr, p);
|
||||
|
||||
QLIST_FOREACH(aurb, &s->aurbs, next) {
|
||||
if (p != aurb->packet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DPRINTF("husb: async cancel: packet %p, aurb %p\n", p, aurb);
|
||||
trace_usb_host_urb_canceled(s->bus_num, s->addr, aurb);
|
||||
|
||||
/* Mark it as dead (see async_complete above) */
|
||||
aurb->packet = NULL;
|
||||
|
@ -844,12 +853,12 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
|||
uint8_t *pbuf;
|
||||
uint8_t ep;
|
||||
|
||||
trace_usb_host_req_data(s->bus_num, s->addr,
|
||||
trace_usb_host_req_data(s->bus_num, s->addr, p,
|
||||
p->pid == USB_TOKEN_IN,
|
||||
p->ep->nr, p->iov.size);
|
||||
|
||||
if (!is_valid(s, p->pid, p->ep->nr)) {
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
|
||||
return USB_RET_NAK;
|
||||
}
|
||||
|
||||
|
@ -864,7 +873,7 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
|||
ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
|
||||
if (ret < 0) {
|
||||
perror("USBDEVFS_CLEAR_HALT");
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
|
||||
return USB_RET_NAK;
|
||||
}
|
||||
clear_halt(s, p->pid, p->ep->nr);
|
||||
|
@ -919,11 +928,13 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
|||
|
||||
switch(errno) {
|
||||
case ETIMEDOUT:
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p,
|
||||
USB_RET_NAK);
|
||||
return USB_RET_NAK;
|
||||
case EPIPE:
|
||||
default:
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_STALL);
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, p,
|
||||
USB_RET_STALL);
|
||||
return USB_RET_STALL;
|
||||
}
|
||||
}
|
||||
|
@ -1030,17 +1041,23 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
|
|||
*/
|
||||
|
||||
/* Note request is (bRequestType << 8) | bRequest */
|
||||
trace_usb_host_req_control(s->bus_num, s->addr, request, value, index);
|
||||
trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);
|
||||
|
||||
switch (request) {
|
||||
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
|
||||
return usb_host_set_address(s, value);
|
||||
ret = usb_host_set_address(s, value);
|
||||
trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
|
||||
return ret;
|
||||
|
||||
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
|
||||
return usb_host_set_config(s, value & 0xff);
|
||||
ret = usb_host_set_config(s, value & 0xff);
|
||||
trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
|
||||
return ret;
|
||||
|
||||
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
|
||||
return usb_host_set_interface(s, index, value);
|
||||
ret = usb_host_set_interface(s, index, value);
|
||||
trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The rest are asynchronous */
|
||||
|
@ -1092,120 +1109,128 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
|
|||
return USB_RET_ASYNC;
|
||||
}
|
||||
|
||||
static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
|
||||
uint8_t configuration, uint8_t interface)
|
||||
{
|
||||
char device_name[64], line[1024];
|
||||
int alt_setting;
|
||||
|
||||
sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
|
||||
(int)configuration, (int)interface);
|
||||
|
||||
if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
|
||||
device_name)) {
|
||||
/* Assume alt 0 on error */
|
||||
return 0;
|
||||
}
|
||||
if (sscanf(line, "%d", &alt_setting) != 1) {
|
||||
/* Assume alt 0 on error */
|
||||
return 0;
|
||||
}
|
||||
return alt_setting;
|
||||
}
|
||||
|
||||
/* returns 1 on problem encountered or 0 for success */
|
||||
static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||
{
|
||||
uint8_t *descriptors;
|
||||
uint8_t devep, type, alt_interface;
|
||||
uint16_t raw;
|
||||
int interface, length, i, ep, pid;
|
||||
static const char *tname[] = {
|
||||
[USB_ENDPOINT_XFER_CONTROL] = "control",
|
||||
[USB_ENDPOINT_XFER_ISOC] = "isoc",
|
||||
[USB_ENDPOINT_XFER_BULK] = "bulk",
|
||||
[USB_ENDPOINT_XFER_INT] = "int",
|
||||
};
|
||||
uint8_t devep, type;
|
||||
uint16_t mps, v, p;
|
||||
int ep, pid;
|
||||
unsigned int i, configuration = -1, interface = -1, altsetting = -1;
|
||||
struct endp_data *epd;
|
||||
USBDescriptor *d;
|
||||
bool active = false;
|
||||
|
||||
usb_ep_init(&s->dev);
|
||||
|
||||
if (s->dev.configuration == 0) {
|
||||
/* not configured yet -- leave all endpoints disabled */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the desired configuration, interface, and endpoint descriptors
|
||||
* from device description */
|
||||
descriptors = &s->descr[18];
|
||||
length = s->descr_len - 18;
|
||||
i = 0;
|
||||
|
||||
while (i < length) {
|
||||
if (descriptors[i + 1] != USB_DT_CONFIG) {
|
||||
fprintf(stderr, "invalid descriptor data\n");
|
||||
return 1;
|
||||
} else if (descriptors[i + 5] != s->dev.configuration) {
|
||||
DPRINTF("not requested configuration %d\n", s->dev.configuration);
|
||||
i += (descriptors[i + 3] << 8) + descriptors[i + 2];
|
||||
continue;
|
||||
}
|
||||
i += descriptors[i];
|
||||
|
||||
if (descriptors[i + 1] != USB_DT_INTERFACE ||
|
||||
(descriptors[i + 1] == USB_DT_INTERFACE &&
|
||||
descriptors[i + 4] == 0)) {
|
||||
i += descriptors[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
interface = descriptors[i + 2];
|
||||
alt_interface = usb_linux_get_alt_setting(s, s->dev.configuration,
|
||||
interface);
|
||||
|
||||
/* the current interface descriptor is the active interface
|
||||
* and has endpoints */
|
||||
if (descriptors[i + 3] != alt_interface) {
|
||||
i += descriptors[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* advance to the endpoints */
|
||||
while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
|
||||
i += descriptors[i];
|
||||
}
|
||||
|
||||
if (i >= length)
|
||||
break;
|
||||
|
||||
while (i < length) {
|
||||
if (descriptors[i + 1] != USB_DT_ENDPOINT) {
|
||||
for (i = 0;; i += d->bLength) {
|
||||
if (i+2 >= s->descr_len) {
|
||||
break;
|
||||
}
|
||||
|
||||
devep = descriptors[i + 2];
|
||||
d = (void *)(s->descr + i);
|
||||
if (d->bLength < 2) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"descriptor too short");
|
||||
goto error;
|
||||
}
|
||||
if (i + d->bLength > s->descr_len) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"descriptor too long");
|
||||
goto error;
|
||||
}
|
||||
switch (d->bDescriptorType) {
|
||||
case 0:
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"invalid descriptor type");
|
||||
goto error;
|
||||
case USB_DT_DEVICE:
|
||||
if (d->bLength < 0x12) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"device descriptor too short");
|
||||
goto error;
|
||||
}
|
||||
v = (d->u.device.idVendor_hi << 8) | d->u.device.idVendor_lo;
|
||||
p = (d->u.device.idProduct_hi << 8) | d->u.device.idProduct_lo;
|
||||
trace_usb_host_parse_device(s->bus_num, s->addr, v, p);
|
||||
break;
|
||||
case USB_DT_CONFIG:
|
||||
if (d->bLength < 0x09) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"config descriptor too short");
|
||||
goto error;
|
||||
}
|
||||
configuration = d->u.config.bConfigurationValue;
|
||||
active = (configuration == s->dev.configuration);
|
||||
trace_usb_host_parse_config(s->bus_num, s->addr,
|
||||
configuration, active);
|
||||
break;
|
||||
case USB_DT_INTERFACE:
|
||||
if (d->bLength < 0x09) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"interface descriptor too short");
|
||||
goto error;
|
||||
}
|
||||
interface = d->u.interface.bInterfaceNumber;
|
||||
altsetting = d->u.interface.bAlternateSetting;
|
||||
active = (configuration == s->dev.configuration) &&
|
||||
(altsetting == s->dev.altsetting[interface]);
|
||||
trace_usb_host_parse_interface(s->bus_num, s->addr,
|
||||
interface, altsetting, active);
|
||||
break;
|
||||
case USB_DT_ENDPOINT:
|
||||
if (d->bLength < 0x07) {
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"endpoint descriptor too short");
|
||||
goto error;
|
||||
}
|
||||
devep = d->u.endpoint.bEndpointAddress;
|
||||
pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
|
||||
ep = devep & 0xf;
|
||||
if (ep == 0) {
|
||||
fprintf(stderr, "usb-linux: invalid ep descriptor, ep == 0\n");
|
||||
return 1;
|
||||
trace_usb_host_parse_error(s->bus_num, s->addr,
|
||||
"invalid endpoint address");
|
||||
goto error;
|
||||
}
|
||||
|
||||
type = descriptors[i + 3] & 0x3;
|
||||
raw = descriptors[i + 4] + (descriptors[i + 5] << 8);
|
||||
usb_ep_set_max_packet_size(&s->dev, pid, ep, raw);
|
||||
type = d->u.endpoint.bmAttributes & 0x3;
|
||||
mps = d->u.endpoint.wMaxPacketSize_lo |
|
||||
(d->u.endpoint.wMaxPacketSize_hi << 8);
|
||||
trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep,
|
||||
(devep & USB_DIR_IN) ? "in" : "out",
|
||||
tname[type], active);
|
||||
|
||||
if (active) {
|
||||
usb_ep_set_max_packet_size(&s->dev, pid, ep, mps);
|
||||
assert(usb_ep_get_type(&s->dev, pid, ep) ==
|
||||
USB_ENDPOINT_XFER_INVALID);
|
||||
usb_ep_set_type(&s->dev, pid, ep, type);
|
||||
usb_ep_set_ifnum(&s->dev, pid, ep, interface);
|
||||
if (type == USB_ENDPOINT_XFER_BULK) {
|
||||
if ((s->options & (1 << USB_HOST_OPT_PIPELINE)) &&
|
||||
(type == USB_ENDPOINT_XFER_BULK)) {
|
||||
usb_ep_set_pipeline(&s->dev, pid, ep, true);
|
||||
}
|
||||
|
||||
epd = get_endp(s, pid, ep);
|
||||
epd->halted = 0;
|
||||
}
|
||||
|
||||
i += descriptors[i];
|
||||
break;
|
||||
default:
|
||||
trace_usb_host_parse_unknown(s->bus_num, s->addr,
|
||||
d->bLength, d->bDescriptorType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
usb_ep_dump(&s->dev);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
error:
|
||||
usb_ep_init(&s->dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1403,6 +1428,7 @@ static int usb_host_initfn(USBDevice *dev)
|
|||
if (s->match.bus_num != 0 && s->match.port != NULL) {
|
||||
usb_host_claim_port(s);
|
||||
}
|
||||
add_boot_device_path(s->bootindex, &dev->qdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1418,6 +1444,9 @@ static Property usb_host_dev_properties[] = {
|
|||
DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
|
||||
DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
|
||||
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
||||
DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
|
||||
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
|
||||
USB_HOST_OPT_PIPELINE, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ struct USBRedirDevice {
|
|||
CharDriverState *cs;
|
||||
uint8_t debug;
|
||||
char *filter_str;
|
||||
int32_t bootindex;
|
||||
/* Data passed from chardev the fd_read cb to the usbredirparser read cb */
|
||||
const uint8_t *read_buf;
|
||||
int read_buf_size;
|
||||
|
@ -835,7 +836,13 @@ static void usbredir_do_attach(void *opaque)
|
|||
{
|
||||
USBRedirDevice *dev = opaque;
|
||||
|
||||
usb_device_attach(&dev->dev);
|
||||
if (usb_device_attach(&dev->dev) != 0) {
|
||||
usbredir_device_disconnect(dev);
|
||||
if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
|
||||
usbredirparser_send_filter_reject(dev->parser);
|
||||
usbredirparser_do_write(dev->parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -923,6 +930,7 @@ static int usbredir_initfn(USBDevice *udev)
|
|||
qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
|
||||
usbredir_chardev_read, usbredir_chardev_event, dev);
|
||||
|
||||
add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1452,6 +1460,7 @@ static Property usbredir_properties[] = {
|
|||
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
|
||||
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
|
||||
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
|
||||
DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
26
trace-events
26
trace-events
|
@ -289,7 +289,7 @@ usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
|
|||
usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
|
||||
usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
|
||||
|
||||
# hw/usb-desc.c
|
||||
# hw/usb/desc.c
|
||||
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
|
||||
usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
|
||||
usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
|
||||
|
@ -301,6 +301,15 @@ usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d,
|
|||
usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
|
||||
usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
|
||||
|
||||
# hw/usb/dev-hub.c
|
||||
usb_hub_reset(int addr) "dev %d"
|
||||
usb_hub_control(int addr, int request, int value, int index, int length) "dev %d, req 0x%x, value %d, index %d, langth %d"
|
||||
usb_hub_get_port_status(int addr, int nr, int status, int changed) "dev %d, port %d, status 0x%x, changed 0x%x"
|
||||
usb_hub_set_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
|
||||
usb_hub_clear_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
|
||||
usb_hub_attach(int addr, int nr) "dev %d, port %d"
|
||||
usb_hub_detach(int addr, int nr) "dev %d, port %d"
|
||||
|
||||
# hw/usb/host-linux.c
|
||||
usb_host_open_started(int bus, int addr) "dev %d:%d"
|
||||
usb_host_open_success(int bus, int addr) "dev %d:%d"
|
||||
|
@ -312,11 +321,14 @@ usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d"
|
|||
usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d"
|
||||
usb_host_claim_interfaces(int bus, int addr, int config, int nif) "dev %d:%d, config %d, nif %d"
|
||||
usb_host_release_interfaces(int bus, int addr) "dev %d:%d"
|
||||
usb_host_req_control(int bus, int addr, int req, int value, int index) "dev %d:%d, req 0x%x, value %d, index %d"
|
||||
usb_host_req_data(int bus, int addr, int in, int ep, int size) "dev %d:%d, in %d, ep %d, size %d"
|
||||
usb_host_req_complete(int bus, int addr, int status) "dev %d:%d, status %d"
|
||||
usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d"
|
||||
usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d"
|
||||
usb_host_req_complete(int bus, int addr, void *p, int status) "dev %d:%d, packet %p, status %d"
|
||||
usb_host_req_emulated(int bus, int addr, void *p, int status) "dev %d:%d, packet %p, status %d"
|
||||
usb_host_req_canceled(int bus, int addr, void *p) "dev %d:%d, packet %p"
|
||||
usb_host_urb_submit(int bus, int addr, void *aurb, int length, int more) "dev %d:%d, aurb %p, length %d, more %d"
|
||||
usb_host_urb_complete(int bus, int addr, void *aurb, int status, int length, int more) "dev %d:%d, aurb %p, status %d, length %d, more %d"
|
||||
usb_host_urb_canceled(int bus, int addr, void *aurb) "dev %d:%d, aurb %p"
|
||||
usb_host_ep_set_halt(int bus, int addr, int ep) "dev %d:%d, ep %d"
|
||||
usb_host_ep_clear_halt(int bus, int addr, int ep) "dev %d:%d, ep %d"
|
||||
usb_host_ep_start_iso(int bus, int addr, int ep) "dev %d:%d, ep %d"
|
||||
|
@ -325,6 +337,12 @@ usb_host_reset(int bus, int addr) "dev %d:%d"
|
|||
usb_host_auto_scan_enabled(void)
|
||||
usb_host_auto_scan_disabled(void)
|
||||
usb_host_claim_port(int bus, int hub, int port) "bus %d, hub addr %d, port %d"
|
||||
usb_host_parse_device(int bus, int addr, int vendor, int product) "dev %d:%d, id %04x:%04x"
|
||||
usb_host_parse_config(int bus, int addr, int value, int active) "dev %d:%d, value %d, active %d"
|
||||
usb_host_parse_interface(int bus, int addr, int num, int alt, int active) "dev %d:%d, num %d, alt %d, active %d"
|
||||
usb_host_parse_endpoint(int bus, int addr, int ep, const char *dir, const char *type, int active) "dev %d:%d, ep %d, %s, %s, active %d"
|
||||
usb_host_parse_unknown(int bus, int addr, int len, int type) "dev %d:%d, len %d, type %d"
|
||||
usb_host_parse_error(int bus, int addr, const char *errmsg) "dev %d:%d, msg %s"
|
||||
|
||||
# hw/scsi-bus.c
|
||||
scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
|
||||
|
|
Loading…
Reference in a new issue