From patchwork Fri Jan 18 22:34:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1027814 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="GDyVVmJG"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43hG2d594Rz9sDB for ; Sat, 19 Jan 2019 09:34:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730050AbfARWeP (ORCPT ); Fri, 18 Jan 2019 17:34:15 -0500 Received: from mail-qt1-f202.google.com ([209.85.160.202]:49787 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729621AbfARWeP (ORCPT ); Fri, 18 Jan 2019 17:34:15 -0500 Received: by mail-qt1-f202.google.com with SMTP id n95so13884860qte.16 for ; Fri, 18 Jan 2019 14:34:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=nTwWiOMeQQPk1NNhszgxior1P2ns22zYDbEehrWJJhA=; b=GDyVVmJGxCpnPZfgSkRb+EHQSCjT1v57gBZZaaytbbmyRQvxyhdKG5lN+denPb5+tK SI1pYset/N8ifX5j+ph4StEYsj0zYFYgbTzrbv8HX5LmBHmMKAMHXul3XmLBjV/TetRd OSd9rI+mOtkVCyN1fDN2vuyr7Gmkr0hKTLU4IHdiVRcpmLbCEUUw00kOA3MaFxGypJCZ 4VmcqMIaY45n/gc5tQ5cfJrG/Gf9ZU2Uh4r/IVWC8HwXhnSuYqcDsTD2ejWVubhod1nU G7AhMKH3L7CxdWYsqGojSkFM8nr4Yh9lCx66SDZqwJ3L+kYhyK9+KiLAky2/XU9/nqi/ xLRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=nTwWiOMeQQPk1NNhszgxior1P2ns22zYDbEehrWJJhA=; b=VTMqwKxn7FoIrb35R1wRJaz+hhLXvTPU+HVGyTuxua6BnYfwtfg7HMem7tCMbcnAnC 66QOf/UKhtX12HpHZAyXp9znkKFIJfqbp2Uw9+zgZYx/RKKll+70flG7b21PJ7lQ7JvF /oftsVk8r9D2dIrjV79CPHX/CL8PljEc4+PRXDdeAy9BYXqeToov7Tn5x77e4miiT9c+ QdkPVyHpY1UTJlviTeDEbgzrAlBK+a7wRmVogTocuZqgwgcAMi1ViHw2SOayJJ4Ml2nq nlwMxti4dGkXnYK2C0d5BENEJAwkk7U3I4laXxSmdd/NCH9z3SmfeahRys1gRn2qdkU9 rQ+Q== X-Gm-Message-State: AJcUukc29RzwQyt7iwuQh/oZ7S01MZuV7oXzTotYDGH/teTNlVCSxd9M N6g+sB1dQYgS0B1Z2RsDcvGc2o0uxMzO X-Google-Smtp-Source: ALg8bN6yUtDSjrlTpRirto0EsNpBCdSlPsT9yVoM4zTbDTrTSi63bp/ZP82V2DLYyOZ5x1EZYwUQBRXAxF4E X-Received: by 2002:aed:22a7:: with SMTP id p36mr13011395qtc.53.1547850854195; Fri, 18 Jan 2019 14:34:14 -0800 (PST) Date: Fri, 18 Jan 2019 14:34:03 -0800 In-Reply-To: <20181117010748.24347-1-rajatja@google.com> Message-Id: <20190118223407.64818-1-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v4 1/5] usb: split code locating ACPI companion into port and device From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dmitry Torokhov In preparation for handling embedded USB devices let's split usb_acpi_find_companion() into usb_acpi_find_companion_for_device() and usb_acpi_find_companion_for_port(). Signed-off-by: Dmitry Torokhov Signed-off-by: Rajat Jain Acked-by: Greg Kroah-Hartman Tested-by: Sukumar Ghorai --- v4: Add Acked-by and Tested-by in signatures. v3: same as v1 v2: same as v1 drivers/usb/core/usb-acpi.c | 133 +++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index e221861b3187..8ff73c83e8e8 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -139,12 +139,79 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent, return acpi_find_child_device(parent, raw, false); } -static struct acpi_device *usb_acpi_find_companion(struct device *dev) +static struct acpi_device * +usb_acpi_get_companion_for_port(struct usb_port *port_dev) { struct usb_device *udev; struct acpi_device *adev; acpi_handle *parent_handle; + int port1; + + /* Get the struct usb_device point of port's hub */ + udev = to_usb_device(port_dev->dev.parent->parent); + + /* + * The root hub ports' parent is the root hub. The non-root-hub + * ports' parent is the parent hub port which the hub is + * connected to. + */ + if (!udev->parent) { + adev = ACPI_COMPANION(&udev->dev); + port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus), + port_dev->portnum); + } else { + parent_handle = usb_get_hub_port_acpi_handle(udev->parent, + udev->portnum); + if (!parent_handle) + return NULL; + + acpi_bus_get_device(parent_handle, &adev); + port1 = port_dev->portnum; + } + + return usb_acpi_find_port(adev, port1); +} + +static struct acpi_device * +usb_acpi_find_companion_for_port(struct usb_port *port_dev) +{ + struct acpi_device *adev; + struct acpi_pld_info *pld; + acpi_handle *handle; + acpi_status status; + + adev = usb_acpi_get_companion_for_port(port_dev); + if (!adev) + return NULL; + + handle = adev->handle; + status = acpi_get_physical_device_location(handle, &pld); + if (!ACPI_FAILURE(status) && pld) { + port_dev->location = USB_ACPI_LOCATION_VALID + | pld->group_token << 8 | pld->group_position; + port_dev->connect_type = usb_acpi_get_connect_type(handle, pld); + ACPI_FREE(pld); + } + return adev; +} + +static struct acpi_device * +usb_acpi_find_companion_for_device(struct usb_device *udev) +{ + struct acpi_device *adev; + + if (!udev->parent) + return NULL; + + /* root hub is only child (_ADR=0) under its parent, the HC */ + adev = ACPI_COMPANION(udev->dev.parent); + return acpi_find_child_device(adev, 0, false); +} + + +static struct acpi_device *usb_acpi_find_companion(struct device *dev) +{ /* * In the ACPI DSDT table, only usb root hub and usb ports are * acpi device nodes. The hierarchy like following. @@ -158,66 +225,10 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev) * So all binding process is divided into two parts. binding * root hub and usb ports. */ - if (is_usb_device(dev)) { - udev = to_usb_device(dev); - if (udev->parent) - return NULL; - - /* root hub is only child (_ADR=0) under its parent, the HC */ - adev = ACPI_COMPANION(dev->parent); - return acpi_find_child_device(adev, 0, false); - } else if (is_usb_port(dev)) { - struct usb_port *port_dev = to_usb_port(dev); - int port1 = port_dev->portnum; - struct acpi_pld_info *pld; - acpi_handle *handle; - acpi_status status; - - /* Get the struct usb_device point of port's hub */ - udev = to_usb_device(dev->parent->parent); - - /* - * The root hub ports' parent is the root hub. The non-root-hub - * ports' parent is the parent hub port which the hub is - * connected to. - */ - if (!udev->parent) { - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - int raw; - - raw = usb_hcd_find_raw_port_number(hcd, port1); - - adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev), - raw); - - if (!adev) - return NULL; - } else { - parent_handle = - usb_get_hub_port_acpi_handle(udev->parent, - udev->portnum); - if (!parent_handle) - return NULL; - - acpi_bus_get_device(parent_handle, &adev); - - adev = usb_acpi_find_port(adev, port1); - - if (!adev) - return NULL; - } - handle = adev->handle; - status = acpi_get_physical_device_location(handle, &pld); - if (ACPI_FAILURE(status) || !pld) - return adev; - - port_dev->location = USB_ACPI_LOCATION_VALID - | pld->group_token << 8 | pld->group_position; - port_dev->connect_type = usb_acpi_get_connect_type(handle, pld); - ACPI_FREE(pld); - - return adev; - } + if (is_usb_device(dev)) + return usb_acpi_find_companion_for_device(to_usb_device(dev)); + else if (is_usb_port(dev)) + return usb_acpi_find_companion_for_port(to_usb_port(dev)); return NULL; } From patchwork Fri Jan 18 22:34:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1027815 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="jzPixTH7"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43hG2p3kcpz9sDL for ; Sat, 19 Jan 2019 09:34:26 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730085AbfARWeV (ORCPT ); Fri, 18 Jan 2019 17:34:21 -0500 Received: from mail-pf1-f201.google.com ([209.85.210.201]:44475 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730069AbfARWeV (ORCPT ); Fri, 18 Jan 2019 17:34:21 -0500 Received: by mail-pf1-f201.google.com with SMTP id b17so11128836pfc.11 for ; Fri, 18 Jan 2019 14:34:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5Vf/zxYwOeYnNWL3N0nFW9n1v8wnzmKf0NaeVZgXiaM=; b=jzPixTH7zJ1yIIX5bZzrUQThN590v6DWlfCKamohvLlKx5xj3PTGaNlXRFdk3O6anO mzvDL3vYXDynePF8uuET9rXYuf00lUdxjkTA7vdbPjEMTOo38mP+zEMUe6bMK7qVNww2 vapy/RgoUXYRI/Qi2zpUXc27WocMAQtoJxAwksTDgm7enmKfcwB0ciKFiY7lilL6doaT +29l3cZ4rfjw6YpRQz+TA6AVwOdXWOPY8LgScYw4iEp5qJHilmJ3ZwE+7ei5/GGjKz0c PBBRloe/D57GSfFJz22Ui/IYngZoDhuVRQjwwsGny6F3ZaPeJ2ItTxPzZ55XpXjse6sI TedA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5Vf/zxYwOeYnNWL3N0nFW9n1v8wnzmKf0NaeVZgXiaM=; b=tOHZ8QB0M1fl9rHWaa3y59vB3GbEdkIPAolkBmsoHTXlRHobI2TsSOMRj9gOGb6hmV 8Uv8vi9pDnp1rrLwUfj+ITcYaiNfro3Nks6AP596hyJcuxOv72lP1sws8+ylhXY78pJl vnnpqWMowA1mlYwJgCzO6axfU2W8V8zXjB+FZsm9VGl+4lGsX8d2XuPSQYVeV95yHuex zzCtQFtm6xxGBk1X0mEMlAGVwO8/mJamXKHbbRV7kQv+hpI8tDafqNtU22XvqZpyXimD VjpTbeRIXrUzigGDBSHb3XUkQ5SRS35+QQvRJT2OtqAdyQLfNcl8ehFfMno41iJp6HVU q63A== X-Gm-Message-State: AJcUukdT4kDSdrTMxKipJYB3UEcn3E3iPXAv2cPTPtrQ26t2rtbFsHUI Bo6jCqL7OJR/hGPdwWTtUgOc195jEroq X-Google-Smtp-Source: ALg8bN6thYeoMCSIyboFDVOgiChvDQtw39+2XeK8itXMoEr8A7Hmc4UB4lWL/ifImlNAu5t+wmuXpmEVFPNz X-Received: by 2002:a62:679d:: with SMTP id t29mr8166391pfj.90.1547850860134; Fri, 18 Jan 2019 14:34:20 -0800 (PST) Date: Fri, 18 Jan 2019 14:34:04 -0800 In-Reply-To: <20190118223407.64818-1-rajatja@google.com> Message-Id: <20190118223407.64818-2-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190118223407.64818-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v4 2/5] usb: assign ACPI companions for embedded USB devices From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Dmitry Torokhov USB devices permanently connected to USB ports may be described in ACPI tables and share ACPI devices with ports they are connected to. See [1] for details. This will allow us to describe sideband resources for devices, such as, for example, hard reset line for BT USB controllers. [1] https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/other-acpi-namespace-objects#acpi-namespace-hierarchy-and-adr-for-embedded-usb-devices Signed-off-by: Dmitry Torokhov Signed-off-by: Rajat Jain (changed how we get the usb_port) Acked-by: Greg Kroah-Hartman Tested-by: Sukumar Ghorai --- v4: Add Acked-by and Tested-by in signatures. v3: same as v1 v2: same as v1 drivers/usb/core/usb-acpi.c | 44 +++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index 8ff73c83e8e8..9043d7242d67 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -200,30 +200,56 @@ static struct acpi_device * usb_acpi_find_companion_for_device(struct usb_device *udev) { struct acpi_device *adev; + struct usb_port *port_dev; + struct usb_hub *hub; + + if (!udev->parent) { + /* root hub is only child (_ADR=0) under its parent, the HC */ + adev = ACPI_COMPANION(udev->dev.parent); + return acpi_find_child_device(adev, 0, false); + } - if (!udev->parent) + hub = usb_hub_to_struct_hub(udev->parent); + if (!hub) return NULL; - /* root hub is only child (_ADR=0) under its parent, the HC */ - adev = ACPI_COMPANION(udev->dev.parent); - return acpi_find_child_device(adev, 0, false); + /* + * This is an embedded USB device connected to a port and such + * devices share port's ACPI companion. + */ + port_dev = hub->ports[udev->portnum - 1]; + return usb_acpi_get_companion_for_port(port_dev); } - static struct acpi_device *usb_acpi_find_companion(struct device *dev) { /* - * In the ACPI DSDT table, only usb root hub and usb ports are - * acpi device nodes. The hierarchy like following. + * The USB hierarchy like following: + * * Device (EHC1) * Device (HUBN) * Device (PR01) * Device (PR11) * Device (PR12) + * Device (FN12) + * Device (FN13) * Device (PR13) * ... - * So all binding process is divided into two parts. binding - * root hub and usb ports. + * where HUBN is root hub, and PRNN are USB ports and devices + * connected to them, and FNNN are individualk functions for + * connected composite USB devices. PRNN and FNNN may contain + * _CRS and other methods describing sideband resources for + * the connected device. + * + * On the kernel side both root hub and embedded USB devices are + * represented as instances of usb_device structure, and ports + * are represented as usb_port structures, so the whole process + * is split into 2 parts: finding companions for devices and + * finding companions for ports. + * + * Note that we do not handle individual functions of composite + * devices yet, for that we would need to assign companions to + * devices corresponding to USB interfaces. */ if (is_usb_device(dev)) return usb_acpi_find_companion_for_device(to_usb_device(dev)); From patchwork Fri Jan 18 22:34:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1027816 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="SKBLVT+t"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43hG2v4SHZz9sDB for ; Sat, 19 Jan 2019 09:34:31 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730111AbfARWe0 (ORCPT ); Fri, 18 Jan 2019 17:34:26 -0500 Received: from mail-ua1-f73.google.com ([209.85.222.73]:53911 "EHLO mail-ua1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730099AbfARWeZ (ORCPT ); Fri, 18 Jan 2019 17:34:25 -0500 Received: by mail-ua1-f73.google.com with SMTP id d9so1073239uaq.20 for ; Fri, 18 Jan 2019 14:34:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=8MIi8gu7z+i/YfVXWgocUhpPLp3jAxogC5eMTHVicfw=; b=SKBLVT+tM+i4aFJrnO5hJGrV8iIRjBdcLFpH1h+nF74lBeSkijVZ7a/CY4b1XLBc2P M8InEFFF3r6BI7YFemEag2pyBoY2jNd6jRVgoS9iBYbU1R6t6IhJg1SjZMleyiHtLg60 mlDk9aILfGb/hLVc0k34bGsE2I8NuGnSaSt4ib2Z99Rl2u90hSbwWkL88QZxr0H1xZYH miVTsvzVSVI9WcxbS611j1Bz+QiaAkhf/k6IJLFZEgU9WCOJ+EMpSRSrIPCFntLhBqzI tmhEgInUooYMrARGPWQLdBvZ/YHzLr9TwmJC6GhUSkWI5LMRhxz7T5CAqIjy6/XNFosd kDqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8MIi8gu7z+i/YfVXWgocUhpPLp3jAxogC5eMTHVicfw=; b=qltOKU/NvZY4Fb0JE5u4s4MZn+ymk+5zJcAjV9v4uBoDg87yWVPCEiUgXkKqaoxtFx pAvdwkQkvfhrdoDepO1qkG04kZKuLjf4aFmnWbFscoUp9GejYoN811d88jgbts1WFqG0 7/3gbjs0kieA2Dwbmb/NXabJKhSrS8JUHzhICtzQzw/5sbOHVRHFbPbjOio22EFOKSUe d+Z4b8zH/1zcR6rnmhz6e7pu18q1usrzmesJ7+q82w19W6ibeGixQa+5zhD41f3oRNgS KRRAwY2vTS7p2/f+8SEyYPIxRFaCmDm9Hu8PilASF2h2d6o2mCtWsm5fIj4Eavm/07RB w/rw== X-Gm-Message-State: AJcUukdstjLWOx6Qn7UszvQQoGKSrlXZ9Gro4CLVvLpStF2Lg9EzY17V QD3y3T4xKit4ntqiyHmDcSImuJxmvDdA X-Google-Smtp-Source: ALg8bN41kTDqj7CBYC9jZrqyjwjFxAeP3fgMWQ/r20O74dWceCGbjiVpwhZuU45MatlNuNxOpe1z6B9oEsEl X-Received: by 2002:a67:7ac5:: with SMTP id v188mr15143415vsc.31.1547850864359; Fri, 18 Jan 2019 14:34:24 -0800 (PST) Date: Fri, 18 Jan 2019 14:34:05 -0800 In-Reply-To: <20190118223407.64818-1-rajatja@google.com> Message-Id: <20190118223407.64818-3-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190118223407.64818-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v4 3/5] Bluetooth: Reset Bluetooth chip after multiple command timeouts From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a quirk and a hook to allow the HCI core to reset the BT chip if needed (after a number of timed out commands). Use that new hook to initiate BT chip reset if the controller fails to respond to certain number of commands (currently 5) including the HCI reset commands. This is done based on a newly introduced quirk. This is done based on some initial work by Intel. Signed-off-by: Rajat Jain --- v4: same as v1 v3: same as v1 v2: same as v1 include/net/bluetooth/hci.h | 8 ++++++++ include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c36dc1e20556..af02fa5ffe54 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -192,6 +192,14 @@ enum { * */ HCI_QUIRK_NON_PERSISTENT_SETUP, + + /* When this quirk is set, hw_reset() would be run to reset the + * hardware, after a certain number of commands (currently 5) + * time out because the device fails to respond. + * + * This quirk should be set before hci_register_dev is called. + */ + HCI_QUIRK_HW_RESET_ON_TIMEOUT, }; /* HCI device flags */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e5ea633ea368..b86218304b80 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -313,6 +313,7 @@ struct hci_dev { unsigned int acl_cnt; unsigned int sco_cnt; unsigned int le_cnt; + unsigned int timeout_cnt; unsigned int acl_mtu; unsigned int sco_mtu; @@ -437,6 +438,7 @@ struct hci_dev { int (*post_init)(struct hci_dev *hdev); int (*set_diag)(struct hci_dev *hdev, bool enable); int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); + void (*hw_reset)(struct hci_dev *hdev); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7352fe85674b..ab3a6a8b7ba6 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2569,13 +2569,24 @@ static void hci_cmd_timeout(struct work_struct *work) struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_timer.work); + hdev->timeout_cnt++; if (hdev->sent_cmd) { struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; u16 opcode = __le16_to_cpu(sent->opcode); - bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); + bt_dev_err(hdev, "command 0x%4.4x tx timeout (cnt = %u)", + opcode, hdev->timeout_cnt); } else { - bt_dev_err(hdev, "command tx timeout"); + bt_dev_err(hdev, "command tx timeout (cnt = %u)", + hdev->timeout_cnt); + } + + if (test_bit(HCI_QUIRK_HW_RESET_ON_TIMEOUT, &hdev->quirks) && + hdev->timeout_cnt >= 5) { + hdev->timeout_cnt = 0; + if (hdev->hw_reset) + hdev->hw_reset(hdev); + return; } atomic_set(&hdev->cmd_cnt, 1); From patchwork Fri Jan 18 22:34:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1027819 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="RJQmUJee"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43hG3B2JDZz9sDB for ; Sat, 19 Jan 2019 09:34:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730140AbfARWeb (ORCPT ); Fri, 18 Jan 2019 17:34:31 -0500 Received: from mail-pg1-f201.google.com ([209.85.215.201]:51054 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730122AbfARWe2 (ORCPT ); Fri, 18 Jan 2019 17:34:28 -0500 Received: by mail-pg1-f201.google.com with SMTP id u17so9562119pgn.17 for ; Fri, 18 Jan 2019 14:34:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=MKDiLdJAGVcam6n/C88chFt5Uukxq2JbRfDsgfi2qfs=; b=RJQmUJeeVSxDNoQBGPZ/aXIwEaENyWhzVw2Y7x9D46/UGWDjU0UN9Oqr0CinUx/qTQ 7NkpqkMD+ZSO/5gkC0c1ToZ8zWQjw2fENP1Yp/u/rrW/wqyyHvFruC+AJiZgHYYlLIt/ rChRudiYfIUxqL5If/sJvySptpuumatRXBBe7glsyfFPbn+bnAxYwnkJK2Qxjb6RBlVt QYvZSSneR/n5b6rCfqz3Y5YlfNpJ3HyT0UQH/20jLMpHQYZ06tbkNSMHMfKJdaOTzmBw ehnLCOr6e8NmvzINoi71Dav346h5LPgqwCJgn54WGvYwA/AYkGP0JiMBhOS9bWMrraqJ jzUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=MKDiLdJAGVcam6n/C88chFt5Uukxq2JbRfDsgfi2qfs=; b=nJsiw3vEDXsVlRyLdTmoIPw9E4QhV2g2iBARq/esb0tPQOLEij4ql+G24LXeJl/y+o ASGhErvrLZ7B/0YxL92xGCNpxNhHzZOEsSQHT7cu1Y3HpAnAunsVSafgv44iJVIWTr8l oZ778YaE8+I/ehtxgau+hH0Ll/B11BCvVf9+CcKxBB8sAuiCzZxknPcQD3iecGsHk0IQ TjjL7WFJ+NHDc1gHQYo5xHLY5SC3HV9cqlHlShVAS3CetroyqMNcddus41SnZ+FqDCNb L2i/yd1JvsZBVqve+S/vvjx0BJHwnrsmPXZj6ABDleA80QVGDkvJCK0MWuNFscUdsqtI 16Lw== X-Gm-Message-State: AJcUukfrT1X/miaJlm+in8xwxPp1qjhoEy1IEj37GxDgV44tYj/YAnRM UlbY+fOp0CIa2hmfiFJPmP5+72yjYszi X-Google-Smtp-Source: ALg8bN4AN0FpDx7fPsGAHiXRpjkJPj+6LBlnXepeOfGKTGYwV8Lhxmbk8334sqb8W+QRfNpfoVe++kw3vpCi X-Received: by 2002:a17:902:1e6:: with SMTP id b93mr6878523plb.0.1547850867920; Fri, 18 Jan 2019 14:34:27 -0800 (PST) Date: Fri, 18 Jan 2019 14:34:06 -0800 In-Reply-To: <20190118223407.64818-1-rajatja@google.com> Message-Id: <20190118223407.64818-4-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190118223407.64818-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v4 4/5] Bluetooth: btusb: Collect the common Intel assignments together From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The BTUSB_INTEL and BTUSB_INTEL_NEW have common functions & quirks are assigned to hdev structure. Lets collect them together instead of repeating them in different code branches. Signed-off-by: Rajat Jain --- v4: same as v1 v3: same as v1 v2: same as v1 drivers/bluetooth/btusb.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4761499db9ee..59869643cc29 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3075,28 +3075,25 @@ static int btusb_probe(struct usb_interface *intf, data->diag = usb_ifnum_to_if(data->udev, ifnum_base + 2); } #endif + if (id->driver_info & BTUSB_INTEL || + id->driver_info & BTUSB_INTEL_NEW) { - if (id->driver_info & BTUSB_INTEL) { hdev->manufacturer = 2; - hdev->setup = btusb_setup_intel; - hdev->shutdown = btusb_shutdown_intel; - hdev->set_diag = btintel_set_diag_mfg; hdev->set_bdaddr = btintel_set_bdaddr; set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); - } - if (id->driver_info & BTUSB_INTEL_NEW) { - hdev->manufacturer = 2; - hdev->send = btusb_send_frame_intel; - hdev->setup = btusb_setup_intel_new; - hdev->hw_error = btintel_hw_error; - hdev->set_diag = btintel_set_diag; - hdev->set_bdaddr = btintel_set_bdaddr; - set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); - set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); - set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); + if (id->driver_info & BTUSB_INTEL) { + hdev->setup = btusb_setup_intel; + hdev->shutdown = btusb_shutdown_intel; + hdev->set_diag = btintel_set_diag_mfg; + } else { + hdev->send = btusb_send_frame_intel; + hdev->setup = btusb_setup_intel_new; + hdev->hw_error = btintel_hw_error; + hdev->set_diag = btintel_set_diag; + } } if (id->driver_info & BTUSB_MARVELL) From patchwork Fri Jan 18 22:34:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 1027817 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="CdP6rvC5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43hG3244k7z9sDP for ; Sat, 19 Jan 2019 09:34:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730166AbfARWed (ORCPT ); Fri, 18 Jan 2019 17:34:33 -0500 Received: from mail-pf1-f202.google.com ([209.85.210.202]:41512 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730150AbfARWec (ORCPT ); Fri, 18 Jan 2019 17:34:32 -0500 Received: by mail-pf1-f202.google.com with SMTP id 75so11137918pfq.8 for ; Fri, 18 Jan 2019 14:34:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=LMLCEs9eeENupsV+Qnkbn3fkJqGemwB3gZdICa3NJTI=; b=CdP6rvC57D5cKadS3QZvEqz1pK1Uom8r2ZvYtQUNDqrDbOaLuCKvX3T3KJfvLienlR HKXnKdnM+88vqOP7x+Qr1cQbYec75f6pdgL4BG25wwNBHgPIby4N6/vJ5hSZXE6mHiVs Hcvs3jKI4KeSM5dxF0SyixWQzed7NLyqPogCz2ILLYQzmUS7IOgIr+8gHCb0t3/L1Hoi QNNUpekCAXgsIXUdg3gpXd8c6p1K28XDcYlnvIs+VHPhlYw25vRsM6lIycxImUFq+NPt LRPHCg5cGE78u/OjeceuUq08snt2sHnqUR7seV1+hgB95RMa6613NACcOzKrtMMv3iTc YJ3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LMLCEs9eeENupsV+Qnkbn3fkJqGemwB3gZdICa3NJTI=; b=o1HlFLvXIoIGlAB24Cvm3QS+dbWh1Noy86OBTmRkZW4DNlSLGRhWNKuWn7v41+dYbu nx6PiosQOWxKFRT7RySIQJWBxhCNwcdHhCY41Ra9/WDhRPKbKta+Aobc8q5fsaGZtkh8 ur+1OeaoDyY8jgtYKVePA3PKjxRW/G4GsNCVuQFnVH30bo8rPw3wIsSqhtfqIXYazDDT Tmpw/rdzNJIwnDaRpEBUzQ8p2zsTL7IM59S3NaYqdD4O19Dmz4/7VhHhP1Vlrg0K6GtF DBxpMwzToF/6fWQSRagPrGvJPejcJuAAaZk0/J+SZXa/ILwXH62a1FSSkFU3W0l/ctPp M+uQ== X-Gm-Message-State: AJcUukeh55R0niYs5fy8svljN3MK5TgZMb8jn0/wgVzPGjwXCulPqU2+ UnoT9AUkgztutsCkJ+hmJ+wndBUIPZaR X-Google-Smtp-Source: ALg8bN6MY0FXSZn0u06boKX4s/6zkstoKWUT0mj8vgREyxFxTE8R2bh+mj2w5AE7044XJkqKVlaHGeSFN6SJ X-Received: by 2002:a17:902:8f95:: with SMTP id z21mr460293plo.99.1547850871247; Fri, 18 Jan 2019 14:34:31 -0800 (PST) Date: Fri, 18 Jan 2019 14:34:07 -0800 In-Reply-To: <20190118223407.64818-1-rajatja@google.com> Message-Id: <20190118223407.64818-5-rajatja@google.com> Mime-Version: 1.0 References: <20181117010748.24347-1-rajatja@google.com> <20190118223407.64818-1-rajatja@google.com> X-Mailer: git-send-email 2.20.1.321.g9e740568ce-goog Subject: [PATCH v4 5/5] Bluetooth: btusb: Use the hw_reset method to allow resetting the BT chip From: Rajat Jain To: Marcel Holtmann , Johan Hedberg , Greg Kroah-Hartman , "David S. Miller" , Dmitry Torokhov , Rajat Jain , Alex Hung , linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, netdev@vger.kernel.org Cc: rajatxjain@gmail.com, dtor@google.com, raghuram.hegde@intel.com, chethan.tumkur.narayan@intel.com, sukumar.ghorai@intel.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If the platform provides it, use the reset gpio to reset the BT chip (requested by the HCI core if needed). This has been found helpful on some of Intel bluetooth controllers where the firmware gets stuck and the only way out is a hard reset pin provided by the platform. Signed-off-by: Rajat Jain --- v4: Use data->flags instead of clearing the quirk in btusb_hw_reset() v3: Better error handling for gpiod_get_optional() v2: Handle the EPROBE_DEFER case. drivers/bluetooth/btusb.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 59869643cc29..7cf1e4f749e9 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -439,6 +440,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { #define BTUSB_BOOTING 9 #define BTUSB_DIAG_RUNNING 10 #define BTUSB_OOB_WAKE_ENABLED 11 +#define BTUSB_HW_RESET_DONE 12 struct btusb_data { struct hci_dev *hdev; @@ -476,6 +478,8 @@ struct btusb_data { struct usb_endpoint_descriptor *diag_tx_ep; struct usb_endpoint_descriptor *diag_rx_ep; + struct gpio_desc *reset_gpio; + __u8 cmdreq_type; __u8 cmdreq; @@ -491,6 +495,30 @@ struct btusb_data { int oob_wake_irq; /* irq for out-of-band wake-on-bt */ }; + +static void btusb_hw_reset(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct gpio_desc *reset_gpio = data->reset_gpio; + + /* + * Toggle the hard reset line if the platform provides one. The reset + * is going to yank the device off the USB and then replug. So doing + * once is enough. The cleanup is handled correctly on the way out + * (standard USB disconnect), and the new device is detected cleanly + * and bound to the driver again like it should be. + */ + if (test_and_set_bit(BTUSB_HW_RESET_DONE, &data->flags)) { + bt_dev_warn(hdev, "last reset failed? Not resetting again\n"); + return; + } + + bt_dev_dbg(hdev, "Initiating HW reset via gpio\n"); + gpiod_set_value(reset_gpio, 1); + mdelay(100); + gpiod_set_value(reset_gpio, 0); +} + static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -2915,6 +2943,7 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_endpoint_descriptor *ep_desc; + struct gpio_desc *reset_gpio; struct btusb_data *data; struct hci_dev *hdev; unsigned ifnum_base; @@ -3028,6 +3057,16 @@ static int btusb_probe(struct usb_interface *intf, SET_HCIDEV_DEV(hdev, &intf->dev); + reset_gpio = gpiod_get_optional(&data->udev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) { + err = PTR_ERR(reset_gpio); + goto out_free_dev; + } else if (reset_gpio) { + data->reset_gpio = reset_gpio; + hdev->hw_reset = btusb_hw_reset; + } + hdev->open = btusb_open; hdev->close = btusb_close; hdev->flush = btusb_flush; @@ -3083,6 +3122,7 @@ static int btusb_probe(struct usb_interface *intf, set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); + set_bit(HCI_QUIRK_HW_RESET_ON_TIMEOUT, &hdev->quirks); if (id->driver_info & BTUSB_INTEL) { hdev->setup = btusb_setup_intel; @@ -3223,6 +3263,8 @@ static int btusb_probe(struct usb_interface *intf, return 0; out_free_dev: + if (data->reset_gpio) + gpiod_put(data->reset_gpio); hci_free_dev(hdev); return err; } @@ -3266,6 +3308,9 @@ static void btusb_disconnect(struct usb_interface *intf) if (data->oob_wake_irq) device_init_wakeup(&data->udev->dev, false); + if (data->reset_gpio) + gpiod_put(data->reset_gpio); + hci_free_dev(hdev); }