From patchwork Wed Apr 24 00:42:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Nematbakhsh X-Patchwork-Id: 2481811 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 982D2DF2E5 for ; Wed, 24 Apr 2013 00:43:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755453Ab3DXAm7 (ORCPT ); Tue, 23 Apr 2013 20:42:59 -0400 Received: from mail-gg0-f202.google.com ([209.85.161.202]:65488 "EHLO mail-gg0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755226Ab3DXAm6 (ORCPT ); Tue, 23 Apr 2013 20:42:58 -0400 Received: by mail-gg0-f202.google.com with SMTP id 4so138935ggm.5 for ; Tue, 23 Apr 2013 17:42:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=FnimIbsYYkSaZb9L5tsUFvlBYeEQxAtPwwN36oB2l24=; b=j3Q/Mvh0rrOIE71pwVpefB8pz3Fgi+w12658Tc8NJX13Bx8YFoJmd+u+ZeElEQJEYE lcjjCCBMSeotIzsjlgcntmVmnC/86cbC97VA9jQDT4/JW43x64zT6NVSyEXc4qTkDsmu OwEGAV6nXc6WXJW2VmPcPrVL6IoKoSHMzUWACP7nzUXxxY7oxyzrEp3nu948RGRgFwb7 jz8Q9hZID2BUBim8rX4oK1lTApPsEq5UesPvVFH0O6/iaNp5OeB7fEpEd0VsuzDzWl/d qYZqAtRbC2ni1Q2KVVP96tDf3KHktSuI4aPhSo91Dbe9dJJiVY5j/DtsNS8fVNWKuX4U +oog== X-Received: by 10.236.231.170 with SMTP id l40mr6322929yhq.16.1366764178188; Tue, 23 Apr 2013 17:42:58 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id k57si54163yhi.3.2013.04.23.17.42.58 for (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Tue, 23 Apr 2013 17:42:58 -0700 (PDT) Received: from brainstorm.mtv.corp.google.com (brainstorm.mtv.corp.google.com [172.22.77.67]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 0D3F131C0AC; Tue, 23 Apr 2013 17:42:58 -0700 (PDT) Received: by brainstorm.mtv.corp.google.com (Postfix, from userid 167876) id BB480140716; Tue, 23 Apr 2013 17:42:57 -0700 (PDT) From: Shawn Nematbakhsh To: Laurent Pinchart Cc: Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, shawnn@chromium.org Subject: [PATCH] [media] uvcvideo: Retry usb_submit_urb on -EPERM return Date: Tue, 23 Apr 2013 17:42:32 -0700 Message-Id: <1366764152-9797-1-git-send-email-shawnn@chromium.org> X-Mailer: git-send-email 1.8.2.1 X-Gm-Message-State: ALoCoQmUusZ7rkOJ+62bG8GE7+FAi4jD8wnVLSNeSIeK1iUrGEsIOszpMTHu/+yKa+9BXc5BRP3QVp8q20NM5kq2EBNdF6W81DuBOIOx7heVTXkXps1hgdUZZ51sBpCz6whs2SX9kHQKUHxUgxn3dGo42mTau39cdW1do4sJYnLqXitpBPz5G6sPGRwZ369YWbkA17+shAU7DGSkY/74qBKjCo84ji7PsA== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org While usb_kill_urb is in progress, calls to usb_submit_urb will fail with -EPERM (documented in Documentation/usb/URB.txt). The UVC driver does not correctly handle this case -- there is no synchronization between uvc_v4l2_open / uvc_status_start and uvc_v4l2_release / uvc_status_stop. This patch adds a retry / timeout when uvc_status_open / usb_submit_urb returns -EPERM. This usually means that usb_kill_urb is in progress, and we just need to wait a while. Signed-off-by: Shawn Nematbakhsh --- drivers/media/usb/uvc/uvc_v4l2.c | 10 +++++++++- drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index b2dc326..f1498a8 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -479,6 +479,7 @@ static int uvc_v4l2_open(struct file *file) { struct uvc_streaming *stream; struct uvc_fh *handle; + unsigned long timeout; int ret = 0; uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); @@ -499,7 +500,14 @@ static int uvc_v4l2_open(struct file *file) } if (atomic_inc_return(&stream->dev->users) == 1) { - ret = uvc_status_start(stream->dev); + timeout = jiffies + msecs_to_jiffies(UVC_STATUS_START_TIMEOUT); + /* -EPERM means stop in progress, wait for completion */ + do { + ret = uvc_status_start(stream->dev); + if (ret == -EPERM) + usleep_range(5000, 6000); + } while (ret == -EPERM && time_before(jiffies, timeout)); + if (ret < 0) { atomic_dec(&stream->dev->users); usb_autopm_put_interface(stream->dev->intf); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index af505fd..a47e1d3 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -122,6 +122,7 @@ #define UVC_CTRL_CONTROL_TIMEOUT 300 #define UVC_CTRL_STREAMING_TIMEOUT 5000 +#define UVC_STATUS_START_TIMEOUT 100 /* Maximum allowed number of control mappings per device */ #define UVC_MAX_CONTROL_MAPPINGS 1024