From 8bcc21a7fae8578f94762f7b31f3582e48773dc7 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 21 Jul 2011 16:43:56 -0300 Subject: [RHEL6 qemu-kvm PATCH 18/65] usb-ehci: Fix handling of PED and PEDC port status bits RH-Author: Gerd Hoffmann Message-id: <1311266648-1179-19-git-send-email-kraxel@redhat.com> Patchwork-id: 30139 O-Subject: [RHEL-6.2 kvm PATCH 18/30] usb-ehci: Fix handling of PED and PEDC port status bits Bugzilla: 723858 723863 RH-Acked-by: Hans de Goede RH-Acked-by: Jes Sorensen RH-Acked-by: Alex Williamson From: Hans de Goede The PED bit should only be set for highspeed devices and the PEDC bit should not be set on "normal" PED bit changes, only on io errors. Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann (cherry picked from commit fbd97532d22b6989fc71d64471c905d3c8174f5d) --- hw/usb-ehci.c | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) Signed-off-by: Eduardo Habkost --- hw/usb-ehci.c | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index e219d9d..edcd4a8 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -106,7 +106,7 @@ * Bits that are reserved or are read-only are masked out of values * written to us by software */ -#define PORTSC_RO_MASK 0x007021c4 +#define PORTSC_RO_MASK 0x007021c0 #define PORTSC_RWC_MASK 0x0000002a #define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable #define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable @@ -752,7 +752,7 @@ static void ehci_detach(USBPort *port) ehci_queues_rip_device(s, port->dev); - *portsc &= ~PORTSC_CONNECT; + *portsc &= ~(PORTSC_CONNECT|PORTSC_PED); *portsc |= PORTSC_CSC; /* @@ -847,16 +847,14 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val) static void handle_port_status_write(EHCIState *s, int port, uint32_t val) { uint32_t *portsc = &s->portsc[port]; - int rwc; USBDevice *dev = s->ports[port].dev; - rwc = val & PORTSC_RWC_MASK; + /* Clear rwc bits */ + *portsc &= ~(val & PORTSC_RWC_MASK); + /* The guest may clear, but not set the PED bit */ + *portsc &= val | ~PORTSC_PED; val &= PORTSC_RO_MASK; - // handle_read_write_clear(&val, portsc, PORTSC_PEDC | PORTSC_CSC); - - *portsc &= ~rwc; - if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) { trace_usb_ehci_port_reset(port, 1); } @@ -869,13 +867,13 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val) *portsc &= ~PORTSC_CSC; } - /* Table 2.16 Set the enable bit(and enable bit change) to indicate + /* + * Table 2.16 Set the enable bit(and enable bit change) to indicate * to SW that this port has a high speed device attached - * - * TODO - when to disable? */ - val |= PORTSC_PED; - val |= PORTSC_PEDC; + if (dev && (dev->speedmask & USB_SPEED_MASK_HIGH)) { + val |= PORTSC_PED; + } } *portsc &= ~PORTSC_RO_MASK; -- 1.7.3.2