Loading hw/usb/combined-packet.c +15 −18 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading @@ -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); Loading @@ -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); } } /* Loading Loading
hw/usb/combined-packet.c +15 −18 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading @@ -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); Loading @@ -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); } } /* Loading