527
459
cpu_physical_memory_rw(ptr, buf, len - n, write);
530
/* Read/Write the contents of an ISO TD from/to main memory. */
531
static void ohci_copy_iso_td(uint32_t start_addr, uint32_t end_addr,
532
uint8_t *buf, int len, int write)
538
n = 0x1000 - (ptr & 0xfff);
541
cpu_physical_memory_rw(ptr, buf, n, write);
544
ptr = end_addr & ~0xfffu;
546
cpu_physical_memory_rw(ptr, buf, len - n, write);
549
static void ohci_process_lists(OHCIState *ohci, int completion);
551
static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
462
static void ohci_process_lists(OHCIState *ohci);
464
static void ohci_async_complete_packet(USBPacket * packet, void *opaque)
553
466
OHCIState *ohci = opaque;
554
467
#ifdef DEBUG_PACKET
555
468
dprintf("Async packet complete\n");
557
470
ohci->async_complete = 1;
558
ohci_process_lists(ohci, 1);
561
#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
563
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
568
const char *str = NULL;
573
struct ohci_iso_td iso_td;
575
uint16_t starting_frame;
576
int16_t relative_frame_number;
578
uint32_t start_offset, next_offset, end_offset = 0;
579
uint32_t start_addr, end_addr;
581
addr = ed->head & OHCI_DPTR_MASK;
583
if (!ohci_read_iso_td(addr, &iso_td)) {
584
printf("usb-ohci: ISO_TD read error at %x\n", addr);
588
starting_frame = OHCI_BM(iso_td.flags, TD_SF);
589
frame_count = OHCI_BM(iso_td.flags, TD_FC);
590
relative_frame_number = USUB(ohci->frame_number, starting_frame);
593
printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
594
"0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
595
"0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
596
"0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
597
"frame_number 0x%.8x starting_frame 0x%.8x\n"
598
"frame_count 0x%.8x relative %d\n"
599
"di 0x%.8x cc 0x%.8x\n",
600
ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
601
iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
602
iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
603
iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
604
ohci->frame_number, starting_frame,
605
frame_count, relative_frame_number,
606
OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
609
if (relative_frame_number < 0) {
610
dprintf("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
612
} else if (relative_frame_number > frame_count) {
613
/* ISO TD expired - retire the TD to the Done Queue and continue with
614
the next ISO TD of the same ED */
615
dprintf("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number,
617
OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
618
ed->head &= ~OHCI_DPTR_MASK;
619
ed->head |= (iso_td.next & OHCI_DPTR_MASK);
620
iso_td.next = ohci->done;
622
i = OHCI_BM(iso_td.flags, TD_DI);
623
if (i < ohci->done_count)
624
ohci->done_count = i;
625
ohci_put_iso_td(addr, &iso_td);
629
dir = OHCI_BM(ed->flags, ED_D);
635
case OHCI_TD_DIR_OUT:
639
case OHCI_TD_DIR_SETUP:
641
pid = USB_TOKEN_SETUP;
644
printf("usb-ohci: Bad direction %d\n", dir);
648
if (!iso_td.bp || !iso_td.be) {
649
printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
653
start_offset = iso_td.offset[relative_frame_number];
654
next_offset = iso_td.offset[relative_frame_number + 1];
656
if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
657
((relative_frame_number < frame_count) &&
658
!(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
659
printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
660
start_offset, next_offset);
664
if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
665
printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
666
start_offset, next_offset);
670
if ((start_offset & 0x1000) == 0) {
671
start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
672
(start_offset & OHCI_OFFSET_MASK);
674
start_addr = (iso_td.be & OHCI_PAGE_MASK) |
675
(start_offset & OHCI_OFFSET_MASK);
678
if (relative_frame_number < frame_count) {
679
end_offset = next_offset - 1;
680
if ((end_offset & 0x1000) == 0) {
681
end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
682
(end_offset & OHCI_OFFSET_MASK);
684
end_addr = (iso_td.be & OHCI_PAGE_MASK) |
685
(end_offset & OHCI_OFFSET_MASK);
688
/* Last packet in the ISO TD */
689
end_addr = iso_td.be;
692
if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
693
len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
694
- (start_addr & OHCI_OFFSET_MASK);
696
len = end_addr - start_addr + 1;
699
if (len && dir != OHCI_TD_DIR_IN) {
700
ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, len, 0);
704
ret = ohci->usb_packet.len;
707
for (i = 0; i < ohci->num_ports; i++) {
708
dev = ohci->rhport[i].port.dev;
709
if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
711
ohci->usb_packet.pid = pid;
712
ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
713
ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
714
ohci->usb_packet.data = ohci->usb_buf;
715
ohci->usb_packet.len = len;
716
ohci->usb_packet.complete_cb = ohci_async_complete_packet;
717
ohci->usb_packet.complete_opaque = ohci;
718
ret = dev->handle_packet(dev, &ohci->usb_packet);
719
if (ret != USB_RET_NODEV)
723
if (ret == USB_RET_ASYNC) {
729
printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
730
start_offset, end_offset, start_addr, end_addr, str, len, ret);
734
if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
735
/* IN transfer succeeded */
736
ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, ret, 1);
737
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
739
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
740
} else if (dir == OHCI_TD_DIR_OUT && ret == len) {
741
/* OUT transfer succeeded */
742
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
744
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
746
if (ret > (ssize_t) len) {
747
printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
748
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
749
OHCI_CC_DATAOVERRUN);
750
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
752
} else if (ret >= 0) {
753
printf("usb-ohci: DataUnderrun %d\n", ret);
754
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
755
OHCI_CC_DATAUNDERRUN);
759
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
760
OHCI_CC_DEVICENOTRESPONDING);
761
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
766
printf("usb-ohci: got NAK/STALL %d\n", ret);
767
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
769
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
773
printf("usb-ohci: Bad device response %d\n", ret);
774
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
775
OHCI_CC_UNDEXPETEDPID);
781
if (relative_frame_number == frame_count) {
782
/* Last data packet of ISO TD - retire the TD to the Done Queue */
783
OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
784
ed->head &= ~OHCI_DPTR_MASK;
785
ed->head |= (iso_td.next & OHCI_DPTR_MASK);
786
iso_td.next = ohci->done;
788
i = OHCI_BM(iso_td.flags, TD_DI);
789
if (i < ohci->done_count)
790
ohci->done_count = i;
792
ohci_put_iso_td(addr, &iso_td);
471
ohci_process_lists(ohci);
796
474
/* Service a transport descriptor.