qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 6/8] usb/combined-packet: Move freeing of combined t


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 6/8] usb/combined-packet: Move freeing of combined to usb_combined_packet_remove()
Date: Fri, 9 Nov 2012 10:05:49 +0100

From: Hans de Goede <address@hidden>

Signed-off-by: Hans de Goede <address@hidden>
Signed-off-by: Gerd Hoffmann <address@hidden>
---
 hw/usb/combined-packet.c |   33 +++++++++++++++------------------
 1 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/hw/usb/combined-packet.c b/hw/usb/combined-packet.c
index e722198..4a0c299 100644
--- a/hw/usb/combined-packet.c
+++ b/hw/usb/combined-packet.c
@@ -31,12 +31,16 @@ static void usb_combined_packet_add(USBCombinedPacket 
*combined, USBPacket *p)
     p->combined = combined;
 }
 
+/* Note will free combined when the last packet gets removed */
 static void usb_combined_packet_remove(USBCombinedPacket *combined,
                                        USBPacket *p)
 {
     assert(p->combined == combined);
     p->combined = NULL;
     QTAILQ_REMOVE(&combined->packets, p, combined_entry);
+    if (QTAILQ_EMPTY(&combined->packets)) {
+        g_free(combined);
+    }
 }
 
 /* Also handles completion of non combined packets for pipelined input eps */
@@ -45,9 +49,8 @@ void usb_combined_input_packet_complete(USBDevice *dev, 
USBPacket *p)
     USBCombinedPacket *combined = p->combined;
     USBEndpoint *ep = p->ep;
     USBPacket *next;
-    enum { completing, complete, leftover };
-    int status, actual_length, state = completing;
-    bool short_not_ok;
+    int status, actual_length;
+    bool short_not_ok, done = false;
 
     if (combined == NULL) {
         usb_packet_complete_one(dev, p);
@@ -61,39 +64,34 @@ void usb_combined_input_packet_complete(USBDevice *dev, 
USBPacket *p)
     short_not_ok = QTAILQ_LAST(&combined->packets, packets_head)->short_not_ok;
 
     QTAILQ_FOREACH_SAFE(p, &combined->packets, combined_entry, next) {
-        if (state == completing) {
+        if (!done) {
             /* Distribute data over uncombined packets */
             if (actual_length >= p->iov.size) {
                 p->actual_length = p->iov.size;
             } else {
                 /* Send short or error packet to complete the transfer */
                 p->actual_length = actual_length;
-                state = complete;
+                done = true;
             }
             /* Report status on the last packet */
-            if (state == complete || next == NULL) {
+            if (done || next == NULL) {
                 p->status = status;
             } else {
                 p->status = USB_RET_SUCCESS;
             }
             p->short_not_ok = short_not_ok;
+            /* Note will free combined when the last packet gets removed! */
             usb_combined_packet_remove(combined, p);
             usb_packet_complete_one(dev, p);
             actual_length -= p->actual_length;
         } else {
             /* Remove any leftover packets from the queue */
-            state = leftover;
             p->status = USB_RET_REMOVE_FROM_QUEUE;
+            /* Note will free combined on the last packet! */
             dev->port->ops->complete(dev->port, p);
         }
     }
-    /*
-     * If we had leftover packets the hcd driver will have cancelled them
-     * and usb_combined_packet_cancel has already freed combined!
-     */
-    if (state != leftover) {
-        g_free(combined);
-    }
+    /* Do not use combined here, it has been freed! */
 leave:
     /* Check if there are packets in the queue waiting for our completion */
     usb_ep_combine_input_packets(ep);
@@ -104,14 +102,13 @@ void usb_combined_packet_cancel(USBDevice *dev, USBPacket 
*p)
 {
     USBCombinedPacket *combined = p->combined;
     assert(combined != NULL);
+    USBPacket *first = p->combined->first;
 
+    /* Note will free combined on the last packet! */
     usb_combined_packet_remove(combined, p);
-    if (p == combined->first) {
+    if (p == first) {
         usb_device_cancel_packet(dev, p);
     }
-    if (QTAILQ_EMPTY(&combined->packets)) {
-        g_free(combined);
-    }
 }
 
 /*
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]