From patchwork Fri Apr 27 09:31:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 155408 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 3C6A8B6EEC for ; Fri, 27 Apr 2012 19:32:46 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SNhXb-0005iG-7F; Fri, 27 Apr 2012 09:32:39 +0000 Received: from mail-pz0-f48.google.com ([209.85.210.48]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SNhXZ-0005WE-EL for kernel-team@lists.ubuntu.com; Fri, 27 Apr 2012 09:32:37 +0000 Received: by mail-pz0-f48.google.com with SMTP id b39so684280dak.21 for ; Fri, 27 Apr 2012 02:32:37 -0700 (PDT) Received: by 10.68.236.165 with SMTP id uv5mr2940662pbc.37.1335519157006; Fri, 27 Apr 2012 02:32:37 -0700 (PDT) Received: from localhost ([183.37.200.43]) by mx.google.com with ESMTPS id ot5sm5973858pbb.26.2012.04.27.02.32.35 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 27 Apr 2012 02:32:36 -0700 (PDT) From: ming.lei@canonical.com To: kernel-team@lists.ubuntu.com Subject: [PATCH 07/10] usb/uas: only bind if the hcd supports SG Date: Fri, 27 Apr 2012 17:31:49 +0800 Message-Id: <1335519112-8372-8-git-send-email-ming.lei@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1335519112-8372-1-git-send-email-ming.lei@canonical.com> References: <1335519112-8372-1-git-send-email-ming.lei@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Sebastian Andrzej Siewior The UAS driver requires SG support by the HCD operating the device. This patch stops UAS from operating on a HCD without sg support and prints a message to let him know. The spec says: |For [USB2] backward compatibility, the device shall present [BOT] as |alternate interface zero (primary) and [UAS] as alternate interface one |(secondary). A device which does not need backward compatibility with |[BOT] shall present [UAS] as alternate interface zero. In [USB2] |systems, the [BOT] driver or an associated filter driver may need to |issue a SET INTERFACE request for alternate interface one and then allow |the [UAS] driver to load. If the user used usb_modeswitch to switch to UAS then he can go back to BOT or use a different HCD. In case UAS is the only interface then there is currently no way out. In future usb_sg_wait() should be extended to provide a non-blocking interface so it can work with the UAS driver. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e0133c9..e34c759 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -621,22 +622,34 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } +static int uas_isnt_supported(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + dev_warn(&udev->dev, "The driver for the USB controller %s does not " + "support scatter-gather which is\n", + hcd->driver->description); + dev_warn(&udev->dev, "required by the UAS driver. Please try an" + "alternative USB controller if you wish to use UAS.\n"); + return -ENODEV; +} + static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { int i; - - if (uas_is_interface(intf->cur_altsetting)) - return 0; + int sg_supported = udev->bus->sg_tablesize != 0; for (i = 0; i < intf->num_altsetting; i++) { struct usb_host_interface *alt = &intf->altsetting[i]; - if (alt == intf->cur_altsetting) - continue; - if (uas_is_interface(alt)) + + if (uas_is_interface(alt)) { + if (!sg_supported) + return uas_isnt_supported(udev); return usb_set_interface(udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + } } return -ENODEV;