提交 f5eef2cf 编写于 作者: A Anthony Liguori

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

* kraxel/usb.49:
  usb-uhci: update irq line on reset
  usb: add serial number generator
  usb-redir: Not finding an async urb id is not an error
  usb-redir: Reset device address and speed on disconnect
  usb-redir: An interface count of 0 is a valid value
  usb-xhci: fix bit test
  usb-xhci: Use PCI DMA helper functions
  usb-host: fix zero-length packets
  usb-host: don't dereference invalid iovecs
  usb-storage: fix request canceling
  usb-ehci: Ensure frindex writes leave a valid frindex value
  usb-ehci: add missing usb_packet_init() call
  usb-ehci: remove hack
...@@ -501,6 +501,7 @@ void usb_packet_set_state(USBPacket *p, USBPacketState state) ...@@ -501,6 +501,7 @@ void usb_packet_set_state(USBPacket *p, USBPacketState state)
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep) void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep)
{ {
assert(!usb_packet_is_inflight(p)); assert(!usb_packet_is_inflight(p));
assert(p->iov.iov != NULL);
p->pid = pid; p->pid = pid;
p->ep = ep; p->ep = ep;
p->result = 0; p->result = 0;
......
#include <ctype.h>
#include "hw/usb.h" #include "hw/usb.h"
#include "hw/usb/desc.h" #include "hw/usb/desc.h"
#include "trace.h" #include "trace.h"
...@@ -412,6 +414,36 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str) ...@@ -412,6 +414,36 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str)
s->str = g_strdup(str); s->str = g_strdup(str);
} }
/*
* This function creates a serial number for a usb device.
* The serial number should:
* (a) Be unique within the virtual machine.
* (b) Be constant, so you don't get a new one each
* time the guest is started.
* So we are using the physical location to generate a serial number
* from it. It has three pieces: First a fixed, device-specific
* prefix. Second the device path of the host controller (which is
* the pci address in most cases). Third the physical port path.
* Results in serial numbers like this: "314159-0000:00:1d.7-3".
*/
void usb_desc_create_serial(USBDevice *dev)
{
DeviceState *hcd = dev->qdev.parent_bus->parent;
const USBDesc *desc = usb_device_get_usb_desc(dev);
int index = desc->id.iSerialNumber;
char serial[64];
int dst;
assert(index != 0 && desc->str[index] != NULL);
dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]);
if (hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
char *path = hcd->parent_bus->info->get_dev_path(hcd);
dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", path);
}
dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
usb_desc_set_string(dev, index, serial);
}
const char *usb_desc_get_string(USBDevice *dev, uint8_t index) const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
{ {
USBDescString *s; USBDescString *s;
......
...@@ -171,6 +171,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); ...@@ -171,6 +171,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
void usb_desc_init(USBDevice *dev); void usb_desc_init(USBDevice *dev);
void usb_desc_attach(USBDevice *dev); void usb_desc_attach(USBDevice *dev);
void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
void usb_desc_create_serial(USBDevice *dev);
const char *usb_desc_get_string(USBDevice *dev, uint8_t index); const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len); int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
......
...@@ -648,6 +648,7 @@ static int usb_audio_initfn(USBDevice *dev) ...@@ -648,6 +648,7 @@ static int usb_audio_initfn(USBDevice *dev)
{ {
USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
s->dev.opaque = s; s->dev.opaque = s;
AUD_register_card("usb-audio", &s->card); AUD_register_card("usb-audio", &s->card);
......
...@@ -494,6 +494,7 @@ static void usb_bt_handle_destroy(USBDevice *dev) ...@@ -494,6 +494,7 @@ static void usb_bt_handle_destroy(USBDevice *dev)
static int usb_bt_initfn(USBDevice *dev) static int usb_bt_initfn(USBDevice *dev)
{ {
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
return 0; return 0;
} }
......
...@@ -520,6 +520,7 @@ static int usb_hub_initfn(USBDevice *dev) ...@@ -520,6 +520,7 @@ static int usb_hub_initfn(USBDevice *dev)
USBHubPort *port; USBHubPort *port;
int i; int i;
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
for (i = 0; i < NUM_PORTS; i++) { for (i = 0; i < NUM_PORTS; i++) {
......
...@@ -1324,6 +1324,7 @@ static int usb_net_initfn(USBDevice *dev) ...@@ -1324,6 +1324,7 @@ static int usb_net_initfn(USBDevice *dev)
{ {
USBNetState *s = DO_UPCAST(USBNetState, dev, dev); USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
s->rndis_state = RNDIS_UNINITIALIZED; s->rndis_state = RNDIS_UNINITIALIZED;
......
...@@ -479,6 +479,7 @@ static int usb_serial_initfn(USBDevice *dev) ...@@ -479,6 +479,7 @@ static int usb_serial_initfn(USBDevice *dev)
{ {
USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev); USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
if (!s->cs) { if (!s->cs) {
......
...@@ -1189,6 +1189,7 @@ static int ccid_initfn(USBDevice *dev) ...@@ -1189,6 +1189,7 @@ static int ccid_initfn(USBDevice *dev)
{ {
USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL); qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP); s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
......
...@@ -268,7 +268,6 @@ static void usb_msd_request_cancelled(SCSIRequest *req) ...@@ -268,7 +268,6 @@ static void usb_msd_request_cancelled(SCSIRequest *req)
if (req == s->req) { if (req == s->req) {
scsi_req_unref(s->req); scsi_req_unref(s->req);
s->req = NULL; s->req = NULL;
s->packet = NULL;
s->scsi_len = 0; s->scsi_len = 0;
} }
} }
...@@ -330,6 +329,9 @@ static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p) ...@@ -330,6 +329,9 @@ static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
{ {
MSDState *s = DO_UPCAST(MSDState, dev, dev); MSDState *s = DO_UPCAST(MSDState, dev, dev);
assert(s->packet == p);
s->packet = NULL;
if (s->req) { if (s->req) {
scsi_req_cancel(s->req); scsi_req_cancel(s->req);
} }
...@@ -544,6 +546,8 @@ static int usb_msd_initfn(USBDevice *dev) ...@@ -544,6 +546,8 @@ static int usb_msd_initfn(USBDevice *dev)
} }
if (s->serial) { if (s->serial) {
usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial); usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial);
} else {
usb_desc_create_serial(dev);
} }
usb_desc_init(dev); usb_desc_init(dev);
......
...@@ -339,6 +339,7 @@ static void usb_wacom_handle_destroy(USBDevice *dev) ...@@ -339,6 +339,7 @@ static void usb_wacom_handle_destroy(USBDevice *dev)
static int usb_wacom_initfn(USBDevice *dev) static int usb_wacom_initfn(USBDevice *dev)
{ {
USBWacomState *s = DO_UPCAST(USBWacomState, dev, dev); USBWacomState *s = DO_UPCAST(USBWacomState, dev, dev);
usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
s->changed = 1; s->changed = 1;
return 0; return 0;
......
...@@ -133,7 +133,6 @@ ...@@ -133,7 +133,6 @@
#define NB_MAXINTRATE 8 // Max rate at which controller issues ints #define NB_MAXINTRATE 8 // Max rate at which controller issues ints
#define NB_PORTS 6 // Number of downstream ports #define NB_PORTS 6 // Number of downstream ports
#define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction #define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction
#define MAX_ITERATIONS 20 // Max number of QH before we break the loop
#define MAX_QH 100 // Max allowable queue heads in a chain #define MAX_QH 100 // Max allowable queue heads in a chain
/* Internal periodic / asynchronous schedule state machine states /* Internal periodic / asynchronous schedule state machine states
...@@ -665,6 +664,7 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async) ...@@ -665,6 +664,7 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async)
q = g_malloc0(sizeof(*q)); q = g_malloc0(sizeof(*q));
q->ehci = ehci; q->ehci = ehci;
usb_packet_init(&q->packet);
QTAILQ_INSERT_HEAD(head, q, next); QTAILQ_INSERT_HEAD(head, q, next);
trace_usb_ehci_queue_action(q, "alloc"); trace_usb_ehci_queue_action(q, "alloc");
return q; return q;
...@@ -1101,6 +1101,10 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) ...@@ -1101,6 +1101,10 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
val &= USBINTR_MASK; val &= USBINTR_MASK;
break; break;
case FRINDEX:
val &= 0x00003ff8; /* frindex is 14bits and always a multiple of 8 */
break;
case CONFIGFLAG: case CONFIGFLAG:
val &= 0x1; val &= 0x1;
if (val) { if (val) {
...@@ -1931,24 +1935,8 @@ static void ehci_advance_state(EHCIState *ehci, ...@@ -1931,24 +1935,8 @@ static void ehci_advance_state(EHCIState *ehci,
{ {
EHCIQueue *q = NULL; EHCIQueue *q = NULL;
int again; int again;
int iter = 0;
do { do {
if (ehci_get_state(ehci, async) == EST_FETCHQH) {
iter++;
/* if we are roaming a lot of QH without executing a qTD
* something is wrong with the linked list. TO-DO: why is
* this hack needed?
*/
assert(iter < MAX_ITERATIONS);
#if 0
if (iter > MAX_ITERATIONS) {
DPRINTF("\n*** advance_state: bailing on MAX ITERATIONS***\n");
ehci_set_state(ehci, async, EST_ACTIVE);
break;
}
#endif
}
switch(ehci_get_state(ehci, async)) { switch(ehci_get_state(ehci, async)) {
case EST_WAITLISTHEAD: case EST_WAITLISTHEAD:
again = ehci_state_waitlisthead(ehci, async); again = ehci_state_waitlisthead(ehci, async);
...@@ -1984,7 +1972,6 @@ static void ehci_advance_state(EHCIState *ehci, ...@@ -1984,7 +1972,6 @@ static void ehci_advance_state(EHCIState *ehci,
break; break;
case EST_EXECUTE: case EST_EXECUTE:
iter = 0;
again = ehci_state_execute(q, async); again = ehci_state_execute(q, async);
break; break;
......
...@@ -369,6 +369,7 @@ static void uhci_reset(void *opaque) ...@@ -369,6 +369,7 @@ static void uhci_reset(void *opaque)
} }
uhci_async_cancel_all(s); uhci_async_cancel_all(s);
uhci_update_irq(s);
} }
static void uhci_pre_save(void *opaque) static void uhci_pre_save(void *opaque)
......
此差异已折叠。
...@@ -884,16 +884,16 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) ...@@ -884,16 +884,16 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
} }
v = 0; v = 0;
prem = p->iov.iov[v].iov_len; prem = 0;
pbuf = p->iov.iov[v].iov_base; pbuf = NULL;
rem = p->iov.size; rem = p->iov.size;
while (rem) { do {
if (prem == 0) { if (prem == 0 && rem > 0) {
v++;
assert(v < p->iov.niov); assert(v < p->iov.niov);
prem = p->iov.iov[v].iov_len; prem = p->iov.iov[v].iov_len;
pbuf = p->iov.iov[v].iov_base; pbuf = p->iov.iov[v].iov_base;
assert(prem <= rem); assert(prem <= rem);
v++;
} }
aurb = async_alloc(s); aurb = async_alloc(s);
aurb->packet = p; aurb->packet = p;
...@@ -938,7 +938,7 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) ...@@ -938,7 +938,7 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
return USB_RET_STALL; return USB_RET_STALL;
} }
} }
} } while (rem > 0);
return USB_RET_ASYNC; return USB_RET_ASYNC;
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "hw/usb.h" #include "hw/usb.h"
#define MAX_ENDPOINTS 32 #define MAX_ENDPOINTS 32
#define NO_INTERFACE_INFO 255 /* Valid interface_count always <= 32 */
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f)) #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f)) #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
...@@ -276,7 +277,7 @@ static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id) ...@@ -276,7 +277,7 @@ static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
return aurb; return aurb;
} }
} }
ERROR("could not find async urb for packet_id %u\n", packet_id); DPRINTF("could not find async urb for packet_id %u\n", packet_id);
return NULL; return NULL;
} }
...@@ -970,7 +971,7 @@ static void usbredir_handle_destroy(USBDevice *udev) ...@@ -970,7 +971,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
static int usbredir_check_filter(USBRedirDevice *dev) static int usbredir_check_filter(USBRedirDevice *dev)
{ {
if (dev->interface_info.interface_count == 0) { if (dev->interface_info.interface_count == NO_INTERFACE_INFO) {
ERROR("No interface info for device\n"); ERROR("No interface info for device\n");
goto error; goto error;
} }
...@@ -1134,7 +1135,9 @@ static void usbredir_device_disconnect(void *priv) ...@@ -1134,7 +1135,9 @@ static void usbredir_device_disconnect(void *priv)
QTAILQ_INIT(&dev->endpoint[i].bufpq); QTAILQ_INIT(&dev->endpoint[i].bufpq);
} }
usb_ep_init(&dev->dev); usb_ep_init(&dev->dev);
dev->interface_info.interface_count = 0; dev->interface_info.interface_count = NO_INTERFACE_INFO;
dev->dev.addr = 0;
dev->dev.speed = 0;
} }
static void usbredir_interface_info(void *priv, static void usbredir_interface_info(void *priv,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册