flash: Tidy up coding style for flash functions
[oweals/u-boot.git] / common / usb_hub.c
index bbb1155089644f24379c947ef86844dc16f5486a..c642b683e7ebc74dab4056001d8b2179265c68bb 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Most of this source has been derived from the Linux USB
  * project:
@@ -13,8 +14,6 @@
  *
  * Adapted for U-Boot:
  * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /****************************************************************************
@@ -25,7 +24,9 @@
 #include <common.h>
 #include <command.h>
 #include <dm.h>
+#include <env.h>
 #include <errno.h>
+#include <malloc.h>
 #include <memalign.h>
 #include <asm/processor.h>
 #include <asm/unaligned.h>
@@ -37,8 +38,6 @@
 #endif
 #include <asm/unaligned.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #include <usb.h>
 
 #define USB_BUFSIZ     512
@@ -57,7 +56,7 @@ struct usb_device_scan {
 
 static LIST_HEAD(usb_scan_list);
 
-__weak void usb_hub_reset_devices(int port)
+__weak void usb_hub_reset_devices(struct usb_hub_device *hub, int port)
 {
        return;
 }
@@ -67,7 +66,7 @@ static inline bool usb_hub_is_superspeed(struct usb_device *hdev)
        return hdev->descriptor.bDeviceProtocol == 3;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 bool usb_hub_is_root_hub(struct udevice *hub)
 {
        if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB)
@@ -128,7 +127,7 @@ int usb_get_port_status(struct usb_device *dev, int port, void *data)
                        USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
                        data, sizeof(struct usb_port_status), USB_CNTL_TIMEOUT);
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
        if (ret < 0)
                return ret;
 
@@ -189,7 +188,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
         * but allow this time to be increased via env variable as some
         * devices break the spec and require longer warm-up times
         */
-       env = getenv("usb_pgood_delay");
+       env = env_get("usb_pgood_delay");
        if (env)
                pgood_delay = max(pgood_delay,
                                  (unsigned)simple_strtol(env, NULL, 0));
@@ -212,7 +211,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
              max(100, (int)pgood_delay) + 1000);
 }
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
 static int usb_hub_index;
 
@@ -236,26 +235,18 @@ static struct usb_hub_device *usb_hub_allocate(void)
 
 #define MAX_TRIES 5
 
-static inline char *portspeed(int portstatus)
+static inline const char *portspeed(int portstatus)
 {
-       char *speed_str;
-
        switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
        case USB_PORT_STAT_SUPER_SPEED:
-               speed_str = "5 Gb/s";
-               break;
+               return "5 Gb/s";
        case USB_PORT_STAT_HIGH_SPEED:
-               speed_str = "480 Mb/s";
-               break;
+               return "480 Mb/s";
        case USB_PORT_STAT_LOW_SPEED:
-               speed_str = "1.5 Mb/s";
-               break;
+               return "1.5 Mb/s";
        default:
-               speed_str = "12 Mb/s";
-               break;
+               return "12 Mb/s";
        }
-
-       return speed_str;
 }
 
 /**
@@ -276,7 +267,7 @@ static int usb_hub_port_reset(struct usb_device *dev, int port,
        unsigned short portstatus, portchange;
        int delay = HUB_SHORT_RESET_TIME; /* start with short reset delay */
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
        debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name,
              port + 1);
 #else
@@ -397,7 +388,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
                break;
        }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
        struct udevice *child;
 
        ret = usb_scan_device(dev->dev, port + 1, speed, &child);
@@ -489,6 +480,17 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
                return 0;
        }
 
+       if (portchange & USB_PORT_STAT_C_RESET) {
+               debug("port %d reset change\n", i + 1);
+               usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
+       }
+
+       if ((portchange & USB_SS_PORT_STAT_C_BH_RESET) &&
+           usb_hub_is_superspeed(dev)) {
+               debug("port %d BH reset change\n", i + 1);
+               usb_clear_port_feature(dev, i + 1, USB_SS_PORT_FEAT_C_BH_RESET);
+       }
+
        /* A new USB device is ready at this point */
        debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);
 
@@ -543,11 +545,6 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
                       hub->overcurrent_count[i]);
        }
 
-       if (portchange & USB_PORT_STAT_C_RESET) {
-               debug("port %d reset change\n", i + 1);
-               usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
-       }
-
        /*
         * We're done with this device, so let's remove this device from
         * scanning list
@@ -601,7 +598,7 @@ static struct usb_hub_device *usb_get_hub_device(struct usb_device *dev)
 {
        struct usb_hub_device *hub;
 
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
        /* "allocate" Hub device */
        hub = usb_hub_allocate();
 #else
@@ -619,7 +616,7 @@ static int usb_hub_configure(struct usb_device *dev)
        short hubCharacteristics;
        struct usb_hub_descriptor *descriptor;
        struct usb_hub_device *hub;
-       __maybe_unused struct usb_hub_status *hubsts;
+       struct usb_hub_status *hubsts;
        int ret;
 
        hub = usb_get_hub_device(dev);
@@ -773,9 +770,7 @@ static int usb_hub_configure(struct usb_device *dev)
                return ret;
        }
 
-#ifdef DEBUG
        hubsts = (struct usb_hub_status *)buffer;
-#endif
 
        debug("get_hub_status returned status %X, change %X\n",
              le16_to_cpu(hubsts->wHubStatus),
@@ -787,7 +782,18 @@ static int usb_hub_configure(struct usb_device *dev)
              (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
              "" : "no ");
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
+       /*
+        * Update USB host controller's internal representation of this hub
+        * after the hub descriptor is fetched.
+        */
+       ret = usb_update_hub_device(dev);
+       if (ret < 0 && ret != -ENOSYS) {
+               debug("%s: failed to update hub device for HCD (%x)\n",
+                     __func__, ret);
+               return ret;
+       }
+
        /*
         * A maximum of seven tiers are allowed in a USB topology, and the
         * root hub occupies the first tier. The last tier ends with a normal
@@ -836,7 +842,7 @@ static int usb_hub_configure(struct usb_device *dev)
         * should occur in the board file of the device.
         */
        for (i = 0; i < dev->maxchild; i++)
-               usb_hub_reset_devices(i + 1);
+               usb_hub_reset_devices(hub, i + 1);
 
        /*
         * Only add the connected USB devices, including potential hubs,
@@ -918,7 +924,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
        return ret;
 }
 
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
 int usb_hub_scan(struct udevice *hub)
 {
        struct usb_device *udev = dev_get_parent_priv(hub);