@@ -443,8 +443,10 @@ static bool ehci_verify_qh(EHCIQueue *q, EHCIqh *qh)
uint32_t endp = get_field(qh->epchar, QH_EPCHAR_EP);
if ((devaddr != get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)) ||
(endp != get_field(q->qh.epchar, QH_EPCHAR_EP)) ||
- (memcmp(&qh->current_qtd, &q->qh.current_qtd,
- 9 * sizeof(uint32_t)) != 0) ||
+ (qh->current_qtd != q->qh.current_qtd) ||
+ (q->async && qh->next_qtd != q->qh.next_qtd) ||
+ (memcmp(&qh->altnext_qtd, &q->qh.altnext_qtd,
+ 7 * sizeof(uint32_t)) != 0) ||
(q->dev != NULL && q->dev->addr != devaddr)) {
return false;
} else {
@@ -455,7 +457,8 @@ static bool ehci_verify_qh(EHCIQueue *q, EHCIqh *qh)
static bool ehci_verify_qtd(EHCIPacket *p, EHCIqtd *qtd)
{
if (p->qtdaddr != p->queue->qtdaddr ||
- (!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd->next)) ||
+ (p->queue->async && !NLPTR_TBIT(p->qtd.next) &&
+ (p->qtd.next != qtd->next)) ||
(!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd->altnext)) ||
p->qtd.token != qtd->token ||
p->qtd.bufptr[0] != qtd->bufptr[0]) {
Windows-XP likes to play tricks with the next pointer for periodic qh-s, so far we were not hit by this as we never called fill_queue for periodic qh-s, but with the move to async packet handling for interrupt endpoints this becomes an issue. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- hw/usb/hcd-ehci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)