From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01CA3C4363A for ; Mon, 5 Oct 2020 15:37:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B108F206DD for ; Mon, 5 Oct 2020 15:37:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1601912239; bh=gCKQc0RuxXgtsmMmxBMiFoGPVaXIUmX3aLYTtzXxrzw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=M+WLt18RpNTvkrvadeuzMllVzKPXTvWH2gjTH+jT+qv6Lsr8r/twqJ5Jbd/EgwbwR fwfqrp+1SsX4X04Mx8cqey0hStokAJXLvF9z2A9ai2vzjawLv8fIIupCT/Wp83Bvty +6HREjocy16V1l5Mw1xDgXT5RVUTH6M2t21LjGh4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728512AbgJEPhS (ORCPT ); Mon, 5 Oct 2020 11:37:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:59642 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727975AbgJEPcN (ORCPT ); Mon, 5 Oct 2020 11:32:13 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5DF9C2085B; Mon, 5 Oct 2020 15:32:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1601911932; bh=gCKQc0RuxXgtsmMmxBMiFoGPVaXIUmX3aLYTtzXxrzw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=flaVJOHOK1n9eQ2n86NOSnw5K8EL38Uu+mvTUBHXU0c+eUsdZqRo7wnRqPZ/k/KeO mk4tgMY9cKNNPHJ0FjzxOu9gS47Zpkabg+EmKr4qkzRDZZqCHuU05nBoTrkSBH30yI k5Y/3cTrFCwhZ3TFjLMmmY/FPUxnFLOyC3JBYoEE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Bastien Nocera , Valentina Manea , Shuah Khan , Alan Stern , syzkaller@googlegroups.com, Andrey Konovalov , Shuah Khan , "M. Vefa Bicakci" Subject: [PATCH 5.8 08/85] usbcore/driver: Accommodate usbip Date: Mon, 5 Oct 2020 17:26:04 +0200 Message-Id: <20201005142115.136344472@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201005142114.732094228@linuxfoundation.org> References: <20201005142114.732094228@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: M. Vefa Bicakci commit 3fce39601a1a34d940cf62858ee01ed9dac5d459 upstream. Commit 88b7381a939d ("USB: Select better matching USB drivers when available") inadvertently broke usbip functionality. The commit in question allows USB device drivers to be explicitly matched with USB devices via the use of driver-provided identifier tables and match functions, which is useful for a specialised device driver to be chosen for a device that can also be handled by another, more generic, device driver. Prior, the USB device section of usb_device_match() had an unconditional "return 1" statement, which allowed user-space to bind USB devices to the usbip_host device driver, if desired. However, the aforementioned commit changed the default/fallback return value to zero. This breaks device drivers such as usbip_host, so this commit restores the legacy behaviour, but only if a device driver does not have an id_table and a match() function. In addition, if usb_device_match is called for a device driver and device pair where the device does not match the id_table of the device driver in question, then the device driver will be disqualified for the device. This allows avoiding the default case of "return 1", which prevents undesirable probe() calls to a driver even though its id_table did not match the device. Finally, this commit changes the specialised-driver-to-generic-driver transition code so that when a device driver returns -ENODEV, a more generic device driver is only considered if the current device driver does not have an id_table and a match() function. This ensures that "generic" drivers such as usbip_host will not be considered specialised device drivers and will not cause the device to be locked in to the generic device driver, when a more specialised device driver could be tried. All of these changes restore usbip functionality without regressions, ensure that the specialised/generic device driver selection logic works as expected with the usb and apple-mfi-fastcharge drivers, and do not negatively affect the use of devices provided by dummy_hcd. Fixes: 88b7381a939d ("USB: Select better matching USB drivers when available") Cc: # 5.8 Cc: Bastien Nocera Cc: Valentina Manea Cc: Shuah Khan Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Tested-by: Andrey Konovalov Acked-by: Shuah Khan Signed-off-by: M. Vefa Bicakci Link: https://lore.kernel.org/r/20200922110703.720960-5-m.v.b@runbox.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -269,8 +269,30 @@ static int usb_probe_device(struct devic if (error) return error; + /* Probe the USB device with the driver in hand, but only + * defer to a generic driver in case the current USB + * device driver has an id_table or a match function; i.e., + * when the device driver was explicitly matched against + * a device. + * + * If the device driver does not have either of these, + * then we assume that it can bind to any device and is + * not truly a more specialized/non-generic driver, so a + * return value of -ENODEV should not force the device + * to be handled by the generic USB driver, as there + * can still be another, more specialized, device driver. + * + * This accommodates the usbip driver. + * + * TODO: What if, in the future, there are multiple + * specialized USB device drivers for a particular device? + * In such cases, there is a need to try all matching + * specialised device drivers prior to setting the + * use_generic_driver bit. + */ error = udriver->probe(udev); - if (error == -ENODEV && udriver != &usb_generic_driver) { + if (error == -ENODEV && udriver != &usb_generic_driver && + (udriver->id_table || udriver->match)) { udev->use_generic_driver = 1; return -EPROBE_DEFER; } @@ -831,14 +853,17 @@ static int usb_device_match(struct devic udev = to_usb_device(dev); udrv = to_usb_device_driver(drv); - if (udrv->id_table && - usb_device_match_id(udev, udrv->id_table) != NULL) { - return 1; - } + if (udrv->id_table) + return usb_device_match_id(udev, udrv->id_table) != NULL; if (udrv->match) return udrv->match(udev); - return 0; + + /* If the device driver under consideration does not have a + * id_table or a match function, then let the driver's probe + * function decide. + */ + return 1; } else if (is_usb_interface(dev)) { struct usb_interface *intf;