mirror of https://gitee.com/openkylin/qemu.git
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:
parent
552908fef5
commit
68d553587c
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue