提交 9ca2140a 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'kraxel/usb.37' into staging

* kraxel/usb.37:
  usb-redir: Improve some debugging messages
  usb-redir: Try to keep our buffer size near the target size
  usb-redir: Pre-fill our isoc input buffer before sending pkts to the host
  usb-redir: Dynamically adjust iso buffering size based on ep interval
  usb-redir: Clear iso / irq error when stopping the stream
  usb: link packets to endpoints not devices
  usb: add max_packet_size to USBEndpoint
  usb/debug: add usb_ep_dump
  usb-desc: USBEndpoint support
  usb: add ifnum to USBEndpoint
  usb: add USBEndpoint
  xhci: Initial xHCI implementation
  usb: add audio device model
  usb-desc: audio endpoint support
  usb: track altsetting in USBDevice
  usb: track configuration and interface count in USBDevice.
  usb-host: rip out legacy procfs support
......@@ -102,7 +102,7 @@ common-obj-y += scsi-disk.o cdrom.o
common-obj-y += scsi-generic.o scsi-bus.o
common-obj-y += hid.o
common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o
common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o usb-audio.o
common-obj-$(CONFIG_SSI) += ssi.o
common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
common-obj-$(CONFIG_SD) += sd.o
......@@ -211,6 +211,7 @@ hw-obj-$(CONFIG_PCKBD) += pckbd.o
hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
hw-obj-$(CONFIG_USB_XHCI) += usb-xhci.o
hw-obj-$(CONFIG_FDC) += fdc.o
hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
......
......@@ -4,6 +4,7 @@ CONFIG_VIRTIO=y
CONFIG_USB_UHCI=y
CONFIG_USB_OHCI=y
CONFIG_USB_EHCI=y
CONFIG_USB_XHCI=y
CONFIG_NE2000_PCI=y
CONFIG_EEPRO100_PCI=y
CONFIG_PCNET_PCI=y
......
......@@ -120,3 +120,6 @@
#define PCI_VENDOR_ID_XEN 0x5853
#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
#define PCI_VENDOR_ID_NEC 0x1033
#define PCI_DEVICE_ID_NEC_UPD720200 0x0194
此差异已折叠。
......@@ -28,7 +28,6 @@ struct USBBtState {
USBDevice dev;
struct HCIInfo *hci;
int altsetting;
int config;
#define CFIFO_LEN_MASK 255
......@@ -362,7 +361,6 @@ static void usb_bt_handle_reset(USBDevice *dev)
s->outcmd.len = 0;
s->outacl.len = 0;
s->outsco.len = 0;
s->altsetting = 0;
}
static int usb_bt_handle_control(USBDevice *dev, USBPacket *p,
......@@ -402,26 +400,6 @@ static int usb_bt_handle_control(USBDevice *dev, USBPacket *p,
case EndpointOutRequest | USB_REQ_SET_FEATURE:
goto fail;
break;
case InterfaceRequest | USB_REQ_GET_INTERFACE:
if (value != 0 || (index & ~1) || length != 1)
goto fail;
if (index == 1)
data[0] = s->altsetting;
else
data[0] = 0;
ret = 1;
break;
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
if ((index & ~1) || length != 0 ||
(index == 1 && (value < 0 || value > 4)) ||
(index == 0 && value != 0)) {
printf("%s: Wrong SET_INTERFACE request (%i, %i)\n",
__FUNCTION__, index, value);
goto fail;
}
s->altsetting = value;
ret = 0;
break;
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8):
if (s->config)
usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send,
......
......@@ -75,6 +75,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
dev->info = info;
dev->auto_attach = 1;
QLIST_INIT(&dev->strings);
usb_ep_init(dev);
rc = usb_claim_port(dev);
if (rc != 0) {
return rc;
......
......@@ -611,14 +611,6 @@ static int ccid_handle_control(USBDevice *dev, USBPacket *p, int request,
}
switch (request) {
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
/* Class specific requests. */
case InterfaceOutClass | CCID_CONTROL_ABORT:
DPRINTF(s, 1, "ccid_control abort UNIMPLEMENTED\n");
......
......@@ -192,9 +192,10 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len)
int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len)
{
uint8_t bLength = 0x07;
uint8_t bLength = ep->is_audio ? 0x09 : 0x07;
uint8_t extralen = ep->extra ? ep->extra[0] : 0;
if (len < bLength) {
if (len < bLength + extralen) {
return -1;
}
......@@ -205,8 +206,15 @@ int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len)
dest[0x04] = usb_lo(ep->wMaxPacketSize);
dest[0x05] = usb_hi(ep->wMaxPacketSize);
dest[0x06] = ep->bInterval;
if (ep->is_audio) {
dest[0x07] = ep->bRefresh;
dest[0x08] = ep->bSynchAddress;
}
if (ep->extra) {
memcpy(dest + bLength, ep->extra, extralen);
}
return bLength;
return bLength + extralen;
}
int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
......@@ -223,6 +231,111 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
/* ------------------------------------------------------------------ */
static void usb_desc_ep_init(USBDevice *dev)
{
const USBDescIface *iface;
int i, e, pid, ep;
usb_ep_init(dev);
for (i = 0; i < dev->ninterfaces; i++) {
iface = dev->ifaces[i];
if (iface == NULL) {
continue;
}
for (e = 0; e < iface->bNumEndpoints; e++) {
pid = (iface->eps[e].bEndpointAddress & USB_DIR_IN) ?
USB_TOKEN_IN : USB_TOKEN_OUT;
ep = iface->eps[e].bEndpointAddress & 0x0f;
usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03);
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
usb_ep_set_max_packet_size(dev, pid, ep,
iface->eps[e].wMaxPacketSize);
}
}
}
static const USBDescIface *usb_desc_find_interface(USBDevice *dev,
int nif, int alt)
{
const USBDescIface *iface;
int g, i;
if (!dev->config) {
return NULL;
}
for (g = 0; g < dev->config->nif_groups; g++) {
for (i = 0; i < dev->config->if_groups[g].nif; i++) {
iface = &dev->config->if_groups[g].ifs[i];
if (iface->bInterfaceNumber == nif &&
iface->bAlternateSetting == alt) {
return iface;
}
}
}
for (i = 0; i < dev->config->nif; i++) {
iface = &dev->config->ifs[i];
if (iface->bInterfaceNumber == nif &&
iface->bAlternateSetting == alt) {
return iface;
}
}
return NULL;
}
static int usb_desc_set_interface(USBDevice *dev, int index, int value)
{
const USBDescIface *iface;
int old;
iface = usb_desc_find_interface(dev, index, value);
if (iface == NULL) {
return -1;
}
old = dev->altsetting[index];
dev->altsetting[index] = value;
dev->ifaces[index] = iface;
usb_desc_ep_init(dev);
if (dev->info->set_interface && old != value) {
dev->info->set_interface(dev, index, old, value);
}
return 0;
}
static int usb_desc_set_config(USBDevice *dev, int value)
{
int i;
if (value == 0) {
dev->configuration = 0;
dev->ninterfaces = 0;
dev->config = NULL;
} else {
for (i = 0; i < dev->device->bNumConfigurations; i++) {
if (dev->device->confs[i].bConfigurationValue == value) {
dev->configuration = value;
dev->ninterfaces = dev->device->confs[i].bNumInterfaces;
dev->config = dev->device->confs + i;
assert(dev->ninterfaces <= USB_MAX_INTERFACES);
}
}
if (i < dev->device->bNumConfigurations) {
return -1;
}
}
for (i = 0; i < dev->ninterfaces; i++) {
usb_desc_set_interface(dev, i, 0);
}
for (; i < USB_MAX_INTERFACES; i++) {
dev->altsetting[i] = 0;
dev->ifaces[i] = NULL;
}
return 0;
}
static void usb_desc_setdefaults(USBDevice *dev)
{
const USBDesc *desc = dev->info->usb_desc;
......@@ -237,7 +350,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
dev->device = desc->high;
break;
}
dev->config = dev->device->confs;
usb_desc_set_config(dev, 0);
}
void usb_desc_init(USBDevice *dev)
......@@ -408,7 +521,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
int request, int value, int index, int length, uint8_t *data)
{
const USBDesc *desc = dev->info->usb_desc;
int i, ret = -1;
int ret = -1;
assert(desc != NULL);
switch(request) {
......@@ -427,12 +540,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
for (i = 0; i < dev->device->bNumConfigurations; i++) {
if (dev->device->confs[i].bConfigurationValue == value) {
dev->config = dev->device->confs + i;
ret = 0;
}
}
ret = usb_desc_set_config(dev, value);
trace_usb_set_config(dev->addr, value, ret);
break;
......@@ -461,6 +569,19 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
}
trace_usb_set_device_feature(dev->addr, value, ret);
break;
case InterfaceRequest | USB_REQ_GET_INTERFACE:
if (index < 0 || index >= dev->ninterfaces) {
break;
}
data[0] = dev->altsetting[index];
ret = 1;
break;
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
ret = usb_desc_set_interface(dev, index, value);
trace_usb_set_interface(dev->addr, index, value, ret);
break;
}
return ret;
}
......@@ -71,6 +71,11 @@ struct USBDescEndpoint {
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;
};
struct USBDescOther {
......
......@@ -715,7 +715,8 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)
EHCIQueue *q, *tmp;
QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
if (q->packet.owner != dev) {
if (q->packet.owner == NULL ||
q->packet.owner->dev != dev) {
continue;
}
ehci_free_queue(q);
......
......@@ -384,13 +384,6 @@ static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
ret = 0;
switch (request) {
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
/* hid specific requests */
case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
switch (value >> 8) {
......
......@@ -258,13 +258,6 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
}
ret = 0;
break;
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
/* usb specific requests */
case GetHubStatus:
data[0] = 0;
......
......@@ -306,19 +306,9 @@ static int usb_msd_handle_control(USBDevice *dev, USBPacket *p,
ret = 0;
switch (request) {
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
ret = 0;
break;
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
/* Class specific requests. */
case ClassInterfaceOutRequest | MassStorageReset:
/* Reset state ready for the next CBW. */
......
......@@ -812,7 +812,8 @@ static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
for (ep = 0; ep < 16; ep++) {
for (dir = 0; dir < 2; dir++) {
if (s->ep[ep].packey[dir].p.owner != dev) {
if (s->ep[ep].packey[dir].p.owner == NULL ||
s->ep[ep].packey[dir].p.owner->dev != dev) {
continue;
}
usb_cancel_packet(&s->ep[ep].packey[dir].p);
......
......@@ -71,9 +71,6 @@ enum usbstring_idx {
#define USB_CDC_UNION_TYPE 0x06 /* union_desc */
#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define USB_CDC_REQ_SET_LINE_CODING 0x20
......@@ -1098,17 +1095,6 @@ static int usb_net_handle_control(USBDevice *dev, USBPacket *p,
#endif
break;
case DeviceRequest | USB_REQ_GET_INTERFACE:
case InterfaceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
default:
fail:
fprintf(stderr, "usbnet: failed control transaction: "
......
......@@ -1707,7 +1707,9 @@ static void ohci_mem_write(void *opaque,
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
{
if (ohci->async_td && ohci->usb_packet.owner == dev) {
if (ohci->async_td &&
ohci->usb_packet.owner != NULL &&
ohci->usb_packet.owner->dev == dev) {
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
}
......
......@@ -233,13 +233,6 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
ret = 0;
switch (request) {
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
ret = 0;
break;
......
......@@ -245,7 +245,8 @@ static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev)
UHCIAsync *curr, *n;
QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
if (curr->packet.owner != dev) {
if (curr->packet.owner == NULL ||
curr->packet.owner->dev != dev) {
continue;
}
uhci_async_unlink(s, curr);
......
......@@ -263,13 +263,6 @@ static int usb_wacom_handle_control(USBDevice *dev, USBPacket *p,
ret = 0;
switch (request) {
case DeviceRequest | USB_REQ_GET_INTERFACE:
data[0] = 0;
ret = 1;
break;
case DeviceOutRequest | USB_REQ_SET_INTERFACE:
ret = 0;
break;
case WACOM_SET_REPORT:
if (s->mouse_grabbed) {
qemu_remove_mouse_event_handler(s->eh_entry);
......
此差异已折叠。
......@@ -329,7 +329,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
ret = dev->info->handle_packet(dev, p);
if (ret == USB_RET_ASYNC) {
if (p->owner == NULL) {
p->owner = dev;
p->owner = usb_ep_get(dev, p->pid, p->devep);
} else {
/* We'll end up here when usb_handle_packet is called
* recursively due to a hub being in the chain. Nothing
......@@ -357,7 +357,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
void usb_cancel_packet(USBPacket * p)
{
assert(p->owner != NULL);
p->owner->info->cancel_packet(p->owner, p);
p->owner->dev->info->cancel_packet(p->owner->dev, p);
p->owner = NULL;
}
......@@ -414,3 +414,124 @@ void usb_packet_cleanup(USBPacket *p)
{
qemu_iovec_destroy(&p->iov);
}
void usb_ep_init(USBDevice *dev)
{
int ep;
dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
dev->ep_ctl.ifnum = 0;
dev->ep_ctl.dev = dev;
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
dev->ep_in[ep].ifnum = 0;
dev->ep_out[ep].ifnum = 0;
dev->ep_in[ep].dev = dev;
dev->ep_out[ep].dev = dev;
}
}
void usb_ep_dump(USBDevice *dev)
{
static const char *tname[] = {
[USB_ENDPOINT_XFER_CONTROL] = "control",
[USB_ENDPOINT_XFER_ISOC] = "isoc",
[USB_ENDPOINT_XFER_BULK] = "bulk",
[USB_ENDPOINT_XFER_INT] = "int",
};
int ifnum, ep, first;
fprintf(stderr, "Device \"%s\", config %d\n",
dev->product_desc, dev->configuration);
for (ifnum = 0; ifnum < 16; ifnum++) {
first = 1;
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
dev->ep_in[ep].ifnum == ifnum) {
if (first) {
first = 0;
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
}
fprintf(stderr, " Endpoint %d, IN, %s, %d max\n", ep,
tname[dev->ep_in[ep].type],
dev->ep_in[ep].max_packet_size);
}
if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
dev->ep_out[ep].ifnum == ifnum) {
if (first) {
first = 0;
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
}
fprintf(stderr, " Endpoint %d, OUT, %s, %d max\n", ep,
tname[dev->ep_out[ep].type],
dev->ep_out[ep].max_packet_size);
}
}
}
fprintf(stderr, "--\n");
}
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
{
struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out;
if (ep == 0) {
return &dev->ep_ctl;
}
assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
return eps + ep - 1;
}
uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
return uep->type;
}
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
uep->type = type;
}
uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
return uep->ifnum;
}
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
uep->ifnum = ifnum;
}
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
uint16_t raw)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
int size, microframes;
size = raw & 0x7ff;
switch ((raw >> 11) & 3) {
case 1:
microframes = 2;
break;
case 2:
microframes = 3;
break;
default:
microframes = 1;
break;
}
uep->max_packet_size = size * microframes;
}
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
return uep->max_packet_size;
}
......@@ -79,6 +79,11 @@
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
#define USB_SUBCLASS_UNDEFINED 0
#define USB_SUBCLASS_AUDIO_CONTROL 1
#define USB_SUBCLASS_AUDIO_STREAMING 2
#define USB_SUBCLASS_AUDIO_MIDISTREAMING 3
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
......@@ -132,11 +137,14 @@
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_DEBUG 0x0A
#define USB_DT_INTERFACE_ASSOC 0x0B
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
#define USB_ENDPOINT_XFER_INVALID 255
typedef struct USBBus USBBus;
typedef struct USBBusOps USBBusOps;
......@@ -144,6 +152,7 @@ typedef struct USBPort USBPort;
typedef struct USBDevice USBDevice;
typedef struct USBDeviceInfo USBDeviceInfo;
typedef struct USBPacket USBPacket;
typedef struct USBEndpoint USBEndpoint;
typedef struct USBDesc USBDesc;
typedef struct USBDescID USBDescID;
......@@ -161,6 +170,16 @@ struct USBDescString {
QLIST_ENTRY(USBDescString) next;
};
#define USB_MAX_ENDPOINTS 15
#define USB_MAX_INTERFACES 16
struct USBEndpoint {
uint8_t type;
uint8_t ifnum;
int max_packet_size;
USBDevice *dev;
};
/* definition of a USB device */
struct USBDevice {
DeviceState qdev;
......@@ -186,9 +205,18 @@ struct USBDevice {
int32_t setup_len;
int32_t setup_index;
USBEndpoint ep_ctl;
USBEndpoint ep_in[USB_MAX_ENDPOINTS];
USBEndpoint ep_out[USB_MAX_ENDPOINTS];
QLIST_HEAD(, USBDescString) strings;
const USBDescDevice *device;
int configuration;
int ninterfaces;
int altsetting[USB_MAX_INTERFACES];
const USBDescConfig *config;
const USBDescIface *ifaces[USB_MAX_INTERFACES];
};
struct USBDeviceInfo {
......@@ -241,6 +269,9 @@ struct USBDeviceInfo {
*/
int (*handle_data)(USBDevice *dev, USBPacket *p);
void (*set_interface)(USBDevice *dev, int interface,
int alt_old, int alt_new);
const char *product_desc;
const USBDesc *usb_desc;
......@@ -288,7 +319,7 @@ struct USBPacket {
QEMUIOVector iov;
int result; /* transfer length or USB_RET_* status code */
/* Internal use by the USB layer. */
USBDevice *owner;
USBEndpoint *owner;
};
void usb_packet_init(USBPacket *p);
......@@ -304,6 +335,17 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p);
void usb_packet_complete(USBDevice *dev, USBPacket *p);
void usb_cancel_packet(USBPacket * p);
void usb_ep_init(USBDevice *dev);
void usb_ep_dump(USBDevice *dev);
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
uint16_t raw);
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
void usb_attach(USBPort *port);
void usb_detach(USBPort *port);
void usb_reset(USBPort *port);
......
......@@ -246,6 +246,7 @@ usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query
usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %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_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %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"
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册