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
This commit is contained in:
Anthony Liguori 2012-04-26 15:21:52 -05:00
commit f5eef2cf66
16 changed files with 157 additions and 127 deletions

View File

@ -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;

View File

@ -1,3 +1,5 @@
#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)
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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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++) {

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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)
{ {
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)
} }
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);

View File

@ -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;

View File

@ -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)
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)
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,
{ {
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,
break; break;
case EST_EXECUTE: case EST_EXECUTE:
iter = 0;
again = ehci_state_execute(q, async); again = ehci_state_execute(q, async);
break; break;

View File

@ -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)

View File

@ -22,7 +22,6 @@
#include "qemu-timer.h" #include "qemu-timer.h"
#include "hw/usb.h" #include "hw/usb.h"
#include "hw/pci.h" #include "hw/pci.h"
#include "hw/qdev-addr.h"
#include "hw/msi.h" #include "hw/msi.h"
//#define DEBUG_XHCI //#define DEBUG_XHCI
@ -140,7 +139,7 @@ typedef struct XHCITRB {
uint64_t parameter; uint64_t parameter;
uint32_t status; uint32_t status;
uint32_t control; uint32_t control;
target_phys_addr_t addr; dma_addr_t addr;
bool ccs; bool ccs;
} XHCITRB; } XHCITRB;
@ -291,8 +290,8 @@ typedef enum EPType {
} EPType; } EPType;
typedef struct XHCIRing { typedef struct XHCIRing {
target_phys_addr_t base; dma_addr_t base;
target_phys_addr_t dequeue; dma_addr_t dequeue;
bool ccs; bool ccs;
} XHCIRing; } XHCIRing;
@ -345,7 +344,7 @@ typedef struct XHCIEPContext {
unsigned int next_bg; unsigned int next_bg;
XHCITransfer bg_transfers[BG_XFERS]; XHCITransfer bg_transfers[BG_XFERS];
EPType type; EPType type;
target_phys_addr_t pctx; dma_addr_t pctx;
unsigned int max_psize; unsigned int max_psize;
bool has_bg; bool has_bg;
uint32_t state; uint32_t state;
@ -353,7 +352,7 @@ typedef struct XHCIEPContext {
typedef struct XHCISlot { typedef struct XHCISlot {
bool enabled; bool enabled;
target_phys_addr_t ctx; dma_addr_t ctx;
unsigned int port; unsigned int port;
unsigned int devaddr; unsigned int devaddr;
XHCIEPContext * eps[31]; XHCIEPContext * eps[31];
@ -402,7 +401,7 @@ struct XHCIState {
uint32_t erdp_low; uint32_t erdp_low;
uint32_t erdp_high; uint32_t erdp_high;
target_phys_addr_t er_start; dma_addr_t er_start;
uint32_t er_size; uint32_t er_size;
bool er_pcs; bool er_pcs;
unsigned int er_ep_idx; unsigned int er_ep_idx;
@ -479,22 +478,22 @@ static const char *trb_name(XHCITRB *trb)
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
unsigned int epid); unsigned int epid);
static inline target_phys_addr_t xhci_addr64(uint32_t low, uint32_t high) static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high)
{ {
#if TARGET_PHYS_ADDR_BITS > 32 if (sizeof(dma_addr_t) == 4) {
return low | ((target_phys_addr_t)high << 32); return low;
#else } else {
return low; return low | (((dma_addr_t)high << 16) << 16);
#endif }
} }
static inline target_phys_addr_t xhci_mask64(uint64_t addr) static inline dma_addr_t xhci_mask64(uint64_t addr)
{ {
#if TARGET_PHYS_ADDR_BITS > 32 if (sizeof(dma_addr_t) == 4) {
return addr; return addr & 0xffffffff;
#else } else {
return addr & 0xffffffff; return addr;
#endif }
} }
static void xhci_irq_update(XHCIState *xhci) static void xhci_irq_update(XHCIState *xhci)
@ -502,7 +501,7 @@ static void xhci_irq_update(XHCIState *xhci)
int level = 0; int level = 0;
if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE && if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE &&
xhci->usbcmd && USBCMD_INTE) { xhci->usbcmd & USBCMD_INTE) {
level = 1; level = 1;
} }
@ -532,7 +531,7 @@ static void xhci_die(XHCIState *xhci)
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) static void xhci_write_event(XHCIState *xhci, XHCIEvent *event)
{ {
XHCITRB ev_trb; XHCITRB ev_trb;
target_phys_addr_t addr; dma_addr_t addr;
ev_trb.parameter = cpu_to_le64(event->ptr); ev_trb.parameter = cpu_to_le64(event->ptr);
ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24)); ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24));
@ -548,7 +547,7 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event)
trb_name(&ev_trb)); trb_name(&ev_trb));
addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx;
cpu_physical_memory_write(addr, (uint8_t *) &ev_trb, TRB_SIZE); pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE);
xhci->er_ep_idx++; xhci->er_ep_idx++;
if (xhci->er_ep_idx >= xhci->er_size) { if (xhci->er_ep_idx >= xhci->er_size) {
@ -559,7 +558,7 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event)
static void xhci_events_update(XHCIState *xhci) static void xhci_events_update(XHCIState *xhci)
{ {
target_phys_addr_t erdp; dma_addr_t erdp;
unsigned int dp_idx; unsigned int dp_idx;
bool do_irq = 0; bool do_irq = 0;
@ -570,8 +569,8 @@ static void xhci_events_update(XHCIState *xhci)
erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high);
if (erdp < xhci->er_start || if (erdp < xhci->er_start ||
erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) {
fprintf(stderr, "xhci: ERDP out of bounds: "TARGET_FMT_plx"\n", erdp); fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
fprintf(stderr, "xhci: ER at "TARGET_FMT_plx" len %d\n", fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n",
xhci->er_start, xhci->er_size); xhci->er_start, xhci->er_size);
xhci_die(xhci); xhci_die(xhci);
return; return;
@ -630,7 +629,7 @@ static void xhci_events_update(XHCIState *xhci)
static void xhci_event(XHCIState *xhci, XHCIEvent *event) static void xhci_event(XHCIState *xhci, XHCIEvent *event)
{ {
target_phys_addr_t erdp; dma_addr_t erdp;
unsigned int dp_idx; unsigned int dp_idx;
if (xhci->er_full) { if (xhci->er_full) {
@ -649,8 +648,8 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event)
erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high);
if (erdp < xhci->er_start || if (erdp < xhci->er_start ||
erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) {
fprintf(stderr, "xhci: ERDP out of bounds: "TARGET_FMT_plx"\n", erdp); fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
fprintf(stderr, "xhci: ER at "TARGET_FMT_plx" len %d\n", fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n",
xhci->er_start, xhci->er_size); xhci->er_start, xhci->er_size);
xhci_die(xhci); xhci_die(xhci);
return; return;
@ -686,7 +685,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event)
} }
static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
target_phys_addr_t base) dma_addr_t base)
{ {
ring->base = base; ring->base = base;
ring->dequeue = base; ring->dequeue = base;
@ -694,18 +693,18 @@ static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
} }
static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
target_phys_addr_t *addr) dma_addr_t *addr)
{ {
while (1) { while (1) {
TRBType type; TRBType type;
cpu_physical_memory_read(ring->dequeue, (uint8_t *) trb, TRB_SIZE); pci_dma_read(&xhci->pci_dev, ring->dequeue, trb, TRB_SIZE);
trb->addr = ring->dequeue; trb->addr = ring->dequeue;
trb->ccs = ring->ccs; trb->ccs = ring->ccs;
le64_to_cpus(&trb->parameter); le64_to_cpus(&trb->parameter);
le32_to_cpus(&trb->status); le32_to_cpus(&trb->status);
le32_to_cpus(&trb->control); le32_to_cpus(&trb->control);
DPRINTF("xhci: TRB fetched [" TARGET_FMT_plx "]: " DPRINTF("xhci: TRB fetched [" DMA_ADDR_FMT "]: "
"%016" PRIx64 " %08x %08x %s\n", "%016" PRIx64 " %08x %08x %s\n",
ring->dequeue, trb->parameter, trb->status, trb->control, ring->dequeue, trb->parameter, trb->status, trb->control,
trb_name(trb)); trb_name(trb));
@ -735,19 +734,19 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
{ {
XHCITRB trb; XHCITRB trb;
int length = 0; int length = 0;
target_phys_addr_t dequeue = ring->dequeue; dma_addr_t dequeue = ring->dequeue;
bool ccs = ring->ccs; bool ccs = ring->ccs;
/* hack to bundle together the two/three TDs that make a setup transfer */ /* hack to bundle together the two/three TDs that make a setup transfer */
bool control_td_set = 0; bool control_td_set = 0;
while (1) { while (1) {
TRBType type; TRBType type;
cpu_physical_memory_read(dequeue, (uint8_t *) &trb, TRB_SIZE); pci_dma_read(&xhci->pci_dev, dequeue, &trb, TRB_SIZE);
le64_to_cpus(&trb.parameter); le64_to_cpus(&trb.parameter);
le32_to_cpus(&trb.status); le32_to_cpus(&trb.status);
le32_to_cpus(&trb.control); le32_to_cpus(&trb.control);
DPRINTF("xhci: TRB peeked [" TARGET_FMT_plx "]: " DPRINTF("xhci: TRB peeked [" DMA_ADDR_FMT "]: "
"%016" PRIx64 " %08x %08x\n", "%016" PRIx64 " %08x %08x\n",
dequeue, trb.parameter, trb.status, trb.control); dequeue, trb.parameter, trb.status, trb.control);
@ -790,8 +789,8 @@ static void xhci_er_reset(XHCIState *xhci)
xhci_die(xhci); xhci_die(xhci);
return; return;
} }
target_phys_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high); dma_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high);
cpu_physical_memory_read(erstba, (uint8_t *) &seg, sizeof(seg)); pci_dma_read(&xhci->pci_dev, erstba, &seg, sizeof(seg));
le32_to_cpus(&seg.addr_low); le32_to_cpus(&seg.addr_low);
le32_to_cpus(&seg.addr_high); le32_to_cpus(&seg.addr_high);
le32_to_cpus(&seg.size); le32_to_cpus(&seg.size);
@ -807,7 +806,7 @@ static void xhci_er_reset(XHCIState *xhci)
xhci->er_pcs = 1; xhci->er_pcs = 1;
xhci->er_full = 0; xhci->er_full = 0;
DPRINTF("xhci: event ring:" TARGET_FMT_plx " [%d]\n", DPRINTF("xhci: event ring:" DMA_ADDR_FMT " [%d]\n",
xhci->er_start, xhci->er_size); xhci->er_start, xhci->er_size);
} }
@ -833,24 +832,24 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
return; return;
} }
cpu_physical_memory_read(epctx->pctx, (uint8_t *) ctx, sizeof(ctx)); pci_dma_read(&xhci->pci_dev, epctx->pctx, ctx, sizeof(ctx));
ctx[0] &= ~EP_STATE_MASK; ctx[0] &= ~EP_STATE_MASK;
ctx[0] |= state; ctx[0] |= state;
ctx[2] = epctx->ring.dequeue | epctx->ring.ccs; ctx[2] = epctx->ring.dequeue | epctx->ring.ccs;
ctx[3] = (epctx->ring.dequeue >> 16) >> 16; ctx[3] = (epctx->ring.dequeue >> 16) >> 16;
DPRINTF("xhci: set epctx: " TARGET_FMT_plx " state=%d dequeue=%08x%08x\n", DPRINTF("xhci: set epctx: " DMA_ADDR_FMT " state=%d dequeue=%08x%08x\n",
epctx->pctx, state, ctx[3], ctx[2]); epctx->pctx, state, ctx[3], ctx[2]);
cpu_physical_memory_write(epctx->pctx, (uint8_t *) ctx, sizeof(ctx)); pci_dma_write(&xhci->pci_dev, epctx->pctx, ctx, sizeof(ctx));
epctx->state = state; epctx->state = state;
} }
static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
unsigned int epid, target_phys_addr_t pctx, unsigned int epid, dma_addr_t pctx,
uint32_t *ctx) uint32_t *ctx)
{ {
XHCISlot *slot; XHCISlot *slot;
XHCIEPContext *epctx; XHCIEPContext *epctx;
target_phys_addr_t dequeue; dma_addr_t dequeue;
int i; int i;
assert(slotid >= 1 && slotid <= MAXSLOTS); assert(slotid >= 1 && slotid <= MAXSLOTS);
@ -1087,7 +1086,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
{ {
XHCISlot *slot; XHCISlot *slot;
XHCIEPContext *epctx; XHCIEPContext *epctx;
target_phys_addr_t dequeue; dma_addr_t dequeue;
assert(slotid >= 1 && slotid <= MAXSLOTS); assert(slotid >= 1 && slotid <= MAXSLOTS);
@ -1142,7 +1141,7 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
for (i = 0; i < xfer->trb_count; i++) { for (i = 0; i < xfer->trb_count; i++) {
XHCITRB *trb = &xfer->trbs[i]; XHCITRB *trb = &xfer->trbs[i];
target_phys_addr_t addr; dma_addr_t addr;
unsigned int chunk = 0; unsigned int chunk = 0;
switch (TRB_TYPE(*trb)) { switch (TRB_TYPE(*trb)) {
@ -1173,11 +1172,11 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
memcpy(data, &idata, chunk); memcpy(data, &idata, chunk);
} else { } else {
DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at " DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at "
TARGET_FMT_plx "\n", in_xfer, chunk, addr); DMA_ADDR_FMT "\n", in_xfer, chunk, addr);
if (in_xfer) { if (in_xfer) {
cpu_physical_memory_write(addr, data, chunk); pci_dma_write(&xhci->pci_dev, addr, data, chunk);
} else { } else {
cpu_physical_memory_read(addr, data, chunk); pci_dma_read(&xhci->pci_dev, addr, data, chunk);
} }
#ifdef DEBUG_DATA #ifdef DEBUG_DATA
unsigned int count = chunk; unsigned int count = chunk;
@ -1240,7 +1239,7 @@ static void xhci_stall_ep(XHCITransfer *xfer)
epctx->ring.ccs = xfer->trbs[0].ccs; epctx->ring.ccs = xfer->trbs[0].ccs;
xhci_set_ep_state(xhci, epctx, EP_HALTED); xhci_set_ep_state(xhci, epctx, EP_HALTED);
DPRINTF("xhci: stalled slot %d ep %d\n", xfer->slotid, xfer->epid); DPRINTF("xhci: stalled slot %d ep %d\n", xfer->slotid, xfer->epid);
DPRINTF("xhci: will continue at "TARGET_FMT_plx"\n", epctx->ring.dequeue); DPRINTF("xhci: will continue at "DMA_ADDR_FMT"\n", epctx->ring.dequeue);
} }
static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
@ -1802,7 +1801,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
{ {
XHCISlot *slot; XHCISlot *slot;
USBDevice *dev; USBDevice *dev;
target_phys_addr_t ictx, octx, dcbaap; dma_addr_t ictx, octx, dcbaap;
uint64_t poctx; uint64_t poctx;
uint32_t ictl_ctx[2]; uint32_t ictl_ctx[2];
uint32_t slot_ctx[4]; uint32_t slot_ctx[4];
@ -1815,15 +1814,14 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci_address_slot(%d)\n", slotid); DPRINTF("xhci_address_slot(%d)\n", slotid);
dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
cpu_physical_memory_read(dcbaap + 8*slotid, pci_dma_read(&xhci->pci_dev, dcbaap + 8*slotid, &poctx, sizeof(poctx));
(uint8_t *) &poctx, sizeof(poctx));
ictx = xhci_mask64(pictx); ictx = xhci_mask64(pictx);
octx = xhci_mask64(le64_to_cpu(poctx)); octx = xhci_mask64(le64_to_cpu(poctx));
DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx); DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);
DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx); DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx);
cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx)); pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx));
if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) { if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) {
fprintf(stderr, "xhci: invalid input context control %08x %08x\n", fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
@ -1831,8 +1829,8 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
return CC_TRB_ERROR; return CC_TRB_ERROR;
} }
cpu_physical_memory_read(ictx+32, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_read(&xhci->pci_dev, ictx+32, slot_ctx, sizeof(slot_ctx));
cpu_physical_memory_read(ictx+64, (uint8_t *) ep0_ctx, sizeof(ep0_ctx)); pci_dma_read(&xhci->pci_dev, ictx+64, ep0_ctx, sizeof(ep0_ctx));
DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n",
slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
@ -1881,8 +1879,8 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n", DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n",
ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);
cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
cpu_physical_memory_write(octx+32, (uint8_t *) ep0_ctx, sizeof(ep0_ctx)); pci_dma_write(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx));
return res; return res;
} }
@ -1891,7 +1889,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid, static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
uint64_t pictx, bool dc) uint64_t pictx, bool dc)
{ {
target_phys_addr_t ictx, octx; dma_addr_t ictx, octx;
uint32_t ictl_ctx[2]; uint32_t ictl_ctx[2];
uint32_t slot_ctx[4]; uint32_t slot_ctx[4];
uint32_t islot_ctx[4]; uint32_t islot_ctx[4];
@ -1905,8 +1903,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
ictx = xhci_mask64(pictx); ictx = xhci_mask64(pictx);
octx = xhci->slots[slotid-1].ctx; octx = xhci->slots[slotid-1].ctx;
DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx); DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);
DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx); DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx);
if (dc) { if (dc) {
for (i = 2; i <= 31; i++) { for (i = 2; i <= 31; i++) {
@ -1915,17 +1913,17 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
} }
} }
cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT); slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
slot_ctx[3] |= SLOT_ADDRESSED << SLOT_STATE_SHIFT; slot_ctx[3] |= SLOT_ADDRESSED << SLOT_STATE_SHIFT;
DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
return CC_SUCCESS; return CC_SUCCESS;
} }
cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx)); pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx));
if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) { if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) {
fprintf(stderr, "xhci: invalid input context control %08x %08x\n", fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
@ -1933,8 +1931,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
return CC_TRB_ERROR; return CC_TRB_ERROR;
} }
cpu_physical_memory_read(ictx+32, (uint8_t *) islot_ctx, sizeof(islot_ctx)); pci_dma_read(&xhci->pci_dev, ictx+32, islot_ctx, sizeof(islot_ctx));
cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) { if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) {
fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]); fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]);
@ -1946,8 +1944,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
xhci_disable_ep(xhci, slotid, i); xhci_disable_ep(xhci, slotid, i);
} }
if (ictl_ctx[1] & (1<<i)) { if (ictl_ctx[1] & (1<<i)) {
cpu_physical_memory_read(ictx+32+(32*i), pci_dma_read(&xhci->pci_dev, ictx+32+(32*i), ep_ctx,
(uint8_t *) ep_ctx, sizeof(ep_ctx)); sizeof(ep_ctx));
DPRINTF("xhci: input ep%d.%d context: %08x %08x %08x %08x %08x\n", DPRINTF("xhci: input ep%d.%d context: %08x %08x %08x %08x %08x\n",
i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2], i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2],
ep_ctx[3], ep_ctx[4]); ep_ctx[3], ep_ctx[4]);
@ -1959,8 +1957,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci: output ep%d.%d context: %08x %08x %08x %08x %08x\n", DPRINTF("xhci: output ep%d.%d context: %08x %08x %08x %08x %08x\n",
i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2], i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2],
ep_ctx[3], ep_ctx[4]); ep_ctx[3], ep_ctx[4]);
cpu_physical_memory_write(octx+(32*i), pci_dma_write(&xhci->pci_dev, octx+(32*i), ep_ctx, sizeof(ep_ctx));
(uint8_t *) ep_ctx, sizeof(ep_ctx));
} }
} }
@ -1972,7 +1969,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
return CC_SUCCESS; return CC_SUCCESS;
} }
@ -1981,7 +1978,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid, static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
uint64_t pictx) uint64_t pictx)
{ {
target_phys_addr_t ictx, octx; dma_addr_t ictx, octx;
uint32_t ictl_ctx[2]; uint32_t ictl_ctx[2];
uint32_t iep0_ctx[5]; uint32_t iep0_ctx[5];
uint32_t ep0_ctx[5]; uint32_t ep0_ctx[5];
@ -1994,10 +1991,10 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
ictx = xhci_mask64(pictx); ictx = xhci_mask64(pictx);
octx = xhci->slots[slotid-1].ctx; octx = xhci->slots[slotid-1].ctx;
DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx); DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);
DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx); DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx);
cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx)); pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx));
if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) { if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) {
fprintf(stderr, "xhci: invalid input context control %08x %08x\n", fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
@ -2006,13 +2003,12 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
} }
if (ictl_ctx[1] & 0x1) { if (ictl_ctx[1] & 0x1) {
cpu_physical_memory_read(ictx+32, pci_dma_read(&xhci->pci_dev, ictx+32, islot_ctx, sizeof(islot_ctx));
(uint8_t *) islot_ctx, sizeof(islot_ctx));
DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n",
islot_ctx[0], islot_ctx[1], islot_ctx[2], islot_ctx[3]); islot_ctx[0], islot_ctx[1], islot_ctx[2], islot_ctx[3]);
cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
slot_ctx[1] &= ~0xFFFF; /* max exit latency */ slot_ctx[1] &= ~0xFFFF; /* max exit latency */
slot_ctx[1] |= islot_ctx[1] & 0xFFFF; slot_ctx[1] |= islot_ctx[1] & 0xFFFF;
@ -2022,18 +2018,17 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
} }
if (ictl_ctx[1] & 0x2) { if (ictl_ctx[1] & 0x2) {
cpu_physical_memory_read(ictx+64, pci_dma_read(&xhci->pci_dev, ictx+64, iep0_ctx, sizeof(iep0_ctx));
(uint8_t *) iep0_ctx, sizeof(iep0_ctx));
DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n", DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n",
iep0_ctx[0], iep0_ctx[1], iep0_ctx[2], iep0_ctx[0], iep0_ctx[1], iep0_ctx[2],
iep0_ctx[3], iep0_ctx[4]); iep0_ctx[3], iep0_ctx[4]);
cpu_physical_memory_read(octx+32, (uint8_t *) ep0_ctx, sizeof(ep0_ctx)); pci_dma_read(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx));
ep0_ctx[1] &= ~0xFFFF0000; /* max packet size*/ ep0_ctx[1] &= ~0xFFFF0000; /* max packet size*/
ep0_ctx[1] |= iep0_ctx[1] & 0xFFFF0000; ep0_ctx[1] |= iep0_ctx[1] & 0xFFFF0000;
@ -2041,8 +2036,7 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n", DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n",
ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);
cpu_physical_memory_write(octx+32, pci_dma_write(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx));
(uint8_t *) ep0_ctx, sizeof(ep0_ctx));
} }
return CC_SUCCESS; return CC_SUCCESS;
@ -2051,7 +2045,7 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid) static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid)
{ {
uint32_t slot_ctx[4]; uint32_t slot_ctx[4];
target_phys_addr_t octx; dma_addr_t octx;
int i; int i;
assert(slotid >= 1 && slotid <= MAXSLOTS); assert(slotid >= 1 && slotid <= MAXSLOTS);
@ -2059,7 +2053,7 @@ static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid)
octx = xhci->slots[slotid-1].ctx; octx = xhci->slots[slotid-1].ctx;
DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx); DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx);
for (i = 2; i <= 31; i++) { for (i = 2; i <= 31; i++) {
if (xhci->slots[slotid-1].eps[i-1]) { if (xhci->slots[slotid-1].eps[i-1]) {
@ -2067,12 +2061,12 @@ static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid)
} }
} }
cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT); slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
slot_ctx[3] |= SLOT_DEFAULT << SLOT_STATE_SHIFT; slot_ctx[3] |= SLOT_DEFAULT << SLOT_STATE_SHIFT;
DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx)); pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx));
return CC_SUCCESS; return CC_SUCCESS;
} }
@ -2095,19 +2089,19 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr
static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
{ {
target_phys_addr_t ctx; dma_addr_t ctx;
uint8_t bw_ctx[MAXPORTS+1]; uint8_t bw_ctx[MAXPORTS+1];
DPRINTF("xhci_get_port_bandwidth()\n"); DPRINTF("xhci_get_port_bandwidth()\n");
ctx = xhci_mask64(pctx); ctx = xhci_mask64(pctx);
DPRINTF("xhci: bandwidth context at "TARGET_FMT_plx"\n", ctx); DPRINTF("xhci: bandwidth context at "DMA_ADDR_FMT"\n", ctx);
/* TODO: actually implement real values here */ /* TODO: actually implement real values here */
bw_ctx[0] = 0; bw_ctx[0] = 0;
memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */ memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */
cpu_physical_memory_write(ctx, bw_ctx, sizeof(bw_ctx)); pci_dma_write(&xhci->pci_dev, ctx, bw_ctx, sizeof(bw_ctx));
return CC_SUCCESS; return CC_SUCCESS;
} }
@ -2128,13 +2122,13 @@ static uint32_t xhci_nec_challenge(uint32_t hi, uint32_t lo)
return ~val; return ~val;
} }
static void xhci_via_challenge(uint64_t addr) static void xhci_via_challenge(XHCIState *xhci, uint64_t addr)
{ {
uint32_t buf[8]; uint32_t buf[8];
uint32_t obuf[8]; uint32_t obuf[8];
target_phys_addr_t paddr = xhci_mask64(addr); dma_addr_t paddr = xhci_mask64(addr);
cpu_physical_memory_read(paddr, (uint8_t *) &buf, 32); pci_dma_read(&xhci->pci_dev, paddr, &buf, 32);
memcpy(obuf, buf, sizeof(obuf)); memcpy(obuf, buf, sizeof(obuf));
@ -2150,7 +2144,7 @@ static void xhci_via_challenge(uint64_t addr)
obuf[7] = obuf[2] ^ obuf[3] ^ 0x65866593; obuf[7] = obuf[2] ^ obuf[3] ^ 0x65866593;
} }
cpu_physical_memory_write(paddr, (uint8_t *) &obuf, 32); pci_dma_write(&xhci->pci_dev, paddr, &obuf, 32);
} }
static void xhci_process_commands(XHCIState *xhci) static void xhci_process_commands(XHCIState *xhci)
@ -2158,7 +2152,7 @@ static void xhci_process_commands(XHCIState *xhci)
XHCITRB trb; XHCITRB trb;
TRBType type; TRBType type;
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS}; XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
target_phys_addr_t addr; dma_addr_t addr;
unsigned int i, slotid = 0; unsigned int i, slotid = 0;
DPRINTF("xhci_process_commands()\n"); DPRINTF("xhci_process_commands()\n");
@ -2247,7 +2241,7 @@ static void xhci_process_commands(XHCIState *xhci)
event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter); event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter);
break; break;
case CR_VENDOR_VIA_CHALLENGE_RESPONSE: case CR_VENDOR_VIA_CHALLENGE_RESPONSE:
xhci_via_challenge(trb.parameter); xhci_via_challenge(xhci, trb.parameter);
break; break;
case CR_VENDOR_NEC_FIRMWARE_REVISION: case CR_VENDOR_NEC_FIRMWARE_REVISION:
event.type = 48; /* NEC reply */ event.type = 48; /* NEC reply */
@ -2537,7 +2531,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
xhci_event(xhci, &event); xhci_event(xhci, &event);
DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low);
} else { } else {
target_phys_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val);
xhci_ring_init(xhci, &xhci->cmd_ring, base); xhci_ring_init(xhci, &xhci->cmd_ring, base);
} }
xhci->crcr_low &= ~(CRCR_CA | CRCR_CS); xhci->crcr_low &= ~(CRCR_CA | CRCR_CS);

View File

@ -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)
return USB_RET_STALL; return USB_RET_STALL;
} }
} }
} } while (rem > 0);
return USB_RET_ASYNC; return USB_RET_ASYNC;
} }

View File

@ -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)
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)
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)
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,