Revision 54f254f9 hw/usb-uhci.c

b/hw/usb-uhci.c
3 3
 *
4 4
 * Copyright (c) 2005 Fabrice Bellard
5 5
 *
6
 * Copyright (c) 2008 Max Krasnyansky
7
 *     Magor rewrite of the UHCI data structures parser and frame processor
8
 *     Support for fully async operation and multiple outstanding transactions
9
 *
6 10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 11
 * of this software and associated documentation files (the "Software"), to deal
8 12
 * in the Software without restriction, including without limitation the rights
......
27 31
#include "qemu-timer.h"
28 32

  
29 33
//#define DEBUG
30
//#define DEBUG_PACKET
31
//#define DEBUG_ISOCH
34
//#define DEBUG_DUMP_DATA
32 35

  
33 36
#define UHCI_CMD_FGR      (1 << 4)
34 37
#define UHCI_CMD_EGSM     (1 << 3)
......
66 69

  
67 70
#define NB_PORTS 2
68 71

  
72
#ifdef DEBUG
73
#define dprintf printf
74

  
75
const char *pid2str(int pid)
76
{
77
    switch (pid) {
78
    case USB_TOKEN_SETUP: return "SETUP";
79
    case USB_TOKEN_IN:    return "IN";
80
    case USB_TOKEN_OUT:   return "OUT";
81
    }
82
    return "?";
83
}
84

  
85
#else
86
#define dprintf(...)
87
#endif
88

  
89
#ifdef DEBUG_DUMP_DATA
90
static void dump_data(const uint8_t *data, int len)
91
{
92
    int i;
93

  
94
    printf("uhci: data: ");
95
    for(i = 0; i < len; i++)
96
        printf(" %02x", data[i]);
97
    printf("\n");
98
}
99
#else
100
static void dump_data(const uint8_t *data, int len) {}
101
#endif
102

  
103
/* 
104
 * Pending async transaction.
105
 * 'packet' must be the first field because completion
106
 * handler does "(UHCIAsync *) pkt" cast.
107
 */
108
typedef struct UHCIAsync {
109
    USBPacket packet;
110
    struct UHCIAsync *next;
111
    uint32_t  td;
112
    uint32_t  token;
113
    int8_t    valid;
114
    uint8_t   done;
115
    uint8_t   buffer[2048];
116
} UHCIAsync;
117

  
69 118
typedef struct UHCIPort {
70 119
    USBPort port;
71 120
    uint16_t ctrl;
......
85 134

  
86 135
    /* Interrupts that should be raised at the end of the current frame.  */
87 136
    uint32_t pending_int_mask;
88
    /* For simplicity of implementation we only allow a single pending USB
89
       request.  This means all usb traffic on this controller is effectively
90
       suspended until that transfer completes.  When the transfer completes
91
       the next transfer from that queue will be processed.  However
92
       other queues will not be processed until the next frame.  The solution
93
       is to allow multiple pending requests.  */
94
    uint32_t async_qh;
95
    uint32_t async_frame_addr;
96
    USBPacket usb_packet;
97
    uint8_t usb_buf[2048];
137

  
138
    /* Active packets */
139
    UHCIAsync *async_pending;
140
    UHCIAsync *async_pool;
98 141
} UHCIState;
99 142

  
100 143
typedef struct UHCI_TD {
......
109 152
    uint32_t el_link;
110 153
} UHCI_QH;
111 154

  
155
static UHCIAsync *uhci_async_alloc(UHCIState *s)
156
{
157
    UHCIAsync *async = qemu_malloc(sizeof(UHCIAsync));
158
    if (async) {
159
        memset(&async->packet, 0, sizeof(async->packet));
160
        async->valid = 0;
161
        async->td    = 0;
162
        async->token = 0;
163
        async->done  = 0;
164
        async->next  = NULL;
165
    }
166

  
167
    return async;
168
}
169

  
170
static void uhci_async_free(UHCIState *s, UHCIAsync *async)
171
{
172
    qemu_free(async);
173
}
174

  
175
static void uhci_async_link(UHCIState *s, UHCIAsync *async)
176
{
177
    async->next = s->async_pending;
178
    s->async_pending = async;
179
}
180

  
181
static void uhci_async_unlink(UHCIState *s, UHCIAsync *async)
182
{
183
    UHCIAsync *curr = s->async_pending;
184
    UHCIAsync **prev = &s->async_pending;
185

  
186
    while (curr) {
187
	if (curr == async) {
188
            *prev = curr->next;
189
            return;
190
        }
191

  
192
        prev = &curr->next;
193
        curr = curr->next;
194
    }
195
}
196

  
197
static void uhci_async_cancel(UHCIState *s, UHCIAsync *async)
198
{
199
    dprintf("uhci: cancel td 0x%x token 0x%x done %u\n",
200
           async->td, async->token, async->done);
201

  
202
    if (!async->done)
203
        usb_cancel_packet(&async->packet);
204
    uhci_async_free(s, async);
205
}
206

  
207
/*
208
 * Mark all outstanding async packets as invalid.
209
 * This is used for canceling them when TDs are removed by the HCD.
210
 */
211
static UHCIAsync *uhci_async_validate_begin(UHCIState *s)
212
{
213
    UHCIAsync *async = s->async_pending;
214

  
215
    while (async) {
216
        async->valid--;
217
        async = async->next;
218
    }
219
    return NULL;
220
}
221

  
222
/*
223
 * Cancel async packets that are no longer valid
224
 */
225
static void uhci_async_validate_end(UHCIState *s)
226
{
227
    UHCIAsync *curr = s->async_pending;
228
    UHCIAsync **prev = &s->async_pending;
229
    UHCIAsync *next;
230

  
231
    while (curr) {
232
        if (curr->valid > 0) {
233
            prev = &curr->next;
234
            curr = curr->next;
235
            continue;
236
        }
237

  
238
        next = curr->next;
239

  
240
        /* Unlink */
241
        *prev = next;
242

  
243
        uhci_async_cancel(s, curr);
244

  
245
        curr = next;
246
    }
247
}
248

  
249
static void uhci_async_cancel_all(UHCIState *s)
250
{
251
    UHCIAsync *curr = s->async_pending;
252
    UHCIAsync *next;
253

  
254
    while (curr) {
255
        next = curr->next;
256

  
257
        uhci_async_cancel(s, curr);
258

  
259
        curr = next;
260
    }
261

  
262
    s->async_pending = NULL;
263
}
264

  
265
static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token)
266
{
267
    UHCIAsync *async = s->async_pending;
268

  
269
    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);
281
            }
282
        }
283

  
284
        async = async->next;
285
    }
286
    return NULL;
287
}
288

  
112 289
static void uhci_attach(USBPort *port1, USBDevice *dev);
113 290

  
114 291
static void uhci_update_irq(UHCIState *s)
......
143 320
    s->intr = 0;
144 321
    s->fl_base_addr = 0;
145 322
    s->sof_timing = 64;
323

  
146 324
    for(i = 0; i < NB_PORTS; i++) {
147 325
        port = &s->ports[i];
148 326
        port->ctrl = 0x0080;
149 327
        if (port->port.dev)
150 328
            uhci_attach(&port->port, port->port.dev);
151 329
    }
330

  
331
    uhci_async_cancel_all(s);
152 332
}
153 333

  
154
#if 0
334
#if 1
155 335
static void uhci_save(QEMUFile *f, void *opaque)
156 336
{
157 337
    UHCIState *s = opaque;
......
239 419
    UHCIState *s = opaque;
240 420

  
241 421
    addr &= 0x1f;
242
#ifdef DEBUG
243
    printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
244
#endif
422
    dprintf("uhci: writew port=0x%04x val=0x%04x\n", addr, val);
423

  
245 424
    switch(addr) {
246 425
    case 0x00:
247 426
        if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
......
350 529
        val = 0xff7f; /* disabled port */
351 530
        break;
352 531
    }
353
#ifdef DEBUG
354
    printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
355
#endif
532

  
533
    dprintf("uhci: readw port=0x%04x val=0x%04x\n", addr, val);
534

  
356 535
    return val;
357 536
}
358 537

  
......
361 540
    UHCIState *s = opaque;
362 541

  
363 542
    addr &= 0x1f;
364
#ifdef DEBUG
365
    printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
366
#endif
543
    dprintf("uhci: writel port=0x%04x val=0x%08x\n", addr, val);
544

  
367 545
    switch(addr) {
368 546
    case 0x08:
369 547
        s->fl_base_addr = val & ~0xfff;
......
451 629

  
452 630
static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
453 631
{
454
    UHCIPort *port;
455
    USBDevice *dev;
456 632
    int i, ret;
457 633

  
458
#ifdef DEBUG_PACKET
459
    {
460
        const char *pidstr;
461
        switch(p->pid) {
462
        case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
463
        case USB_TOKEN_IN: pidstr = "IN"; break;
464
        case USB_TOKEN_OUT: pidstr = "OUT"; break;
465
        default: pidstr = "?"; break;
466
        }
467
        printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
468
               s->frnum, pidstr, p->devaddr, p->devep, p->len);
469
        if (p->pid != USB_TOKEN_IN) {
470
            printf("     data_out=");
471
            for(i = 0; i < p->len; i++) {
472
                printf(" %02x", p->data[i]);
473
            }
474
            printf("\n");
475
        }
476
    }
477
#endif
478
    for(i = 0; i < NB_PORTS; i++) {
479
        port = &s->ports[i];
480
        dev = port->port.dev;
481
        if (dev && (port->ctrl & UHCI_PORT_EN)) {
634
    dprintf("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n",
635
           pid2str(p->pid), p->devaddr, p->devep, p->len);
636
    if (p->pid == USB_TOKEN_OUT)
637
        dump_data(p->data, p->len);
638

  
639
    ret = USB_RET_NODEV;
640
    for (i = 0; i < NB_PORTS && ret == USB_RET_NODEV; i++) {
641
        UHCIPort *port = &s->ports[i];
642
        USBDevice *dev = port->port.dev;
643

  
644
        if (dev && (port->ctrl & UHCI_PORT_EN))
482 645
            ret = dev->handle_packet(dev, p);
483
            if (ret != USB_RET_NODEV) {
484
#ifdef DEBUG_PACKET
485
                if (ret == USB_RET_ASYNC) {
486
                    printf("usb-uhci: Async packet\n");
487
                } else {
488
                    printf("     ret=%d ", ret);
489
                    if (p->pid == USB_TOKEN_IN && ret > 0) {
490
                        printf("data_in=");
491
                        for(i = 0; i < ret; i++) {
492
                            printf(" %02x", p->data[i]);
493
                        }
494
                    }
495
                    printf("\n");
496
                }
497
#endif
498
                return ret;
499
            }
500
        }
501 646
    }
502
    return USB_RET_NODEV;
647

  
648
    dprintf("uhci: packet exit. ret %d len %d\n", ret, p->len);
649
    if (p->pid == USB_TOKEN_IN && ret > 0)
650
        dump_data(p->data, ret);
651

  
652
    return ret;
503 653
}
504 654

  
505
static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
655
static void uhci_async_complete(USBPacket * packet, void *opaque);
656
static void uhci_process_frame(UHCIState *s);
506 657

  
507 658
/* return -1 if fatal error (frame must be stopped)
508 659
          0 if TD successful
509 660
          1 if TD unsuccessful or inactive
510 661
*/
511
static int uhci_handle_td(UHCIState *s, UHCI_TD *td, uint32_t *int_mask,
512
                          int completion)
662
static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
513 663
{
664
    int len = 0, max_len, err, ret;
514 665
    uint8_t pid;
515
    int len = 0, max_len, err, ret = 0;
516 666

  
517
    /* ??? This is wrong for async completion.  */
518
    if (td->ctrl & TD_CTRL_IOC) {
667
    max_len = ((td->token >> 21) + 1) & 0x7ff;
668
    pid = td->token & 0xff;
669

  
670
    ret = async->packet.len;
671

  
672
    if (td->ctrl & TD_CTRL_IOC)
519 673
        *int_mask |= 0x01;
520
    }
521 674

  
522
    if (!(td->ctrl & TD_CTRL_ACTIVE))
523
        return 1;
675
    if (td->ctrl & TD_CTRL_IOS)
676
        td->ctrl &= ~TD_CTRL_ACTIVE;
524 677

  
525
    /* TD is active */
526
    max_len = ((td->token >> 21) + 1) & 0x7ff;
527
    pid = td->token & 0xff;
678
    if (ret < 0)
679
        goto out;
528 680

  
529
    if (completion && (s->async_qh || s->async_frame_addr)) {
530
        ret = s->usb_packet.len;
531
        if (ret >= 0) {
532
            len = ret;
533
            if (len > max_len) {
534
                len = max_len;
535
                ret = USB_RET_BABBLE;
536
            }
537
            if (len > 0) {
538
                /* write the data back */
539
                cpu_physical_memory_write(td->buffer, s->usb_buf, len);
540
            }
541
        } else {
542
            len = 0;
543
        }
544
        s->async_qh = 0;
545
        s->async_frame_addr = 0;
546
    } else if (!completion) {
547
        s->usb_packet.pid = pid;
548
        s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
549
        s->usb_packet.devep = (td->token >> 15) & 0xf;
550
        s->usb_packet.data = s->usb_buf;
551
        s->usb_packet.len = max_len;
552
        s->usb_packet.complete_cb = uhci_async_complete_packet;
553
        s->usb_packet.complete_opaque = s;
554
        switch(pid) {
555
        case USB_TOKEN_OUT:
556
        case USB_TOKEN_SETUP:
557
            cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
558
            ret = uhci_broadcast_packet(s, &s->usb_packet);
681
    len = async->packet.len;
682
    td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
683

  
684
    /* The NAK bit may have been set by a previous frame, so clear it
685
       here.  The docs are somewhat unclear, but win2k relies on this
686
       behavior.  */
687
    td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
688

  
689
    if (pid == USB_TOKEN_IN) {
690
        if (len > max_len) {
559 691
            len = max_len;
560
            break;
561
        case USB_TOKEN_IN:
562
            ret = uhci_broadcast_packet(s, &s->usb_packet);
563
            if (ret >= 0) {
564
                len = ret;
565
                if (len > max_len) {
566
                    len = max_len;
567
                    ret = USB_RET_BABBLE;
568
                }
569
                if (len > 0) {
570
                    /* write the data back */
571
                    cpu_physical_memory_write(td->buffer, s->usb_buf, len);
572
                }
573
            } else {
574
                len = 0;
575
            }
576
            break;
577
        default:
578
            /* invalid pid : frame interrupted */
579
            s->status |= UHCI_STS_HCPERR;
580
            uhci_update_irq(s);
581
            return -1;
692
            ret = USB_RET_BABBLE;
693
            goto out;
582 694
        }
583
    }
584 695

  
585
    if (ret == USB_RET_ASYNC) {
586
        return 2;
587
    }
588
    if (td->ctrl & TD_CTRL_IOS)
589
        td->ctrl &= ~TD_CTRL_ACTIVE;
590
    if (ret >= 0) {
591
        td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
592
        /* The NAK bit may have been set by a previous frame, so clear it
593
           here.  The docs are somewhat unclear, but win2k relies on this
594
           behavior.  */
595
        td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
596
        if (pid == USB_TOKEN_IN &&
597
            (td->ctrl & TD_CTRL_SPD) &&
598
            len < max_len) {
696
        if (len > 0) {
697
            /* write the data back */
698
            cpu_physical_memory_write(td->buffer, async->buffer, len);
699
        }
700

  
701
        if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
599 702
            *int_mask |= 0x02;
600 703
            /* short packet: do not update QH */
704
            dprintf("uhci: short packet. td 0x%x token 0x%x\n", async->td, async->token);
601 705
            return 1;
602
        } else {
603
            /* success */
604
            return 0;
605 706
        }
606
    } else {
607
        switch(ret) {
608
        default:
609
        case USB_RET_NODEV:
610
        do_timeout:
611
            td->ctrl |= TD_CTRL_TIMEOUT;
612
            err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
613
            if (err != 0) {
614
                err--;
615
                if (err == 0) {
616
                    td->ctrl &= ~TD_CTRL_ACTIVE;
617
                    s->status |= UHCI_STS_USBERR;
618
                    uhci_update_irq(s);
619
                }
620
            }
621
            td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
622
                (err << TD_CTRL_ERROR_SHIFT);
623
            return 1;
624
        case USB_RET_NAK:
625
            td->ctrl |= TD_CTRL_NAK;
626
            if (pid == USB_TOKEN_SETUP)
627
                goto do_timeout;
628
            return 1;
629
        case USB_RET_STALL:
630
            td->ctrl |= TD_CTRL_STALL;
631
            td->ctrl &= ~TD_CTRL_ACTIVE;
632
            return 1;
633
        case USB_RET_BABBLE:
634
            td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
707
    }
708

  
709
    /* success */
710
    return 0;
711

  
712
out:
713
    switch(ret) {
714
    case USB_RET_STALL:
715
        td->ctrl |= TD_CTRL_STALL;
716
        td->ctrl &= ~TD_CTRL_ACTIVE;
717
        return 1;
718

  
719
    case USB_RET_BABBLE:
720
        td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
721
        td->ctrl &= ~TD_CTRL_ACTIVE;
722
        /* frame interrupted */
723
        return -1;
724

  
725
    case USB_RET_NAK:
726
        td->ctrl |= TD_CTRL_NAK;
727
        if (pid == USB_TOKEN_SETUP)
728
            break;
729
	return 1;
730

  
731
    case USB_RET_NODEV:
732
    default:
733
	break;
734
    }
735

  
736
    /* Retry the TD if error count is not zero */
737

  
738
    td->ctrl |= TD_CTRL_TIMEOUT;
739
    err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
740
    if (err != 0) {
741
        err--;
742
        if (err == 0) {
635 743
            td->ctrl &= ~TD_CTRL_ACTIVE;
636
            /* frame interrupted */
637
            return -1;
744
            s->status |= UHCI_STS_USBERR;
745
            uhci_update_irq(s);
638 746
        }
639 747
    }
748
    td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
749
        (err << TD_CTRL_ERROR_SHIFT);
750
    return 1;
640 751
}
641 752

  
642
static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
753
static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
754
{
755
    UHCIAsync *async;
756
    int len = 0, max_len, ret = 0;
757
    uint8_t pid;
758

  
759
    /* Is active ? */
760
    if (!(td->ctrl & TD_CTRL_ACTIVE))
761
        return 1;
762

  
763
    async = uhci_async_find_td(s, addr, td->token);
764
    if (async) {
765
        /* Already submitted */
766
        async->valid = 10;
767

  
768
        if (!async->done)
769
            return 1;
770

  
771
        uhci_async_unlink(s, async);
772
        goto done;
773
    }
774

  
775
    /* Allocate new packet */
776
    async = uhci_async_alloc(s);
777
    if (!async)
778
        return 1;
779

  
780
    async->valid = 10;
781
    async->td    = addr;
782
    async->token = td->token;
783

  
784
    max_len = ((td->token >> 21) + 1) & 0x7ff;
785
    pid = td->token & 0xff;
786

  
787
    async->packet.pid     = pid;
788
    async->packet.devaddr = (td->token >> 8) & 0x7f;
789
    async->packet.devep   = (td->token >> 15) & 0xf;
790
    async->packet.data    = async->buffer;
791
    async->packet.len     = max_len;
792
    async->packet.complete_cb     = uhci_async_complete;
793
    async->packet.complete_opaque = s;
794

  
795
    switch(pid) {
796
    case USB_TOKEN_OUT:
797
    case USB_TOKEN_SETUP:
798
        cpu_physical_memory_read(td->buffer, async->buffer, max_len);
799
        ret = uhci_broadcast_packet(s, &async->packet);
800
        len = max_len;
801
        break;
802

  
803
    case USB_TOKEN_IN:
804
        ret = uhci_broadcast_packet(s, &async->packet);
805
        break;
806

  
807
    default:
808
        /* invalid pid : frame interrupted */
809
        uhci_async_free(s, async);
810
        s->status |= UHCI_STS_HCPERR;
811
        uhci_update_irq(s);
812
        return -1;
813
    }
814
 
815
    if (ret == USB_RET_ASYNC) {
816
        uhci_async_link(s, async);
817
        return 2;
818
    }
819

  
820
    async->packet.len = ret;
821

  
822
done:
823
    ret = uhci_complete_td(s, td, async, int_mask);
824
    uhci_async_free(s, async);
825
    return ret;
826
}
827

  
828
static void uhci_async_complete(USBPacket *packet, void *opaque)
643 829
{
644 830
    UHCIState *s = opaque;
645
    UHCI_QH qh;
831
    UHCIAsync *async = (UHCIAsync *) packet;
832

  
833
    dprintf("uhci: async complete. td 0x%x token 0x%x\n", async->td, async->token);
834

  
835
    async->done = 1;
836

  
837
    uhci_process_frame(s);
838
}
839

  
840
static int is_valid(uint32_t link)
841
{
842
    return (link & 1) == 0;
843
}
844

  
845
static int is_qh(uint32_t link)
846
{
847
    return (link & 2) != 0;
848
}
849

  
850
static int depth_first(uint32_t link)
851
{
852
    return (link & 4) != 0;
853
}
854

  
855
/* QH DB used for detecting QH loops */
856
#define UHCI_MAX_QUEUES 128
857
typedef struct {
858
    uint32_t addr[UHCI_MAX_QUEUES];
859
    int      count;
860
} QhDb;
861

  
862
static void qhdb_reset(QhDb *db)
863
{
864
    db->count = 0;
865
}
866

  
867
/* Add QH to DB. Returns 1 if already present or DB is full. */
868
static int qhdb_insert(QhDb *db, uint32_t addr)
869
{
870
    int i;
871
    for (i = 0; i < db->count; i++)
872
        if (db->addr[i] == addr)
873
            return 1;
874

  
875
    if (db->count >= UHCI_MAX_QUEUES)
876
        return 1;
877

  
878
    db->addr[db->count++] = addr;
879
    return 0;
880
}
881

  
882
static void uhci_process_frame(UHCIState *s)
883
{
884
    uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
885
    uint32_t curr_qh;
886
    int cnt, ret;
646 887
    UHCI_TD td;
647
    uint32_t link;
648
    uint32_t old_td_ctrl;
649
    uint32_t val;
650
    uint32_t frame_addr;
651
    int ret;
888
    UHCI_QH qh;
889
    QhDb qhdb;
652 890

  
653
    /* Handle async isochronous packet completion */
654
    frame_addr = s->async_frame_addr;
655
    if (frame_addr) {
656
        cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
657
        le32_to_cpus(&link);
891
    frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
892

  
893
    dprintf("uhci: processing frame %d addr 0x%x\n" , s->frnum, frame_addr);
894

  
895
    cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
896
    le32_to_cpus(&link);
658 897

  
659
        cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
898
    int_mask = 0;
899
    curr_qh  = 0;
900

  
901
    qhdb_reset(&qhdb);
902

  
903
    for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
904
        if (is_qh(link)) {
905
            /* QH */
906

  
907
            if (qhdb_insert(&qhdb, link)) {
908
                /*
909
                 * We're going in circles. Which is not a bug because
910
                 * HCD is allowed to do that as part of the BW management. 
911
                 * In our case though it makes no sense to spin here. Sync transations 
912
                 * are already done, and async completion handler will re-process 
913
                 * the frame when something is ready.
914
                 */
915
                dprintf("uhci: detected loop. qh 0x%x\n", link);
916
                break;
917
            }
918

  
919
            cpu_physical_memory_read(link & ~0xf, (uint8_t *) &qh, sizeof(qh));
920
            le32_to_cpus(&qh.link);
921
            le32_to_cpus(&qh.el_link);
922

  
923
            dprintf("uhci: QH 0x%x load. link 0x%x elink 0x%x\n",
924
                    link, qh.link, qh.el_link);
925

  
926
            if (!is_valid(qh.el_link)) {
927
                /* QH w/o elements */
928
                curr_qh = 0;
929
                link = qh.link;
930
            } else {
931
                /* QH with elements */
932
            	curr_qh = link;
933
            	link = qh.el_link;
934
            }
935
            continue;
936
        }
937

  
938
        /* TD */
939
        cpu_physical_memory_read(link & ~0xf, (uint8_t *) &td, sizeof(td));
660 940
        le32_to_cpus(&td.link);
661 941
        le32_to_cpus(&td.ctrl);
662 942
        le32_to_cpus(&td.token);
663 943
        le32_to_cpus(&td.buffer);
664
        old_td_ctrl = td.ctrl;
665
        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
666 944

  
667
        /* update the status bits of the TD */
945
        dprintf("uhci: TD 0x%x load. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n", 
946
                link, td.link, td.ctrl, td.token, curr_qh);
947

  
948
        old_td_ctrl = td.ctrl;
949
        ret = uhci_handle_td(s, link, &td, &int_mask);
668 950
        if (old_td_ctrl != td.ctrl) {
951
            /* update the status bits of the TD */
669 952
            val = cpu_to_le32(td.ctrl);
670 953
            cpu_physical_memory_write((link & ~0xf) + 4,
671
                                      (const uint8_t *)&val,
672
                                      sizeof(val));
954
                                      (const uint8_t *)&val, sizeof(val));
673 955
        }
674
        if (ret == 2) {
675
            s->async_frame_addr = frame_addr;
676
        } else if (ret == 0) {
677
            /* update qh element link */
678
            val = cpu_to_le32(td.link);
679
            cpu_physical_memory_write(frame_addr,
680
                                      (const uint8_t *)&val,
681
                                      sizeof(val));
956

  
957
        if (ret < 0) {
958
            /* interrupted frame */
959
            break;
682 960
        }
683
        return;
684
    }
685 961

  
686
    link = s->async_qh;
687
    if (!link) {
688
        /* This should never happen. It means a TD somehow got removed
689
           without cancelling the associated async IO request.  */
690
        return;
691
    }
692
    cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
693
    le32_to_cpus(&qh.link);
694
    le32_to_cpus(&qh.el_link);
695
    /* Re-process the queue containing the async packet.  */
696
    while (1) {
697
        cpu_physical_memory_read(qh.el_link & ~0xf,
698
                                 (uint8_t *)&td, sizeof(td));
699
        le32_to_cpus(&td.link);
700
        le32_to_cpus(&td.ctrl);
701
        le32_to_cpus(&td.token);
702
        le32_to_cpus(&td.buffer);
703
        old_td_ctrl = td.ctrl;
704
        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
962
        if (ret == 2 || ret == 1) {
963
            dprintf("uhci: TD 0x%x %s. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",
964
                    link, ret == 2 ? "pend" : "skip",
965
                    td.link, td.ctrl, td.token, curr_qh);
705 966

  
706
        /* update the status bits of the TD */
707
        if (old_td_ctrl != td.ctrl) {
708
            val = cpu_to_le32(td.ctrl);
709
            cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
710
                                      (const uint8_t *)&val,
711
                                      sizeof(val));
967
            link = curr_qh ? qh.link : td.link;
968
            continue;
712 969
        }
713
        if (ret < 0)
714
            break; /* interrupted frame */
715
        if (ret == 2) {
716
            s->async_qh = link;
717
            break;
718
        } else if (ret == 0) {
719
            /* update qh element link */
720
            qh.el_link = td.link;
970

  
971
        /* completed TD */
972

  
973
        dprintf("uhci: TD 0x%x done. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n", 
974
                link, td.link, td.ctrl, td.token, curr_qh);
975

  
976
        link = td.link;
977

  
978
        if (curr_qh) {
979
	    /* update QH element link */
980
            qh.el_link = link;
721 981
            val = cpu_to_le32(qh.el_link);
722
            cpu_physical_memory_write((link & ~0xf) + 4,
723
                                      (const uint8_t *)&val,
724
                                      sizeof(val));
725
            if (!(qh.el_link & 4))
726
                break;
982
            cpu_physical_memory_write((curr_qh & ~0xf) + 4,
983
                                          (const uint8_t *)&val, sizeof(val));
984

  
985
            if (!depth_first(link)) {
986
               /* done with this QH */
987

  
988
               dprintf("uhci: QH 0x%x done. link 0x%x elink 0x%x\n",
989
                       curr_qh, qh.link, qh.el_link);
990

  
991
               curr_qh = 0;
992
               link    = qh.link;
993
            }
727 994
        }
728
        break;
995

  
996
        /* go to the next entry */
729 997
    }
998

  
999
    s->pending_int_mask = int_mask;
730 1000
}
731 1001

  
732 1002
static void uhci_frame_timer(void *opaque)
733 1003
{
734 1004
    UHCIState *s = opaque;
735 1005
    int64_t expire_time;
736
    uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
737
    int cnt, ret;
738
    UHCI_TD td;
739
    UHCI_QH qh;
740
    uint32_t old_async_qh;
741 1006

  
742 1007
    if (!(s->cmd & UHCI_CMD_RS)) {
1008
        /* Full stop */
743 1009
        qemu_del_timer(s->frame_timer);
744 1010
        /* set hchalted bit in status - UHCI11D 2.1.2 */
745 1011
        s->status |= UHCI_STS_HCHALTED;
746 1012
        return;
747 1013
    }
748
    /* Complete the previous frame.  */
749
    s->frnum = (s->frnum + 1) & 0x7ff;
1014

  
1015
    /* Complete the previous frame */
750 1016
    if (s->pending_int_mask) {
751 1017
        s->status2 |= s->pending_int_mask;
752
        s->status |= UHCI_STS_USBINT;
1018
        s->status  |= UHCI_STS_USBINT;
753 1019
        uhci_update_irq(s);
754 1020
    }
755
    old_async_qh = s->async_qh;
756
    frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
757
    cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
758
    le32_to_cpus(&link);
759
    int_mask = 0;
760
    cnt = FRAME_MAX_LOOPS;
761
    while ((link & 1) == 0) {
762
        if (--cnt == 0)
763
            break;
764
        /* valid frame */
765
        if (link & 2) {
766
            /* QH */
767
            if (link == s->async_qh) {
768
                /* We've found a previously issues packet.
769
                   Nothing else to do.  */
770
                old_async_qh = 0;
771
                break;
772
            }
773
            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
774
            le32_to_cpus(&qh.link);
775
            le32_to_cpus(&qh.el_link);
776
        depth_first:
777
            if (qh.el_link & 1) {
778
                /* no element : go to next entry */
779
                link = qh.link;
780
            } else if (qh.el_link & 2) {
781
                /* QH */
782
                link = qh.el_link;
783
            } else if (s->async_qh) {
784
                /* We can only cope with one pending packet.  Keep looking
785
                   for the previously issued packet.  */
786
                link = qh.link;
787
            } else {
788
                /* TD */
789
                if (--cnt == 0)
790
                    break;
791
                cpu_physical_memory_read(qh.el_link & ~0xf,
792
                                         (uint8_t *)&td, sizeof(td));
793
                le32_to_cpus(&td.link);
794
                le32_to_cpus(&td.ctrl);
795
                le32_to_cpus(&td.token);
796
                le32_to_cpus(&td.buffer);
797
                old_td_ctrl = td.ctrl;
798
                ret = uhci_handle_td(s, &td, &int_mask, 0);
799

  
800
                /* update the status bits of the TD */
801
                if (old_td_ctrl != td.ctrl) {
802
                    val = cpu_to_le32(td.ctrl);
803
                    cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
804
                                              (const uint8_t *)&val,
805
                                              sizeof(val));
806
                }
807
                if (ret < 0)
808
                    break; /* interrupted frame */
809
                if (ret == 2) {
810
                    s->async_qh = link;
811
                } else if (ret == 0) {
812
                    /* update qh element link */
813
                    qh.el_link = td.link;
814
                    val = cpu_to_le32(qh.el_link);
815
                    cpu_physical_memory_write((link & ~0xf) + 4,
816
                                              (const uint8_t *)&val,
817
                                              sizeof(val));
818
                    if (qh.el_link & 4) {
819
                        /* depth first */
820
                        goto depth_first;
821
                    }
822
                }
823
                /* go to next entry */
824
                link = qh.link;
825
            }
826
        } else {
827
            /* TD */
828
            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
829
            le32_to_cpus(&td.link);
830
            le32_to_cpus(&td.ctrl);
831
            le32_to_cpus(&td.token);
832
            le32_to_cpus(&td.buffer);
833

  
834
            /* Handle isochonous transfer.  */
835
            /* FIXME: might be more than one isoc in frame */
836
            old_td_ctrl = td.ctrl;
837
            ret = uhci_handle_td(s, &td, &int_mask, 0);
838 1021

  
839
            /* update the status bits of the TD */
840
            if (old_td_ctrl != td.ctrl) {
841
                val = cpu_to_le32(td.ctrl);
842
                cpu_physical_memory_write((link & ~0xf) + 4,
843
                                          (const uint8_t *)&val,
844
                                          sizeof(val));
845
            }
846
            if (ret < 0)
847
                break; /* interrupted frame */
848
            if (ret == 2) {
849
                s->async_frame_addr = frame_addr;
850
            }
851
            link = td.link;
852
        }
853
    }
854
    s->pending_int_mask = int_mask;
855
    if (old_async_qh) {
856
        /* A previously started transfer has disappeared from the transfer
857
           list.  There's nothing useful we can do with it now, so just
858
           discard the packet and hope it wasn't too important.  */
859
#ifdef DEBUG
860
        printf("Discarding USB packet\n");
861
#endif
862
        usb_cancel_packet(&s->usb_packet);
863
        s->async_qh = 0;
864
    }
1022
    /* Start new frame */
1023
    s->frnum = (s->frnum + 1) & 0x7ff;
1024

  
1025
    dprintf("uhci: new frame #%u\n" , s->frnum);
1026

  
1027
    uhci_async_validate_begin(s);
1028

  
1029
    uhci_process_frame(s);
1030

  
1031
    uhci_async_validate_end(s);
865 1032

  
866 1033
    /* prepare the timer for the next frame */
867 1034
    expire_time = qemu_get_clock(vm_clock) +
......
950 1117
       to rely on this.  */
951 1118
    pci_register_io_region(&s->dev, 4, 0x20,
952 1119
                           PCI_ADDRESS_SPACE_IO, uhci_map);
1120

  
1121
    register_savevm("uhci", 0, 1, uhci_save, uhci_load, s);
953 1122
}

Also available in: Unified diff