From patchwork Sat Sep 22 09:29:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 186114 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DE8092C0096 for ; Sat, 22 Sep 2012 19:29:53 +1000 (EST) Received: from localhost ([::1]:58756 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFM22-0002UK-B6 for incoming@patchwork.ozlabs.org; Sat, 22 Sep 2012 05:29:50 -0400 Received: from eggs.gnu.org ([208.118.235.92]:42721) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFM1s-0002U2-IR for qemu-devel@nongnu.org; Sat, 22 Sep 2012 05:29:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TFM1o-0007Mf-Ir for qemu-devel@nongnu.org; Sat, 22 Sep 2012 05:29:40 -0400 Received: from mout.web.de ([212.227.15.3]:58139) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFM1o-0007MZ-93 for qemu-devel@nongnu.org; Sat, 22 Sep 2012 05:29:36 -0400 Received: from mchn199C.mchp.siemens.de ([95.157.56.37]) by smtp.web.de (mrweb002) with ESMTPSA (Nemesis) id 0LgpYk-1TsJSl0Epa-00oXd9; Sat, 22 Sep 2012 11:29:25 +0200 Message-ID: <505D84F3.3070106@web.de> Date: Sat, 22 Sep 2012 11:29:23 +0200 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Hans de Goede References: <5054AC57.205@web.de> <5056E876.9010400@redhat.com> In-Reply-To: <5056E876.9010400@redhat.com> X-Enigmail-Version: 1.4.4 X-Provags-ID: V02:K0:3qeIHyUxEnRQa4Q13ooWEvJfB+9llB1v0lJ3AbddizI TjzZry4Zbzfi/S95ELRBPGPhIUbibwibTRce2oi5SwcdZTbnU5 xuIiD5ZgzFlHalrWg+td65ULPYzaTMXEbA3eXn57vD+Y3UoLrP TF23qiacCJnwXLGH0O1h0YzYu0IuZJ6gBKGowDLNHVjZNmht2r wteRhARW+jXgUjydSoygA== X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 212.227.15.3 Cc: qemu-devel , Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2] usb-redir: Allow to attach USB 2.0 devices to 1.1 host controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Jan Kiszka This follows the logic of host-linux: If a 2.0 device has no ISO endpoint and no interrupt endpoint with a packet size > 64, we can attach it also to an 1.1 host controller. In case the redir server does not report endpoint sizes, play safe and remove the 1.1 compatibility as well. Moreover, if we detect a conflicting change in the configuration after the device was already attached, it will be disconnected immediately. Signed-off-by: Jan Kiszka --- Changes in v2: - fix incompatibility marking via introduction of compatible_speedmask - disconnect device if incompatibility is detected when already attached hw/usb/redirect.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-) diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index b10241a..2099ea4 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -105,6 +105,7 @@ struct USBRedirDevice { struct usb_redir_interface_info_header interface_info; struct usbredirfilter_rule *filter_rules; int filter_rules_count; + int compatible_speedmask; }; static void usbredir_hello(void *priv, struct usb_redir_hello_header *h); @@ -1037,6 +1038,9 @@ static int usbredir_initfn(USBDevice *udev) /* We'll do the attach once we receive the speed from the usb-host */ udev->auto_attach = 0; + /* Will be cleared during setup when we find conflicts */ + dev->compatible_speedmask = USB_SPEED_MASK_FULL; + /* Let the backend know we are ready */ qemu_chr_fe_open(dev->cs); qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, @@ -1177,10 +1181,12 @@ static void usbredir_device_connect(void *priv, case usb_redir_speed_low: speed = "low speed"; dev->dev.speed = USB_SPEED_LOW; + dev->dev.speedmask = 0; break; case usb_redir_speed_full: speed = "full speed"; dev->dev.speed = USB_SPEED_FULL; + dev->dev.speedmask = 0; break; case usb_redir_speed_high: speed = "high speed"; @@ -1189,6 +1195,7 @@ static void usbredir_device_connect(void *priv, case usb_redir_speed_super: speed = "super speed"; dev->dev.speed = USB_SPEED_SUPER; + dev->dev.speedmask = 0; break; default: speed = "unknown speed"; @@ -1210,7 +1217,7 @@ static void usbredir_device_connect(void *priv, device_connect->device_class); } - dev->dev.speedmask = (1 << dev->dev.speed); + dev->dev.speedmask = (1 << dev->dev.speed) | dev->compatible_speedmask; dev->device_info = *device_connect; if (usbredir_check_filter(dev)) { @@ -1271,6 +1278,14 @@ static void usbredir_interface_info(void *priv, } } +static void usbredir_mark_fullspeed_incompatible(USBRedirDevice *dev) +{ + dev->compatible_speedmask &= ~USB_SPEED_MASK_FULL; + if (dev->dev.attached && dev->dev.port->dev->speed == USB_SPEED_FULL) { + usbredir_device_disconnect(dev); + } +} + static void usbredir_ep_info(void *priv, struct usb_redir_ep_info_header *ep_info) { @@ -1286,7 +1301,14 @@ static void usbredir_ep_info(void *priv, case usb_redir_type_invalid: break; case usb_redir_type_iso: + usbredir_mark_fullspeed_incompatible(dev); + /* Fall through */ case usb_redir_type_interrupt: + if (!usbredirparser_peer_has_cap(dev->parser, + usb_redir_cap_ep_info_max_packet_size) || + ep_info->max_packet_size[i] > 64) { + usbredir_mark_fullspeed_incompatible(dev); + } if (dev->endpoint[i].interval == 0) { ERROR("Received 0 interval for isoc or irq endpoint\n"); usbredir_device_disconnect(dev);