Revision e8ee3c72

b/hw/usb-uhci.c
265 265
static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token)
266 266
{
267 267
    UHCIAsync *async = s->async_pending;
268
    UHCIAsync *match = NULL;
269
    int count = 0;
270

  
271
    /*
272
     * We're looking for the best match here. ie both td addr and token.
273
     * Otherwise we return last good match. ie just token.
274
     * It's ok to match just token because it identifies the transaction
275
     * rather well, token includes: device addr, endpoint, size, etc.
276
     *
277
     * Also since we queue async transactions in reverse order by returning
278
     * last good match we restores the order.
279
     *
280
     * It's expected that we wont have a ton of outstanding transactions.
281
     * If we ever do we'd want to optimize this algorithm.
282
     */
268 283

  
269 284
    while (async) {
270
        if (async->td == addr) {
271
            if (async->token == token)
272
                return async;
273

  
274
            /*
275
             * TD was reused for a different transfer.
276
             * Invalidate the original one asap.
277
             */
278
            if (async->valid > 0) {
279
                async->valid = 0;
280
                dprintf("husb: bad reuse. td 0x%x\n", async->td);
285
        if (async->token == token) {
286
            /* Good match */
287
            match = async;
288

  
289
            if (async->td == addr) {
290
                /* Best match */
291
                break;
281 292
            }
282 293
        }
283 294

  
284 295
        async = async->next;
296
        count++;
285 297
    }
286
    return NULL;
298

  
299
    if (count > 64)
300
	fprintf(stderr, "uhci: warning lots of async transactions\n");
301

  
302
    return match;
287 303
}
288 304

  
289 305
static void uhci_attach(USBPort *port1, USBDevice *dev);

Also available in: Unified diff