]> Git Repo - qemu.git/commitdiff
usb: unique packet ids
authorGerd Hoffmann <[email protected]>
Thu, 23 Aug 2012 11:30:13 +0000 (13:30 +0200)
committerGerd Hoffmann <[email protected]>
Fri, 31 Aug 2012 09:57:23 +0000 (11:57 +0200)
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 <[email protected]>
hw/usb.h
hw/usb/core.c
hw/usb/hcd-ehci.c
hw/usb/hcd-musb.c
hw/usb/hcd-ohci.c
hw/usb/hcd-uhci.c
hw/usb/hcd-xhci.c

index e5744773bd6c6938d0caa820c11abf36bef4286e..b8fceec8951446ab8543ad9433c7f1b0f5057c91 100644 (file)
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -332,6 +332,7 @@ typedef enum USBPacketState {
 struct USBPacket {
     /* Data fields for use by the driver.  */
     int pid;
+    uint64_t id;
     USBEndpoint *ep;
     QEMUIOVector iov;
     uint64_t parameter; /* control transfers */
@@ -344,7 +345,7 @@ struct USBPacket {
 void usb_packet_init(USBPacket *p);
 void usb_packet_set_state(USBPacket *p, USBPacketState state);
 void usb_packet_check_state(USBPacket *p, USBPacketState expected);
-void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep);
+void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id);
 void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
 int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
 void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
index 28b840e52d3939f02d33440ea810a4f411f9f006..2da38e7fd024d6c3ebd2de0891333098164b70b0 100644 (file)
@@ -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;
index 8504a6a6b081e5e9c2717c5142de581171810266..f43d690eb54a50032639883f214d8fa22e1c81b2 100644 (file)
@@ -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;
     }
 
index fa9385ee49d52126261e6d95ea07a75b888a5048..0bb5c7b19e88656fb1c1e7e7560e45d0f3a06929 100644 (file)
@@ -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;
index 844e7ed1669b6f2cccd8b0981cd5efae044bf103..c36184ae4fe57e33915ea19939cc571f019b488a 100644 (file)
@@ -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
index 898773414ecc7133befc36c5cab6322fee2e4bed..b0db92145a51e085173a543c43d10da536c9c190 100644 (file)
@@ -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);
 
index 6c2ff024e0af2159d68382e0448fe055de27c431..3eb27fadb88b778049b4626be6a15b5d4560b423 100644 (file)
@@ -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);
This page took 0.033639 seconds and 4 git commands to generate.