Commit c62adbee authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'kraxel/usb.74' into staging



* kraxel/usb.74:
  usb-tablet: Allow connecting to ehci
  ehci: Lower timer freq when the periodic schedule is idle
  usb: Allow overriding of usb_desc at the device level
  usb: Don't allow USB_RET_ASYNC for interrupt packets
  usb: Call wakeup when data becomes available for all devices with int eps
  add pc-1.4

Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents e49d021e 427e3aa1
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -281,8 +281,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
}
#endif

static QEMUMachine pc_machine_v1_3 = {
    .name = "pc-1.3",
static QEMUMachine pc_machine_v1_4 = {
    .name = "pc-1.4",
    .alias = "pc",
    .desc = "Standard PC",
    .init = pc_init_pci_1_3,
@@ -290,7 +290,26 @@ static QEMUMachine pc_machine_v1_3 = {
    .is_default = 1,
};

#define PC_COMPAT_1_3 \
        {\
            .driver   = "usb-tablet",\
            .property = "usb_version",\
            .value    = stringify(1),\
        }

static QEMUMachine pc_machine_v1_3 = {
    .name = "pc-1.3",
    .desc = "Standard PC",
    .init = pc_init_pci_1_3,
    .max_cpus = 255,
    .compat_props = (GlobalProperty[]) {
        PC_COMPAT_1_3,
        { /* end of list */ }
    },
};

#define PC_COMPAT_1_2 \
        PC_COMPAT_1_3,\
        {\
            .driver   = "nec-usb-xhci",\
            .property = "msi",\
@@ -626,6 +645,7 @@ static QEMUMachine xenfv_machine = {

static void pc_machine_init(void)
{
    qemu_register_machine(&pc_machine_v1_4);
    qemu_register_machine(&pc_machine_v1_3);
    qemu_register_machine(&pc_machine_v1_2);
    qemu_register_machine(&pc_machine_v1_1);
+2 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ struct USBEndpoint {

enum USBDeviceFlags {
    USB_DEV_FLAG_FULL_PATH,
    USB_DEV_FLAG_IS_HOST,
};

/* definition of a USB device */
@@ -229,6 +230,7 @@ struct USBDevice {
    USBEndpoint ep_out[USB_MAX_ENDPOINTS];

    QLIST_HEAD(, USBDescString) strings;
    const USBDesc *usb_desc; /* Overrides class usb_desc if not NULL */
    const USBDescDevice *device;

    int configuration;
+3 −0
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ const char *usb_device_get_product_desc(USBDevice *dev)
const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
{
    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
    if (dev->usb_desc) {
        return dev->usb_desc;
    }
    return klass->usb_desc;
}

+4 −0
Original line number Diff line number Diff line
@@ -406,7 +406,11 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
        usb_process_one(p);
        if (p->status == USB_RET_ASYNC) {
            /* hcd drivers cannot handle async for isoc */
            assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
            /* using async for interrupt packets breaks migration */
            assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
                   (dev->flags & USB_DEV_FLAG_IS_HOST));
            usb_packet_set_state(p, USB_PACKET_ASYNC);
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
        } else if (p->status == USB_RET_ADD_TO_QUEUE) {
+84 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ typedef struct USBHIDState {
    USBDevice dev;
    USBEndpoint *intr;
    HIDState hid;
    uint32_t usb_version;
} USBHIDState;

enum {
@@ -131,6 +132,36 @@ static const USBDescIface desc_iface_tablet = {
    },
};

static const USBDescIface desc_iface_tablet2 = {
    .bInterfaceNumber              = 0,
    .bNumEndpoints                 = 1,
    .bInterfaceClass               = USB_CLASS_HID,
    .bInterfaceProtocol            = 0x02,
    .ndesc                         = 1,
    .descs = (USBDescOther[]) {
        {
            /* HID descriptor */
            .data = (uint8_t[]) {
                0x09,          /*  u8  bLength */
                USB_DT_HID,    /*  u8  bDescriptorType */
                0x01, 0x00,    /*  u16 HID_class */
                0x00,          /*  u8  country_code */
                0x01,          /*  u8  num_descriptors */
                USB_DT_REPORT, /*  u8  type: Report */
                74, 0,         /*  u16 len */
            },
        },
    },
    .eps = (USBDescEndpoint[]) {
        {
            .bEndpointAddress      = USB_DIR_IN | 0x01,
            .bmAttributes          = USB_ENDPOINT_XFER_INT,
            .wMaxPacketSize        = 8,
            .bInterval             = 4, /* 2 ^ (4-1) * 125 usecs = 1 ms */
        },
    },
};

static const USBDescIface desc_iface_keyboard = {
    .bInterfaceNumber              = 0,
    .bNumEndpoints                 = 1,
@@ -196,6 +227,23 @@ static const USBDescDevice desc_device_tablet = {
    },
};

static const USBDescDevice desc_device_tablet2 = {
    .bcdUSB                        = 0x0200,
    .bMaxPacketSize0               = 64,
    .bNumConfigurations            = 1,
    .confs = (USBDescConfig[]) {
        {
            .bNumInterfaces        = 1,
            .bConfigurationValue   = 1,
            .iConfiguration        = STR_CONFIG_TABLET,
            .bmAttributes          = 0xa0,
            .bMaxPower             = 50,
            .nif = 1,
            .ifs = &desc_iface_tablet2,
        },
    },
};

static const USBDescDevice desc_device_keyboard = {
    .bcdUSB                        = 0x0100,
    .bMaxPacketSize0               = 8,
@@ -239,6 +287,20 @@ static const USBDesc desc_tablet = {
    .str  = desc_strings,
};

static const USBDesc desc_tablet2 = {
    .id = {
        .idVendor          = 0x0627,
        .idProduct         = 0x0001,
        .bcdDevice         = 0,
        .iManufacturer     = STR_MANUFACTURER,
        .iProduct          = STR_PRODUCT_TABLET,
        .iSerialNumber     = STR_SERIALNUMBER,
    },
    .full = &desc_device_tablet,
    .high = &desc_device_tablet2,
    .str  = desc_strings,
};

static const USBDesc desc_keyboard = {
    .id = {
        .idVendor          = 0x0627,
@@ -508,6 +570,21 @@ static int usb_hid_initfn(USBDevice *dev, int kind)

static int usb_tablet_initfn(USBDevice *dev)
{
    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);

    switch (us->usb_version) {
    case 1:
        dev->usb_desc = &desc_tablet;
        break;
    case 2:
        dev->usb_desc = &desc_tablet2;
        break;
    default:
        error_report("Invalid usb version %d for usb-tabler (must be 1 or 2)",
                     us->usb_version);
        return -1;
    }

    return usb_hid_initfn(dev, HID_TABLET);
}

@@ -562,8 +639,14 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data)
    uc->handle_control = usb_hid_handle_control;
    uc->handle_data    = usb_hid_handle_data;
    uc->handle_destroy = usb_hid_handle_destroy;
    uc->handle_attach  = usb_desc_attach;
}

static Property usb_tablet_properties[] = {
        DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
        DEFINE_PROP_END_OF_LIST(),
};

static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
@@ -572,8 +655,8 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
    usb_hid_class_initfn(klass, data);
    uc->init           = usb_tablet_initfn;
    uc->product_desc   = "QEMU USB Tablet";
    uc->usb_desc       = &desc_tablet;
    dc->vmsd = &vmstate_usb_ptr;
    dc->props = usb_tablet_properties;
}

static TypeInfo usb_tablet_info = {
Loading