Revision 7bfe5777

b/hw/usb-ohci.c
32 32
//#define DEBUG_OHCI
33 33
/* Dump packet contents.  */
34 34
//#define DEBUG_PACKET
35
//#define DEBUG_ISOCH
35 36
/* This causes frames to occur 1000x slower */
36 37
//#define OHCI_TIME_WARP 1
37 38

  
......
132 133
#define OHCI_ED_S         (1<<13)
133 134
#define OHCI_ED_K         (1<<14)
134 135
#define OHCI_ED_F         (1<<15)
135
#define OHCI_ED_MPS_SHIFT 7
136
#define OHCI_ED_MPS_MASK  (0xf<<OHCI_ED_FA_SHIFT)
136
#define OHCI_ED_MPS_SHIFT 16
137
#define OHCI_ED_MPS_MASK  (0x7ff<<OHCI_ED_MPS_SHIFT)
137 138

  
138 139
/* Flags in the head field of an Endpoint Desciptor.  */
139 140
#define OHCI_ED_H         1
......
152 153
#define OHCI_TD_CC_SHIFT  28
153 154
#define OHCI_TD_CC_MASK   (0xf<<OHCI_TD_CC_SHIFT)
154 155

  
156
/* Bitfields for the first word of an Isochronous Transfer Desciptor.  */
157
/* CC & DI - same as in the General Transfer Desciptor */
158
#define OHCI_TD_SF_SHIFT  0
159
#define OHCI_TD_SF_MASK   (0xffff<<OHCI_TD_SF_SHIFT)
160
#define OHCI_TD_FC_SHIFT  24
161
#define OHCI_TD_FC_MASK   (7<<OHCI_TD_FC_SHIFT)
162

  
163
/* Isochronous Transfer Desciptor - Offset / PacketStatusWord */
164
#define OHCI_TD_PSW_CC_SHIFT 12
165
#define OHCI_TD_PSW_CC_MASK  (0xf<<OHCI_TD_PSW_CC_SHIFT)
166
#define OHCI_TD_PSW_SIZE_SHIFT 0
167
#define OHCI_TD_PSW_SIZE_MASK  (0xfff<<OHCI_TD_PSW_SIZE_SHIFT)
168

  
169
#define OHCI_PAGE_MASK    0xfffff000
170
#define OHCI_OFFSET_MASK  0xfff
171

  
155 172
#define OHCI_DPTR_MASK    0xfffffff0
156 173

  
157 174
#define OHCI_BM(val, field) \
......
178 195
    uint32_t be;
179 196
};
180 197

  
198
/* Isochronous transfer descriptor */
199
struct ohci_iso_td {
200
    uint32_t flags;
201
    uint32_t bp;
202
    uint32_t next;
203
    uint32_t be;
204
    uint16_t offset[8];
205
};
206

  
181 207
#define USB_HZ                      12000000
182 208

  
183 209
/* OHCI Local stuff */
......
421 447
    return 1;
422 448
}
423 449

  
450
/* Get an array of words from main memory */
451
static inline int get_words(uint32_t addr, uint16_t *buf, int num)
452
{
453
    int i;
454

  
455
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
456
        cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
457
        *buf = le16_to_cpu(*buf);
458
    }
459

  
460
    return 1;
461
}
462

  
463
/* Put an array of words in to main memory */
464
static inline int put_words(uint32_t addr, uint16_t *buf, int num)
465
{
466
    int i;
467

  
468
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
469
        uint16_t tmp = cpu_to_le16(*buf);
470
        cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
471
    }
472

  
473
    return 1;
474
}
475

  
424 476
static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
425 477
{
426 478
    return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
......
431 483
    return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
432 484
}
433 485

  
486
static inline int ohci_read_iso_td(uint32_t addr, struct ohci_iso_td *td)
487
{
488
    return (get_dwords(addr, (uint32_t *)td, 4) &&
489
            get_words(addr + 16, td->offset, 8));
490
}
491

  
434 492
static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
435 493
{
436 494
    return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
......
441 499
    return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
442 500
}
443 501

  
502
static inline int ohci_put_iso_td(uint32_t addr, struct ohci_iso_td *td)
503
{
504
    return (put_dwords(addr, (uint32_t *)td, 4) &&
505
            put_words(addr + 16, td->offset, 8));
506
}
507

  
444 508
/* Read/Write the contents of a TD from/to main memory.  */
445 509
static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
446 510
{
......
459 523
    cpu_physical_memory_rw(ptr, buf, len - n, write);
460 524
}
461 525

  
462
static void ohci_process_lists(OHCIState *ohci);
526
/* Read/Write the contents of an ISO TD from/to main memory.  */
527
static void ohci_copy_iso_td(uint32_t start_addr, uint32_t end_addr,
528
                             uint8_t *buf, int len, int write)
529
{
530
    uint32_t ptr;
531
    uint32_t n;
463 532

  
464
static void ohci_async_complete_packet(USBPacket * packet, void *opaque)
533
    ptr = start_addr;
534
    n = 0x1000 - (ptr & 0xfff);
535
    if (n > len)
536
        n = len;
537
    cpu_physical_memory_rw(ptr, buf, n, write);
538
    if (n == len)
539
        return;
540
    ptr = end_addr & ~0xfffu;
541
    buf += n;
542
    cpu_physical_memory_rw(ptr, buf, len - n, write);
543
}
544

  
545
static void ohci_process_lists(OHCIState *ohci, int completion);
546

  
547
static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
465 548
{
466 549
    OHCIState *ohci = opaque;
467 550
#ifdef DEBUG_PACKET
468 551
    dprintf("Async packet complete\n");
469 552
#endif
470 553
    ohci->async_complete = 1;
471
    ohci_process_lists(ohci);
554
    ohci_process_lists(ohci, 1);
555
}
556

  
557
#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
558

  
559
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
560
                               int completion)
561
{
562
    int dir;
563
    size_t len = 0;
564
    char *str = NULL;
565
    int pid;
566
    int ret;
567
    int i;
568
    USBDevice *dev;
569
    struct ohci_iso_td iso_td;
570
    uint32_t addr;
571
    uint16_t starting_frame;
572
    int16_t relative_frame_number;
573
    int frame_count;
574
    uint32_t start_offset, next_offset, end_offset = 0;
575
    uint32_t start_addr, end_addr;
576

  
577
    addr = ed->head & OHCI_DPTR_MASK;
578

  
579
    if (!ohci_read_iso_td(addr, &iso_td)) {
580
        printf("usb-ohci: ISO_TD read error at %x\n", addr);
581
        return 0;
582
    }
583

  
584
    starting_frame = OHCI_BM(iso_td.flags, TD_SF);
585
    frame_count = OHCI_BM(iso_td.flags, TD_FC);
586
    relative_frame_number = USUB(ohci->frame_number, starting_frame); 
587

  
588
#ifdef DEBUG_ISOCH
589
    printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
590
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
591
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
592
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
593
           "frame_number 0x%.8x starting_frame 0x%.8x\n"
594
           "frame_count  0x%.8x relative %d\n"
595
           "di 0x%.8x cc 0x%.8x\n",
596
           ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
597
           iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
598
           iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
599
           iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
600
           ohci->frame_number, starting_frame, 
601
           frame_count, relative_frame_number,         
602
           OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
603
#endif
604

  
605
    if (relative_frame_number < 0) {
606
        dprintf("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
607
        return 1;
608
    } else if (relative_frame_number > frame_count) {
609
        /* ISO TD expired - retire the TD to the Done Queue and continue with
610
           the next ISO TD of the same ED */
611
        dprintf("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, 
612
               frame_count);
613
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
614
        ed->head &= ~OHCI_DPTR_MASK;
615
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
616
        iso_td.next = ohci->done;
617
        ohci->done = addr;
618
        i = OHCI_BM(iso_td.flags, TD_DI);
619
        if (i < ohci->done_count)
620
            ohci->done_count = i;
621
        ohci_put_iso_td(addr, &iso_td);        
622
        return 0;
623
    }
624

  
625
    dir = OHCI_BM(ed->flags, ED_D);
626
    switch (dir) {
627
    case OHCI_TD_DIR_IN:
628
        str = "in";
629
        pid = USB_TOKEN_IN;
630
        break;
631
    case OHCI_TD_DIR_OUT:
632
        str = "out";
633
        pid = USB_TOKEN_OUT;
634
        break;
635
    case OHCI_TD_DIR_SETUP:
636
        str = "setup";
637
        pid = USB_TOKEN_SETUP;
638
        break;
639
    default:
640
        printf("usb-ohci: Bad direction %d\n", dir);
641
        return 1;
642
    }
643

  
644
    if (!iso_td.bp || !iso_td.be) {
645
        printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
646
        return 1;
647
    }
648

  
649
    start_offset = iso_td.offset[relative_frame_number];
650
    next_offset = iso_td.offset[relative_frame_number + 1];
651

  
652
    if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || 
653
        ((relative_frame_number < frame_count) && 
654
         !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
655
        printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
656
               start_offset, next_offset);
657
        return 1;
658
    }
659

  
660
    if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
661
        printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
662
                start_offset, next_offset);
663
        return 1;
664
    }
665

  
666
    if ((start_offset & 0x1000) == 0) {
667
        start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
668
            (start_offset & OHCI_OFFSET_MASK);
669
    } else {
670
        start_addr = (iso_td.be & OHCI_PAGE_MASK) |
671
            (start_offset & OHCI_OFFSET_MASK);
672
    }
673

  
674
    if (relative_frame_number < frame_count) {
675
        end_offset = next_offset - 1;
676
        if ((end_offset & 0x1000) == 0) {
677
            end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
678
                (end_offset & OHCI_OFFSET_MASK);
679
        } else {
680
            end_addr = (iso_td.be & OHCI_PAGE_MASK) |
681
                (end_offset & OHCI_OFFSET_MASK);
682
        }
683
    } else {
684
        /* Last packet in the ISO TD */
685
        end_addr = iso_td.be;
686
    }
687

  
688
    if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
689
        len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
690
            - (start_addr & OHCI_OFFSET_MASK);
691
    } else {
692
        len = end_addr - start_addr + 1;
693
    }
694

  
695
    if (len && dir != OHCI_TD_DIR_IN) {
696
        ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, len, 0);
697
    }
698

  
699
    if (completion) {
700
        ret = ohci->usb_packet.len;
701
    } else {
702
        ret = USB_RET_NODEV;
703
        for (i = 0; i < ohci->num_ports; i++) {
704
            dev = ohci->rhport[i].port.dev;
705
            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
706
                continue;
707
            ohci->usb_packet.pid = pid;
708
            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
709
            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
710
            ohci->usb_packet.data = ohci->usb_buf;
711
            ohci->usb_packet.len = len;
712
            ohci->usb_packet.complete_cb = ohci_async_complete_packet;
713
            ohci->usb_packet.complete_opaque = ohci;
714
            ret = dev->handle_packet(dev, &ohci->usb_packet);
715
            if (ret != USB_RET_NODEV)
716
                break;
717
        }
718
    
719
        if (ret == USB_RET_ASYNC) {
720
            return 1;
721
        }
722
    }
723

  
724
#ifdef DEBUG_ISOCH
725
    printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
726
           start_offset, end_offset, start_addr, end_addr, str, len, ret);
727
#endif
728

  
729
    /* Writeback */
730
    if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
731
        /* IN transfer succeeded */
732
        ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, ret, 1);
733
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
734
                    OHCI_CC_NOERROR);
735
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
736
    } else if (dir == OHCI_TD_DIR_OUT && ret == len) {
737
        /* OUT transfer succeeded */
738
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
739
                    OHCI_CC_NOERROR);
740
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
741
    } else {
742
        if (ret > len) {
743
            printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
744
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
745
                        OHCI_CC_DATAOVERRUN);
746
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
747
                        len);
748
        } else if (ret >= 0) {
749
            printf("usb-ohci: DataUnderrun %d\n", ret);
750
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
751
                        OHCI_CC_DATAUNDERRUN);
752
        } else {
753
            switch (ret) {
754
            case USB_RET_NODEV:
755
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
756
                            OHCI_CC_DEVICENOTRESPONDING);
757
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
758
                            0);
759
                break;
760
            case USB_RET_NAK:
761
            case USB_RET_STALL:
762
                printf("usb-ohci: got NAK/STALL %d\n", ret);
763
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
764
                            OHCI_CC_STALL);
765
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
766
                            0);
767
                break;
768
            default:
769
                printf("usb-ohci: Bad device response %d\n", ret);
770
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
771
                            OHCI_CC_UNDEXPETEDPID);
772
                break;
773
            }
774
        }
775
    }
776

  
777
    if (relative_frame_number == frame_count) {
778
        /* Last data packet of ISO TD - retire the TD to the Done Queue */
779
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
780
        ed->head &= ~OHCI_DPTR_MASK;
781
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
782
        iso_td.next = ohci->done;
783
        ohci->done = addr;
784
        i = OHCI_BM(iso_td.flags, TD_DI);
785
        if (i < ohci->done_count)
786
            ohci->done_count = i;
787
    }
788
    ohci_put_iso_td(addr, &iso_td);
789
    return 1;
472 790
}
473 791

  
474 792
/* Service a transport descriptor.
......
671 989
}
672 990

  
673 991
/* Service an endpoint list.  Returns nonzero if active TD were found.  */
674
static int ohci_service_ed_list(OHCIState *ohci, uint32_t head)
992
static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
675 993
{
676 994
    struct ohci_ed ed;
677 995
    uint32_t next_ed;
......
702 1020
            continue;
703 1021
        }
704 1022

  
705
        /* Skip isochronous endpoints.  */
706
        if (ed.flags & OHCI_ED_F)
707
          continue;
708

  
709 1023
        while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
710 1024
#ifdef DEBUG_PACKET
711 1025
            dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
......
719 1033
#endif
720 1034
            active = 1;
721 1035

  
722
            if (ohci_service_td(ohci, &ed))
723
                break;
1036
            if ((ed.flags & OHCI_ED_F) == 0) {
1037
                if (ohci_service_td(ohci, &ed))
1038
                    break;
1039
            } else {
1040
                /* Handle isochronous endpoints */
1041
                if (ohci_service_iso_td(ohci, &ed, completion))
1042
                    break;
1043
            }
724 1044
        }
725 1045

  
726 1046
        ohci_put_ed(cur, &ed);
......
738 1058
}
739 1059

  
740 1060
/* Process Control and Bulk lists.  */
741
static void ohci_process_lists(OHCIState *ohci)
1061
static void ohci_process_lists(OHCIState *ohci, int completion)
742 1062
{
743 1063
    if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
744 1064
        if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
745 1065
          dprintf("usb-ohci: head %x, cur %x\n", ohci->ctrl_head, ohci->ctrl_cur);
746
        if (!ohci_service_ed_list(ohci, ohci->ctrl_head)) {
1066
        if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
747 1067
            ohci->ctrl_cur = 0;
748 1068
            ohci->status &= ~OHCI_STATUS_CLF;
749 1069
        }
750 1070
    }
751 1071

  
752 1072
    if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
753
        if (!ohci_service_ed_list(ohci, ohci->bulk_head)) {
1073
        if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
754 1074
            ohci->bulk_cur = 0;
755 1075
            ohci->status &= ~OHCI_STATUS_BLF;
756 1076
        }
......
770 1090
        int n;
771 1091

  
772 1092
        n = ohci->frame_number & 0x1f;
773
        ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]));
1093
        ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
774 1094
    }
775 1095

  
776 1096
    /* Cancel all pending packets if either of the lists has been disabled.  */
......
780 1100
        ohci->async_td = 0;
781 1101
    }
782 1102
    ohci->old_ctl = ohci->ctl;
783
    ohci_process_lists(ohci);
1103
    ohci_process_lists(ohci, 0);
784 1104

  
785 1105
    /* Frame boundary, so do EOF stuf here */
786 1106
    ohci->frt = ohci->fit;
......
1206 1526
        ohci_set_frame_interval(ohci, val);
1207 1527
        break;
1208 1528

  
1529
    case 15: /* HcFmNumber */
1530
        break;
1531

  
1209 1532
    case 16: /* HcPeriodicStart */
1210 1533
        ohci->pstart = val & 0xffff;
1211 1534
        break;

Also available in: Unified diff