diff options
author | Andreas Färber | 2013-01-10 21:52:28 +0100 |
---|---|---|
committer | Andreas Färber | 2013-01-10 21:52:28 +0100 |
commit | 63e3555e80c31776285accbb4d0c14ae91c457dc (patch) | |
tree | 89907c82724d6519c8bbad7acc15c0198c6f902f /hw/usb/hcd-ohci.c | |
parent | prep: Use pc87312 device instead of collection of random ISA devices (diff) | |
parent | Merge remote-tracking branch 'kraxel/build.1' into staging (diff) | |
download | qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.tar.gz qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.tar.xz qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.zip |
Merge branch 'master' of git://git.qemu.org/qemu into prep-up
Conflicts:
hw/Makefile.objs
hw/ppc_prep.c
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
Diffstat (limited to 'hw/usb/hcd-ohci.c')
-rw-r--r-- | hw/usb/hcd-ohci.c | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 844e7ed166..29bafa6da9 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -27,9 +27,9 @@ */ #include "hw/hw.h" -#include "qemu-timer.h" +#include "qemu/timer.h" #include "hw/usb.h" -#include "hw/pci.h" +#include "hw/pci/pci.h" #include "hw/sysbus.h" #include "hw/qdev-dma.h" @@ -430,6 +430,23 @@ static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr) return NULL; } +static void ohci_stop_endpoints(OHCIState *ohci) +{ + USBDevice *dev; + int i, j; + + for (i = 0; i < ohci->num_ports; i++) { + dev = ohci->rhport[i].port.dev; + if (dev && dev->attached) { + usb_device_ep_stopped(dev, &dev->ep_ctl); + for (j = 0; j < USB_MAX_ENDPOINTS; j++) { + usb_device_ep_stopped(dev, &dev->ep_in[j]); + usb_device_ep_stopped(dev, &dev->ep_out[j]); + } + } + } +} + /* Reset the controller */ static void ohci_reset(void *opaque) { @@ -478,6 +495,7 @@ static void ohci_reset(void *opaque) usb_cancel_packet(&ohci->usb_packet); ohci->async_td = 0; } + ohci_stop_endpoints(ohci); DPRINTF("usb-ohci: Reset %s\n", ohci->name); } @@ -807,18 +825,24 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, DMA_DIRECTION_TO_DEVICE); } - if (completion) { - ret = ohci->usb_packet.result; - } else { + if (!completion) { + bool int_req = relative_frame_number == frame_count && + OHCI_BM(iso_td.flags, TD_DI) == 0; dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); - usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_setup(&ohci->usb_packet, pid, ep, addr, false, int_req); usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); - ret = usb_handle_packet(dev, &ohci->usb_packet); - if (ret == USB_RET_ASYNC) { + usb_handle_packet(dev, &ohci->usb_packet); + if (ohci->usb_packet.status == USB_RET_ASYNC) { + usb_device_flush_ep_queue(dev, ep); return 1; } } + if (ohci->usb_packet.status == USB_RET_SUCCESS) { + ret = ohci->usb_packet.actual_length; + } else { + ret = ohci->usb_packet.status; + } #ifdef DEBUG_ISOCH printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n", @@ -994,7 +1018,6 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) } #endif if (completion) { - ret = ohci->usb_packet.result; ohci->async_td = 0; ohci->async_complete = 0; } else { @@ -1011,17 +1034,25 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) } dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); - usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_setup(&ohci->usb_packet, pid, ep, addr, !flag_r, + OHCI_BM(td.flags, TD_DI) == 0); usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); - ret = usb_handle_packet(dev, &ohci->usb_packet); + usb_handle_packet(dev, &ohci->usb_packet); #ifdef DEBUG_PACKET - DPRINTF("ret=%d\n", ret); + DPRINTF("status=%d\n", ohci->usb_packet.status); #endif - if (ret == USB_RET_ASYNC) { + if (ohci->usb_packet.status == USB_RET_ASYNC) { + usb_device_flush_ep_queue(dev, ep); ohci->async_td = addr; return 1; } } + if (ohci->usb_packet.status == USB_RET_SUCCESS) { + ret = ohci->usb_packet.actual_length; + } else { + ret = ohci->usb_packet.status; + } + if (ret >= 0) { if (dir == OHCI_TD_DIR_IN) { ohci_copy_td(ohci, &td, ohci->usb_buf, ret, @@ -1134,6 +1165,8 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) if (ohci->async_td && addr == ohci->async_td) { usb_cancel_packet(&ohci->usb_packet); ohci->async_td = 0; + usb_device_ep_stopped(ohci->usb_packet.ep->dev, + ohci->usb_packet.ep); } continue; } @@ -1214,10 +1247,12 @@ static void ohci_frame_boundary(void *opaque) } /* Cancel all pending packets if either of the lists has been disabled. */ - if (ohci->async_td && - ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; + if (ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) { + if (ohci->async_td) { + usb_cancel_packet(&ohci->usb_packet); + ohci->async_td = 0; + } + ohci_stop_endpoints(ohci); } ohci->old_ctl = ohci->ctl; ohci_process_lists(ohci, 0); @@ -1470,12 +1505,10 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) if (old_state != port->ctrl) ohci_set_interrupt(ohci, OHCI_INTR_RHSC); - - return; } static uint64_t ohci_mem_read(void *opaque, - target_phys_addr_t addr, + hwaddr addr, unsigned size) { OHCIState *ohci = opaque; @@ -1598,7 +1631,7 @@ static uint64_t ohci_mem_read(void *opaque, } static void ohci_mem_write(void *opaque, - target_phys_addr_t addr, + hwaddr addr, uint64_t val, unsigned size) { @@ -1848,7 +1881,7 @@ static int ohci_init_pxa(SysBusDevice *dev) /* Cannot fail as we pass NULL for masterbus */ usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0, - NULL); + &dma_context_memory); sysbus_init_irq(dev, &s->ohci.irq); sysbus_init_mmio(dev, &s->ohci.mem); @@ -1871,6 +1904,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB; k->class_id = PCI_CLASS_SERIAL_USB; + k->no_hotplug = 1; dc->desc = "Apple USB Controller"; dc->props = ohci_pci_properties; } |