From patchwork Tue Aug 2 09:19:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 654610 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s3Vz32DGdz9t1t for ; Tue, 2 Aug 2016 19:19:59 +1000 (AEST) Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3s3Vz31P5qzDqTC for ; Tue, 2 Aug 2016 19:19:59 +1000 (AEST) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3s3Vyx20tyzDqQ9 for ; Tue, 2 Aug 2016 19:19:53 +1000 (AEST) Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9F64C46203; Tue, 2 Aug 2016 09:19:51 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-30.ams2.redhat.com [10.36.116.30]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u729JiBJ022382; Tue, 2 Aug 2016 05:19:50 -0400 From: Thomas Huth To: slof@lists.ozlabs.org Date: Tue, 2 Aug 2016 11:19:42 +0200 Message-Id: <1470129584-27225-4-git-send-email-thuth@redhat.com> In-Reply-To: <1470129584-27225-1-git-send-email-thuth@redhat.com> References: <1470129584-27225-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 Aug 2016 09:19:51 +0000 (UTC) Subject: [SLOF] [PATCH v2 3/5] usb: Initialize USB3 devices on a hub and keep track of hub topology X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" USB3 devices need to be initialized with usb3_dev_init(), so that they get assigned a proper slot ID. And for USB3 devices that are attached to a (non-root) hub, we also need to keep track of the hub topology, so a new field called "hub" is added to the struct usb_dev which references the hub devices where the current USB devices is attached to. The hub topology will be used later to build the so-called "route string" for the USB3 devices. Signed-off-by: Thomas Huth Reviewed-by: Nikunj A Dadhania --- lib/libusb/usb-core.h | 1 + lib/libusb/usb-hub.c | 36 +++++++++++++++++++++++++++++------- lib/libusb/usb-xhci.c | 10 ++++++---- lib/libusb/usb-xhci.h | 3 +++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/libusb/usb-core.h b/lib/libusb/usb-core.h index a35df34..070aab5 100644 --- a/lib/libusb/usb-core.h +++ b/lib/libusb/usb-core.h @@ -79,6 +79,7 @@ enum USB_SPEED_TYPE { struct usb_dev { struct usb_dev *next; + struct usb_dev *hub; struct usb_hcd_dev *hcidev; struct usb_pipe *intr; struct usb_pipe *control; diff --git a/lib/libusb/usb-hub.c b/lib/libusb/usb-hub.c index bb8a309..5f56630 100644 --- a/lib/libusb/usb-hub.c +++ b/lib/libusb/usb-hub.c @@ -13,6 +13,7 @@ #include #include #include "usb-core.h" +#include "usb-xhci.h" #undef HUB_DEBUG //#define HUB_DEBUG @@ -151,11 +152,37 @@ static int hub_check_port(struct usb_dev *dev, int port) return false; } +static bool usb_hub_init_dev(struct usb_dev *hub_dev, int port) +{ + struct usb_dev *newdev; + + if (hub_dev->hcidev->type == USB_XHCI) { + /* + * USB3 devices need special setup (e.g. with assigning + * a slot ID and route string), which will all be done + * by usb3_dev_init() - it also calls usb_devpool_get(), + * usb_setup_new_device() and usb_slof_populate_new_device() + * internally, so we can return immediately after this step. + */ + return usb3_dev_init(hub_dev->hcidev->priv, hub_dev, port); + } + + newdev = usb_devpool_get(); + dprintf("usb-hub: allocated device %p\n", newdev); + newdev->hub = hub_dev; + newdev->hcidev = hub_dev->hcidev; + if (usb_setup_new_device(newdev, port)) { + usb_slof_populate_new_device(newdev); + return true; + } + + return false; +} + unsigned int usb_hub_init(void *hubdev) { struct usb_dev *dev = hubdev; struct usb_dev_hub_descr hub; - struct usb_dev *newdev; int i; dprintf("%s: enter %p\n", __func__, dev); @@ -172,12 +199,7 @@ unsigned int usb_hub_init(void *hubdev) dprintf("***********************************************\n"); dprintf("\t\tusb-hub: device found %d\n", i); dprintf("***********************************************\n"); - newdev = usb_devpool_get(); - dprintf("usb-hub: allocated device %p\n", newdev); - newdev->hcidev = dev->hcidev; - if (usb_setup_new_device(newdev, i)) - usb_slof_populate_new_device(newdev); - else + if (!usb_hub_init_dev(dev, i)) printf("usb-hub: unable to setup device on port %d\n", i); } } diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c index eda5929..2d34133 100644 --- a/lib/libusb/usb-xhci.c +++ b/lib/libusb/usb-xhci.c @@ -528,7 +528,8 @@ static uint32_t usb_control_max_packet(uint32_t speed) return max_packet; } -static bool xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t port) +static bool xhci_alloc_dev(struct xhci_hcd *xhcd, struct usb_dev *hub, + uint32_t slot_id, uint32_t port) { struct usb_dev *dev; struct xhci_dev *xdev; @@ -629,6 +630,7 @@ static bool xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t por dev->speed = USB_SUPER_SPEED; dev->addr = USB_DEV_ADDRESS(slot->field4); dev->port = newport; + dev->hub = hub; dev->priv = xdev; xdev->dev = dev; if (usb_setup_new_device(dev, newport)) { @@ -654,7 +656,7 @@ static void xhci_free_dev(struct xhci_dev *xdev) xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE); } -static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port) +bool usb3_dev_init(struct xhci_hcd *xhcd, struct usb_dev *hub, uint32_t port) { /* Device enable slot */ xhci_send_enable_slot(xhcd, port); @@ -663,7 +665,7 @@ static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port) return false; } dprintf("SLOT ID: %d\n", xhcd->slot_id); - if (!xhci_alloc_dev(xhcd, xhcd->slot_id, port)) { + if (!xhci_alloc_dev(xhcd, hub, xhcd->slot_id, port)) { dprintf("Unable to allocate device\n"); return false; } @@ -741,7 +743,7 @@ static int xhci_port_scan(struct xhci_hcd *xhcd, dprintf("Port reset complete %d\n", i); } print_port_status(prs); - if (!usb3_dev_init(xhcd, (i - (port_off - 1)))) { + if (!usb3_dev_init(xhcd, NULL, (i - (port_off - 1)))) { dprintf("USB device initialization failed\n"); } } diff --git a/lib/libusb/usb-xhci.h b/lib/libusb/usb-xhci.h index 793f18c..0fd2d8e 100644 --- a/lib/libusb/usb-xhci.h +++ b/lib/libusb/usb-xhci.h @@ -372,4 +372,7 @@ struct xhci_pipe { uint32_t buflen; }; +extern bool usb3_dev_init(struct xhci_hcd *xhcd, struct usb_dev *hub, + uint32_t port); + #endif /* USB_XHCI_H */