From patchwork Sat Mar 25 16:18:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Semwal X-Patchwork-Id: 95993 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp532254qgd; Sat, 25 Mar 2017 09:19:46 -0700 (PDT) X-Received: by 10.98.113.74 with SMTP id m71mr16082385pfc.231.1490458786431; Sat, 25 Mar 2017 09:19:46 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r3si6723034pli.62.2017.03.25.09.19.46; Sat, 25 Mar 2017 09:19:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751364AbdCYQTq (ORCPT + 5 others); Sat, 25 Mar 2017 12:19:46 -0400 Received: from mail-pf0-f176.google.com ([209.85.192.176]:34165 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751309AbdCYQTp (ORCPT ); Sat, 25 Mar 2017 12:19:45 -0400 Received: by mail-pf0-f176.google.com with SMTP id p189so8002680pfp.1 for ; Sat, 25 Mar 2017 09:19:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8DEhyLKBDQCZGGKBYXyziKmBumwTrnOxxVQ2RjMNEbw=; b=jZ3TpCzEKitdEeQENX3BCP+FKC9G0EkI8J3XTrUrjplC8SFe8AgEugwhjYLGyw7d8j tSBcG0HopQsOfb4+bAsJcEj2vWxxZDVd2QNWw2JR2+0dEOyA0BsGv9EIGu7kbiszmXBC Ne7LEeGLj/5ovOynGOxE2SByQT8CUEl9YDfwg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8DEhyLKBDQCZGGKBYXyziKmBumwTrnOxxVQ2RjMNEbw=; b=cpvDmN3tRaUkRpVxLxG8vCFA+Ua2m6A1pZdQu7nNRk61LG1anTogikFJbP+z+ztj4D gyMBbrjp3OfSUX82lfgq4eWVFXaPmy5bL5lsOxBgIdnSnABXrQjDDpq0MKQ/iXa95Sgv vKIXMoMcNNQ5bBj7Ev9VsfCj13MxwmjurQms6oIob1uYu3hdMgG1fPx0fbkNGlq2PBmh C6iZcSsPFtafgiNbmDndBM3vd5P6cUOlLO4DP/N2a4qIp61Q9Jqq29t4Qz/vC7puNZZl ZkE2ar2gyM17JvdmEkPM9mV4BYhBqrh8OnMqI6VAKVlFeFjAVxyMM1LVE8N9NPDSblfx ULpw== X-Gm-Message-State: AFeK/H1rfWDWX1rw2owMtfeKjOJQmKBX+//p1OCLBKRWMlk6+3P2uxFhkiVPj4xlgPgXjwGP X-Received: by 10.99.45.2 with SMTP id t2mr15411197pgt.209.1490458784283; Sat, 25 Mar 2017 09:19:44 -0700 (PDT) Received: from phantom.lan ([106.51.225.38]) by smtp.gmail.com with ESMTPSA id q194sm11469541pfq.43.2017.03.25.09.19.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 25 Mar 2017 09:19:43 -0700 (PDT) From: Sumit Semwal To: stable@vger.kernel.org Cc: Henrik Ingo , Laurent Pinchart , Mauro Carvalho Chehab , Sasha Levin , Greg Kroah-Hartman , Sumit Semwal Subject: [PATCH for-4.4 16/19] uvcvideo: uvc_scan_fallback() for webcams with broken chain Date: Sat, 25 Mar 2017 21:48:16 +0530 Message-Id: <1490458699-24484-17-git-send-email-sumit.semwal@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> References: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Henrik Ingo [ Upstream commit e950267ab802c8558f1100eafd4087fd039ad634 ] Some devices have invalid baSourceID references, causing uvc_scan_chain() to fail, but if we just take the entities we can find and put them together in the most sensible chain we can think of, turns out they do work anyway. Note: This heuristic assumes there is a single chain. At the time of writing, devices known to have such a broken chain are - Acer Integrated Camera (5986:055a) - Realtek rtl157a7 (0bda:57a7) Signed-off-by: Henrik Ingo Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sumit Semwal --- drivers/media/usb/uvc/uvc_driver.c | 118 +++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 6 deletions(-) -- 2.7.4 diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5cefca9..885f689 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain) return buffer; } +static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) +{ + struct uvc_video_chain *chain; + + chain = kzalloc(sizeof(*chain), GFP_KERNEL); + if (chain == NULL) + return NULL; + + INIT_LIST_HEAD(&chain->entities); + mutex_init(&chain->ctrl_mutex); + chain->dev = dev; + v4l2_prio_init(&chain->prio); + + return chain; +} + +/* + * Fallback heuristic for devices that don't connect units and terminals in a + * valid chain. + * + * Some devices have invalid baSourceID references, causing uvc_scan_chain() + * to fail, but if we just take the entities we can find and put them together + * in the most sensible chain we can think of, turns out they do work anyway. + * Note: This heuristic assumes there is a single chain. + * + * At the time of writing, devices known to have such a broken chain are + * - Acer Integrated Camera (5986:055a) + * - Realtek rtl157a7 (0bda:57a7) + */ +static int uvc_scan_fallback(struct uvc_device *dev) +{ + struct uvc_video_chain *chain; + struct uvc_entity *iterm = NULL; + struct uvc_entity *oterm = NULL; + struct uvc_entity *entity; + struct uvc_entity *prev; + + /* + * Start by locating the input and output terminals. We only support + * devices with exactly one of each for now. + */ + list_for_each_entry(entity, &dev->entities, list) { + if (UVC_ENTITY_IS_ITERM(entity)) { + if (iterm) + return -EINVAL; + iterm = entity; + } + + if (UVC_ENTITY_IS_OTERM(entity)) { + if (oterm) + return -EINVAL; + oterm = entity; + } + } + + if (iterm == NULL || oterm == NULL) + return -EINVAL; + + /* Allocate the chain and fill it. */ + chain = uvc_alloc_chain(dev); + if (chain == NULL) + return -ENOMEM; + + if (uvc_scan_chain_entity(chain, oterm) < 0) + goto error; + + prev = oterm; + + /* + * Add all Processing and Extension Units with two pads. The order + * doesn't matter much, use reverse list traversal to connect units in + * UVC descriptor order as we build the chain from output to input. This + * leads to units appearing in the order meant by the manufacturer for + * the cameras known to require this heuristic. + */ + list_for_each_entry_reverse(entity, &dev->entities, list) { + if (entity->type != UVC_VC_PROCESSING_UNIT && + entity->type != UVC_VC_EXTENSION_UNIT) + continue; + + if (entity->num_pads != 2) + continue; + + if (uvc_scan_chain_entity(chain, entity) < 0) + goto error; + + prev->baSourceID[0] = entity->id; + prev = entity; + } + + if (uvc_scan_chain_entity(chain, iterm) < 0) + goto error; + + prev->baSourceID[0] = iterm->id; + + list_add_tail(&chain->list, &dev->chains); + + uvc_trace(UVC_TRACE_PROBE, + "Found a video chain by fallback heuristic (%s).\n", + uvc_print_chain(chain)); + + return 0; + +error: + kfree(chain); + return -EINVAL; +} + /* * Scan the device for video chains and register video devices. * @@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev) if (term->chain.next || term->chain.prev) continue; - chain = kzalloc(sizeof(*chain), GFP_KERNEL); + chain = uvc_alloc_chain(dev); if (chain == NULL) return -ENOMEM; - INIT_LIST_HEAD(&chain->entities); - mutex_init(&chain->ctrl_mutex); - chain->dev = dev; - v4l2_prio_init(&chain->prio); - term->flags |= UVC_ENTITY_FLAG_DEFAULT; if (uvc_scan_chain(chain, term) < 0) { @@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev) list_add_tail(&chain->list, &dev->chains); } + if (list_empty(&dev->chains)) + uvc_scan_fallback(dev); + if (list_empty(&dev->chains)) { uvc_printk(KERN_INFO, "No valid video chain found.\n"); return -1;