sim-card
/
qemu
Archived
10
0
Fork 0

usb-ehci: Use PCI DMA stub functions

This updates the usb-ehci device emulation to use the explicit PCI DMA
wrapper to initialize its scatter/gathjer structure.  This means this
driver should not need further changes when the sglist interface is
extended to support IOMMUs.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
David Gibson 2011-10-31 17:06:57 +11:00 committed by Anthony Liguori
parent 552908fef5
commit 68d553587c
1 changed files with 25 additions and 19 deletions

View File

@ -1101,12 +1101,13 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
// TODO : Put in common header file, duplication from usb-ohci.c
/* Get an array of dwords from main memory */
static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
static inline int get_dwords(EHCIState *ehci, uint32_t addr,
uint32_t *buf, int num)
{
int i;
for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
cpu_physical_memory_rw(addr,(uint8_t *)buf, sizeof(*buf), 0);
pci_dma_read(&ehci->dev, addr, (uint8_t *)buf, sizeof(*buf));
*buf = le32_to_cpu(*buf);
}
@ -1114,13 +1115,14 @@ static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
}
/* Put an array of dwords in to main memory */
static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
static inline int put_dwords(EHCIState *ehci, uint32_t addr,
uint32_t *buf, int num)
{
int i;
for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
uint32_t tmp = cpu_to_le32(*buf);
cpu_physical_memory_rw(addr,(uint8_t *)&tmp, sizeof(tmp), 1);
pci_dma_write(&ehci->dev, addr, (uint8_t *)&tmp, sizeof(tmp));
}
return 1;
@ -1169,7 +1171,8 @@ static int ehci_qh_do_overlay(EHCIQueue *q)
q->qh.bufptr[1] &= ~BUFPTR_CPROGMASK_MASK;
q->qh.bufptr[2] &= ~BUFPTR_FRAMETAG_MASK;
put_dwords(NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);
put_dwords(q->ehci, NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh,
sizeof(EHCIqh) >> 2);
return 0;
}
@ -1177,12 +1180,12 @@ static int ehci_qh_do_overlay(EHCIQueue *q)
static int ehci_init_transfer(EHCIQueue *q)
{
uint32_t cpage, offset, bytes, plen;
target_phys_addr_t page;
dma_addr_t page;
cpage = get_field(q->qh.token, QTD_TOKEN_CPAGE);
bytes = get_field(q->qh.token, QTD_TOKEN_TBYTES);
offset = q->qh.bufptr[0] & ~QTD_BUFPTR_MASK;
qemu_sglist_init(&q->sgl, 5);
pci_dma_sglist_init(&q->sgl, &q->ehci->dev, 5);
while (bytes > 0) {
if (cpage > 4) {
@ -1428,7 +1431,7 @@ static int ehci_process_itd(EHCIState *ehci,
return USB_RET_PROCERR;
}
qemu_sglist_init(&ehci->isgl, 2);
pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2);
if (off + len > 4096) {
/* transfer crosses page border */
uint32_t len2 = off + len - 4096;
@ -1532,7 +1535,8 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async)
/* Find the head of the list (4.9.1.1) */
for(i = 0; i < MAX_QH; i++) {
get_dwords(NLPTR_GET(entry), (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh,
sizeof(EHCIqh) >> 2);
ehci_trace_qh(NULL, NLPTR_GET(entry), &qh);
if (qh.epchar & QH_EPCHAR_H) {
@ -1629,7 +1633,8 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
goto out;
}
get_dwords(NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);
get_dwords(ehci, NLPTR_GET(q->qhaddr),
(uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);
ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh);
if (q->async == EHCI_ASYNC_INFLIGHT) {
@ -1698,7 +1703,7 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async)
assert(!async);
entry = ehci_get_fetch_addr(ehci, async);
get_dwords(NLPTR_GET(entry),(uint32_t *) &itd,
get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd,
sizeof(EHCIitd) >> 2);
ehci_trace_itd(ehci, entry, &itd);
@ -1706,8 +1711,8 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async)
return -1;
}
put_dwords(NLPTR_GET(entry), (uint32_t *) &itd,
sizeof(EHCIitd) >> 2);
put_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd,
sizeof(EHCIitd) >> 2);
ehci_set_fetch_addr(ehci, async, itd.next);
ehci_set_state(ehci, async, EST_FETCHENTRY);
@ -1722,7 +1727,7 @@ static int ehci_state_fetchsitd(EHCIState *ehci, int async)
assert(!async);
entry = ehci_get_fetch_addr(ehci, async);
get_dwords(NLPTR_GET(entry), (uint32_t *)&sitd,
get_dwords(ehci, NLPTR_GET(entry), (uint32_t *)&sitd,
sizeof(EHCIsitd) >> 2);
ehci_trace_sitd(ehci, entry, &sitd);
@ -1784,7 +1789,8 @@ static int ehci_state_fetchqtd(EHCIQueue *q, int async)
{
int again = 0;
get_dwords(NLPTR_GET(q->qtdaddr),(uint32_t *) &q->qtd, sizeof(EHCIqtd) >> 2);
get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qtd,
sizeof(EHCIqtd) >> 2);
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &q->qtd);
if (q->qtd.token & QTD_TOKEN_ACTIVE) {
@ -1827,7 +1833,7 @@ static void ehci_flush_qh(EHCIQueue *q)
uint32_t dwords = sizeof(EHCIqh) >> 2;
uint32_t addr = NLPTR_GET(q->qhaddr);
put_dwords(addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3);
put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3);
}
static int ehci_state_execute(EHCIQueue *q, int async)
@ -1947,8 +1953,8 @@ static int ehci_state_writeback(EHCIQueue *q, int async)
/* Write back the QTD from the QH area */
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), (EHCIqtd*) &q->qh.next_qtd);
put_dwords(NLPTR_GET(q->qtdaddr),(uint32_t *) &q->qh.next_qtd,
sizeof(EHCIqtd) >> 2);
put_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qh.next_qtd,
sizeof(EHCIqtd) >> 2);
/*
* EHCI specs say go horizontal here.
@ -2148,7 +2154,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
}
list |= ((ehci->frindex & 0x1ff8) >> 1);
cpu_physical_memory_rw(list, (uint8_t *) &entry, sizeof entry, 0);
pci_dma_read(&ehci->dev, list, (uint8_t *) &entry, sizeof entry);
entry = le32_to_cpu(entry);
DPRINTF("PERIODIC state adv fr=%d. [%08X] -> %08X\n",