Commit 9df25137 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents d9767f1b 087462c7
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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);
    }
+53 −30
Original line number Diff line number Diff line
@@ -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++)
static void ohci_hard_reset(OHCIState *ohci)
{
        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);
    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[] = {