diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-08-23 13:30:13 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2012-08-31 11:57:23 +0200 |
commit | e983395d30d1d5bfa0ed3ae9c028c130f7c498cc (patch) | |
tree | 6377ecd839a30655f4a78eee1db5aec531804da7 /hw/usb | |
parent | 0132b4b6595423c92f54d7e0b172b5d73aaa8375 (diff) | |
download | hqemu-e983395d30d1d5bfa0ed3ae9c028c130f7c498cc.zip hqemu-e983395d30d1d5bfa0ed3ae9c028c130f7c498cc.tar.gz |
usb: unique packet ids
This patch adds IDs to usb packets. Those IDs are (a) supposed to be
unique for the lifecycle of a packet (from packet setup until the packet
is either completed or canceled) and (b) stable across migration.
uhci, ohci, ehci and xhci use the guest physical address of the transfer
descriptor for this.
musb needs a different approach because there is no transfer descriptor.
But musb also doesn't support pipelining, so we have never more than one
packet per endpoint in flight. So we go create an ID based on endpoint
and device address.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/core.c | 3 | ||||
-rw-r--r-- | hw/usb/hcd-ehci.c | 9 | ||||
-rw-r--r-- | hw/usb/hcd-musb.c | 3 | ||||
-rw-r--r-- | hw/usb/hcd-ohci.c | 4 | ||||
-rw-r--r-- | hw/usb/hcd-uhci.c | 4 | ||||
-rw-r--r-- | hw/usb/hcd-xhci.c | 2 |
6 files changed, 14 insertions, 11 deletions
diff --git a/hw/usb/core.c b/hw/usb/core.c index 28b840e..2da38e7 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -520,10 +520,11 @@ void usb_packet_set_state(USBPacket *p, USBPacketState state) p->state = state; } -void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep) +void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id) { assert(!usb_packet_is_inflight(p)); assert(p->iov.iov != NULL); + p->id = id; p->pid = pid; p->ep = ep; p->result = 0; diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 8504a6a..f43d690 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1530,7 +1530,7 @@ static int ehci_execute(EHCIPacket *p, const char *action) endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP); ep = usb_ep_get(p->queue->dev, p->pid, endp); - usb_packet_setup(&p->packet, p->pid, ep); + usb_packet_setup(&p->packet, p->pid, ep, p->qtdaddr); usb_packet_map(&p->packet, &p->sgl); trace_usb_ehci_packet_action(p->queue, p, action); @@ -1552,7 +1552,8 @@ static int ehci_execute(EHCIPacket *p, const char *action) */ static int ehci_process_itd(EHCIState *ehci, - EHCIitd *itd) + EHCIitd *itd, + uint32_t addr) { USBDevice *dev; USBEndpoint *ep; @@ -1598,7 +1599,7 @@ static int ehci_process_itd(EHCIState *ehci, dev = ehci_find_device(ehci, devaddr); ep = usb_ep_get(dev, pid, endp); if (ep->type == USB_ENDPOINT_XFER_ISOC) { - usb_packet_setup(&ehci->ipacket, pid, ep); + usb_packet_setup(&ehci->ipacket, pid, ep, addr); usb_packet_map(&ehci->ipacket, &ehci->isgl); ret = usb_handle_packet(dev, &ehci->ipacket); assert(ret != USB_RET_ASYNC); @@ -1862,7 +1863,7 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async) sizeof(EHCIitd) >> 2); ehci_trace_itd(ehci, entry, &itd); - if (ehci_process_itd(ehci, &itd) != 0) { + if (ehci_process_itd(ehci, &itd, entry) != 0) { return -1; } diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c index fa9385e..0bb5c7b 100644 --- a/hw/usb/hcd-musb.c +++ b/hw/usb/hcd-musb.c @@ -626,7 +626,8 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep, /* A wild guess on the FADDR semantics... */ dev = usb_find_device(&s->port, ep->faddr[idx]); uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf); - usb_packet_setup(&ep->packey[dir].p, pid, uep); + usb_packet_setup(&ep->packey[dir].p, pid, uep, + (dev->addr << 16) | (uep->nr << 8) | pid); usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len); ep->packey[dir].ep = ep; ep->packey[dir].dir = dir; diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 844e7ed..c36184a 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -812,7 +812,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, } else { dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); - usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_setup(&ohci->usb_packet, pid, ep, addr); usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); ret = usb_handle_packet(dev, &ohci->usb_packet); if (ret == USB_RET_ASYNC) { @@ -1011,7 +1011,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) } dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); - usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_setup(&ohci->usb_packet, pid, ep, addr); usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); ret = usb_handle_packet(dev, &ohci->usb_packet); #ifdef DEBUG_PACKET diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 8987734..b0db921 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -859,14 +859,14 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, * for initial isochronous requests */ async->queue->valid = 32; - async->isoc = td->ctrl & TD_CTRL_IOS; + async->isoc = td->ctrl & TD_CTRL_IOS; max_len = ((td->token >> 21) + 1) & 0x7ff; pid = td->token & 0xff; dev = uhci_find_device(s, (td->token >> 8) & 0x7f); ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf); - usb_packet_setup(&async->packet, pid, ep); + usb_packet_setup(&async->packet, pid, ep, addr); qemu_sglist_add(&async->sgl, td->buffer, max_len); usb_packet_map(&async->packet, &async->sgl); diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 6c2ff02..3eb27fa 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1392,7 +1392,7 @@ static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; ep = usb_ep_get(dev, dir, xfer->epid >> 1); - usb_packet_setup(&xfer->packet, dir, ep); + usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr); usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length); DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", xfer->packet.pid, dev->addr, ep->nr); |