/* Set HcControlRegister */ static void ohci_set_ctl(OHCIState *ohci, uint32_t val) { uint32_t old_state; uint32_t new_state; old_state = ohci->ctl & OHCI_CTL_HCFS; ohci->ctl = val; new_state = ohci->ctl & OHCI_CTL_HCFS; /* no state change */ if (old_state == new_state) return; switch (new_state) { case OHCI_USB_OPERATIONAL: ohci_bus_start(ohci); break; case OHCI_USB_SUSPEND: ohci_bus_stop(ohci); DPRINTF("usb-ohci: %s: USB Suspended\n", ohci->name); break; case OHCI_USB_RESUME: DPRINTF("usb-ohci: %s: USB Resume\n", ohci->name); break; case OHCI_USB_RESET: ohci_reset(ohci); DPRINTF("usb-ohci: %s: USB Reset\n", ohci->name); break; } }
/* Reset the controller */ static void ohci_reset(void *opaque) { OHCIState *ohci = opaque; OHCIPort *port; int i; ohci_bus_stop(ohci); ohci->ctl = 0; ohci->old_ctl = 0; ohci->status = 0; ohci->intr_status = 0; ohci->intr = OHCI_INTR_MIE; ohci->hcca = 0; ohci->ctrl_head = ohci->ctrl_cur = 0; ohci->bulk_head = ohci->bulk_cur = 0; ohci->per_cur = 0; ohci->done = 0; ohci->done_count = 7; /* FSMPS is marked TBD in OCHI 1.0, what gives ffs? * I took the value linux sets ... */ ohci->fsmps = 0x2778; ohci->fi = 0x2edf; ohci->fit = 0; ohci->frt = 0; ohci->frame_number = 0; ohci->pstart = 0; ohci->lst = OHCI_LS_THRESH; ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports; ohci->rhdesc_b = 0x0; /* Impl. specific */ ohci->rhstatus = 0; for (i = 0; i < ohci->num_ports; i++) { port = &ohci->rhport[i]; port->ctrl = 0; if (port->port.dev) { usb_attach(&port->port, port->port.dev); } } if (ohci->async_td) { usb_cancel_packet(&ohci->usb_packet); ohci->async_td = 0; } DPRINTF("usb-ohci: Reset %s\n", ohci->name); }
static void usb_ohci_exit(PCIDevice *dev) { OHCIPCIState *ohci = PCI_OHCI(dev); OHCIState *s = &ohci->state; trace_usb_ohci_exit(s->name); ohci_bus_stop(s); if (s->async_td) { usb_cancel_packet(&s->usb_packet); s->async_td = 0; } ohci_stop_endpoints(s); if (!ohci->masterbus) { usb_bus_release(&s->bus); } timer_del(s->eof_timer); timer_free(s->eof_timer); }