mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 20:03:37 +08:00
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:
parent
2b3de6ada5
commit
e3fdfd488c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user