mirror of https://github.com/xemu-project/xemu.git
usb: mtp and ohci fixes.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJWj4wjAAoJEEy22O7T6HE4PegP/A9occg8K/vXW9WKm4qJLX3w MCSlyEnIVWkK6nRx8xQnzINxvxFg7KXmWU8Rkp8JY7NZOFpdo4/ivGObfl4B7bCY uHfdXAmU7RycT3m0TERS92fK95LPurN19q/66me1HH8orfOMBYmoVr7UILJaehUW ZHEka0lnPeTcs7AY59svUn8g6Xr4dn5zN0v0mEJemAjWmOiolMcX9P/hKskn7nPc kC3vu/vVFEXmKWVwAYrDasFltAJ1670tIvI8sNhPZeoD+wucMBLx29JJ8760AmJT kQO4vZkD0GM4AjDCvKt8tCn6XQt/5D+Fg9gdXtX7Nv8IbHhrLYrTM8iQsvT7dyCX JhY4USoKERjjttzDo6JbGZDYe5YwUP5U9QNXVTCw9oM8jfTA9o6evnFgASMEbGlW CZpZG+PCYe/x2MG4pMSVHYR/RZxNfncqdjX7jxr376zDGWt5ptnZWrNlL92O/+XI 3biXorhsiJUtHMmrDIR8xhGn44F1/zVAvuP+1oqt7kMSr9p7wtxQ2RQEcVFQ7QJN KU6DEoC5EYjUEv74HIylHyrLGa1s+l1LUFS0c4TQGslO5BcjprF37l48q+o+3G9V nN6s+UqUhI8J8mvx7jE04xROPZmMf6oztw28j8EEMbHVvdyPgnCcJcHX0QuEBEWH fZrVjBLAT12RZk4Z7X6f =mdBV -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20160108-1' into staging usb: mtp and ohci fixes. # gpg: Signature made Fri 08 Jan 2016 10:14:59 GMT using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-usb-20160108-1: ohci: clear pending SOF on suspend ohci: delay first SOF interrupt usb-mtp: fix call to trace function usb-mtp: use safe variant when cleaning events list ohci: fix command HostControllerReset ohci: fix Host Controller USBRESET ohci: split reset method in 3 parts Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9df2513730
|
@ -502,9 +502,9 @@ static void inotify_watchfn(void *arg)
|
|||
entry = g_new0(MTPMonEntry, 1);
|
||||
entry->handle = o->handle;
|
||||
entry->event = EVT_OBJ_REMOVED;
|
||||
usb_mtp_object_free(s, o);
|
||||
trace_usb_mtp_inotify_event(s->dev.addr, o->path,
|
||||
event->mask, "Obj Deleted");
|
||||
usb_mtp_object_free(s, o);
|
||||
break;
|
||||
|
||||
case IN_MODIFY:
|
||||
|
@ -556,7 +556,7 @@ static int usb_mtp_inotify_init(MTPState *s)
|
|||
|
||||
static void usb_mtp_inotify_cleanup(MTPState *s)
|
||||
{
|
||||
MTPMonEntry *e;
|
||||
MTPMonEntry *e, *p;
|
||||
|
||||
if (!s->inotifyfd) {
|
||||
return;
|
||||
|
@ -565,7 +565,7 @@ static void usb_mtp_inotify_cleanup(MTPState *s)
|
|||
qemu_set_fd_handler(s->inotifyfd, NULL, NULL, s);
|
||||
close(s->inotifyfd);
|
||||
|
||||
QTAILQ_FOREACH(e, &s->events, next) {
|
||||
QTAILQ_FOREACH_SAFE(e, &s->events, next, p) {
|
||||
QTAILQ_REMOVE(&s->events, e, next);
|
||||
g_free(e);
|
||||
}
|
||||
|
|
|
@ -439,15 +439,37 @@ static void ohci_stop_endpoints(OHCIState *ohci)
|
|||
}
|
||||
}
|
||||
|
||||
/* Reset the controller */
|
||||
static void ohci_reset(void *opaque)
|
||||
static void ohci_roothub_reset(OHCIState *ohci)
|
||||
{
|
||||
OHCIState *ohci = opaque;
|
||||
OHCIPort *port;
|
||||
int i;
|
||||
|
||||
ohci_bus_stop(ohci);
|
||||
ohci->ctl = 0;
|
||||
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 && port->port.dev->attached) {
|
||||
usb_port_reset(&port->port);
|
||||
}
|
||||
}
|
||||
if (ohci->async_td) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
ohci->async_td = 0;
|
||||
}
|
||||
ohci_stop_endpoints(ohci);
|
||||
}
|
||||
|
||||
/* Reset the controller */
|
||||
static void ohci_soft_reset(OHCIState *ohci)
|
||||
{
|
||||
trace_usb_ohci_reset(ohci->name);
|
||||
|
||||
ohci_bus_stop(ohci);
|
||||
ohci->ctl = (ohci->ctl & OHCI_CTL_IR) | OHCI_USB_SUSPEND;
|
||||
ohci->old_ctl = 0;
|
||||
ohci->status = 0;
|
||||
ohci->intr_status = 0;
|
||||
|
@ -470,25 +492,13 @@ static void ohci_reset(void *opaque)
|
|||
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 && port->port.dev->attached) {
|
||||
usb_port_reset(&port->port);
|
||||
}
|
||||
}
|
||||
if (ohci->async_td) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
ohci->async_td = 0;
|
||||
}
|
||||
ohci_stop_endpoints(ohci);
|
||||
trace_usb_ohci_reset(ohci->name);
|
||||
static void ohci_hard_reset(OHCIState *ohci)
|
||||
{
|
||||
ohci_soft_reset(ohci);
|
||||
ohci->ctl = 0;
|
||||
ohci_roothub_reset(ohci);
|
||||
}
|
||||
|
||||
/* Get an array of dwords from main memory */
|
||||
|
@ -1231,11 +1241,16 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
|
|||
return active;
|
||||
}
|
||||
|
||||
/* Generate a SOF event, and set a timer for EOF */
|
||||
static void ohci_sof(OHCIState *ohci)
|
||||
/* set a timer for EOF */
|
||||
static void ohci_eof_timer(OHCIState *ohci)
|
||||
{
|
||||
ohci->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
timer_mod(ohci->eof_timer, ohci->sof_time + usb_frame_time);
|
||||
}
|
||||
/* Set a timer for EOF and generate a SOF event */
|
||||
static void ohci_sof(OHCIState *ohci)
|
||||
{
|
||||
ohci_eof_timer(ohci);
|
||||
ohci_set_interrupt(ohci, OHCI_INTR_SF);
|
||||
}
|
||||
|
||||
|
@ -1343,7 +1358,12 @@ static int ohci_bus_start(OHCIState *ohci)
|
|||
|
||||
trace_usb_ohci_start(ohci->name);
|
||||
|
||||
ohci_sof(ohci);
|
||||
/* Delay the first SOF event by one frame time as
|
||||
* linux driver is not ready to receive it and
|
||||
* can meet some race conditions
|
||||
*/
|
||||
|
||||
ohci_eof_timer(ohci);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1436,12 +1456,15 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
|
|||
break;
|
||||
case OHCI_USB_SUSPEND:
|
||||
ohci_bus_stop(ohci);
|
||||
/* clear pending SF otherwise linux driver loops in ohci_irq() */
|
||||
ohci->intr_status &= ~OHCI_INTR_SF;
|
||||
ohci_intr_update(ohci);
|
||||
break;
|
||||
case OHCI_USB_RESUME:
|
||||
trace_usb_ohci_resume(ohci->name);
|
||||
break;
|
||||
case OHCI_USB_RESET:
|
||||
ohci_reset(ohci);
|
||||
ohci_roothub_reset(ohci);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1704,7 +1727,7 @@ static void ohci_mem_write(void *opaque,
|
|||
ohci->status |= val;
|
||||
|
||||
if (ohci->status & OHCI_STATUS_HCR)
|
||||
ohci_reset(ohci);
|
||||
ohci_soft_reset(ohci);
|
||||
break;
|
||||
|
||||
case 3: /* HcInterruptStatus */
|
||||
|
@ -1783,7 +1806,7 @@ static void ohci_mem_write(void *opaque,
|
|||
case 25: /* HcHReset */
|
||||
ohci->hreset = val & ~OHCI_HRESET_FSBIR;
|
||||
if (val & OHCI_HRESET_FSBIR)
|
||||
ohci_reset(ohci);
|
||||
ohci_hard_reset(ohci);
|
||||
break;
|
||||
|
||||
case 26: /* HcHInterruptEnable */
|
||||
|
@ -1960,7 +1983,7 @@ static void usb_ohci_reset_pci(DeviceState *d)
|
|||
OHCIPCIState *ohci = PCI_OHCI(dev);
|
||||
OHCIState *s = &ohci->state;
|
||||
|
||||
ohci_reset(s);
|
||||
ohci_hard_reset(s);
|
||||
}
|
||||
|
||||
#define TYPE_SYSBUS_OHCI "sysbus-ohci"
|
||||
|
@ -1993,7 +2016,7 @@ static void usb_ohci_reset_sysbus(DeviceState *dev)
|
|||
OHCISysBusState *s = SYSBUS_OHCI(dev);
|
||||
OHCIState *ohci = &s->ohci;
|
||||
|
||||
ohci_reset(ohci);
|
||||
ohci_hard_reset(ohci);
|
||||
}
|
||||
|
||||
static Property ohci_pci_properties[] = {
|
||||
|
|
Loading…
Reference in New Issue