ehci: Verify qtd for async completed packets

Remove the short-circuiting of fetchqtd in fetchqh, so that the
qtd gets properly verified before completing the transaction.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Hans de Goede 2012-12-14 14:35:27 +01:00 committed by Gerd Hoffmann
parent 2b3de6ada5
commit e3fdfd488c

View File

@ -1603,7 +1603,6 @@ out:
static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
{ {
uint32_t entry; uint32_t entry;
EHCIPacket *p;
EHCIQueue *q; EHCIQueue *q;
EHCIqh qh; EHCIqh qh;
@ -1612,7 +1611,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
if (NULL == q) { if (NULL == q) {
q = ehci_alloc_queue(ehci, entry, async); q = ehci_alloc_queue(ehci, entry, async);
} }
p = QTAILQ_FIRST(&q->packets);
q->seen++; q->seen++;
if (q->seen > 1) { if (q->seen > 1) {
@ -1637,7 +1635,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
if (ehci_reset_queue(q) > 0) { if (ehci_reset_queue(q) > 0) {
ehci_trace_guest_bug(ehci, "guest updated active QH"); ehci_trace_guest_bug(ehci, "guest updated active QH");
} }
p = NULL;
} }
q->qh = qh; q->qh = qh;
@ -1651,13 +1648,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)); get_field(q->qh.epchar, QH_EPCHAR_DEVADDR));
} }
if (p && p->async == EHCI_ASYNC_FINISHED) {
/* I/O finished -- continue processing queue */
trace_usb_ehci_packet_action(p->queue, p, "complete");
ehci_set_state(ehci, async, EST_EXECUTING);
goto out;
}
if (async && (q->qh.epchar & QH_EPCHAR_H)) { if (async && (q->qh.epchar & QH_EPCHAR_H)) {
/* EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */ /* EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */
@ -1834,10 +1824,7 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
break; break;
case EHCI_ASYNC_FINISHED: case EHCI_ASYNC_FINISHED:
/* /* Complete executing of the packet */
* We get here when advqueue moves to a packet which is already
* finished, which can happen with packets queued up by fill_queue
*/
ehci_set_state(q->ehci, q->async, EST_EXECUTING); ehci_set_state(q->ehci, q->async, EST_EXECUTING);
break; break;
} }