LCOV - code coverage report
Current view: top level - drivers/usb/core - port.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 229 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 17 0.0 %
Branches: 0 132 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * usb port device code
       4                 :            :  *
       5                 :            :  * Copyright (C) 2012 Intel Corp
       6                 :            :  *
       7                 :            :  * Author: Lan Tianyu <tianyu.lan@intel.com>
       8                 :            :  */
       9                 :            : 
      10                 :            : #include <linux/slab.h>
      11                 :            : #include <linux/pm_qos.h>
      12                 :            : 
      13                 :            : #include "hub.h"
      14                 :            : 
      15                 :            : static int usb_port_block_power_off;
      16                 :            : 
      17                 :            : static const struct attribute_group *port_dev_group[];
      18                 :            : 
      19                 :          0 : static ssize_t location_show(struct device *dev,
      20                 :            :                              struct device_attribute *attr, char *buf)
      21                 :            : {
      22                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      23                 :            : 
      24                 :          0 :         return sprintf(buf, "0x%08x\n", port_dev->location);
      25                 :            : }
      26                 :            : static DEVICE_ATTR_RO(location);
      27                 :            : 
      28                 :          0 : static ssize_t connect_type_show(struct device *dev,
      29                 :            :                                  struct device_attribute *attr, char *buf)
      30                 :            : {
      31                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      32                 :          0 :         char *result;
      33                 :            : 
      34         [ #  # ]:          0 :         switch (port_dev->connect_type) {
      35                 :            :         case USB_PORT_CONNECT_TYPE_HOT_PLUG:
      36                 :            :                 result = "hotplug";
      37                 :            :                 break;
      38                 :            :         case USB_PORT_CONNECT_TYPE_HARD_WIRED:
      39                 :            :                 result = "hardwired";
      40                 :            :                 break;
      41                 :            :         case USB_PORT_NOT_USED:
      42                 :            :                 result = "not used";
      43                 :            :                 break;
      44                 :            :         default:
      45                 :            :                 result = "unknown";
      46                 :            :                 break;
      47                 :            :         }
      48                 :            : 
      49                 :          0 :         return sprintf(buf, "%s\n", result);
      50                 :            : }
      51                 :            : static DEVICE_ATTR_RO(connect_type);
      52                 :            : 
      53                 :          0 : static ssize_t over_current_count_show(struct device *dev,
      54                 :            :                                        struct device_attribute *attr, char *buf)
      55                 :            : {
      56                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      57                 :            : 
      58                 :          0 :         return sprintf(buf, "%u\n", port_dev->over_current_count);
      59                 :            : }
      60                 :            : static DEVICE_ATTR_RO(over_current_count);
      61                 :            : 
      62                 :          0 : static ssize_t quirks_show(struct device *dev,
      63                 :            :                            struct device_attribute *attr, char *buf)
      64                 :            : {
      65                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      66                 :            : 
      67                 :          0 :         return sprintf(buf, "%08x\n", port_dev->quirks);
      68                 :            : }
      69                 :            : 
      70                 :          0 : static ssize_t quirks_store(struct device *dev, struct device_attribute *attr,
      71                 :            :                             const char *buf, size_t count)
      72                 :            : {
      73                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      74                 :          0 :         u32 value;
      75                 :            : 
      76         [ #  # ]:          0 :         if (kstrtou32(buf, 16, &value))
      77                 :            :                 return -EINVAL;
      78                 :            : 
      79                 :          0 :         port_dev->quirks = value;
      80                 :          0 :         return count;
      81                 :            : }
      82                 :            : static DEVICE_ATTR_RW(quirks);
      83                 :            : 
      84                 :          0 : static ssize_t usb3_lpm_permit_show(struct device *dev,
      85                 :            :                               struct device_attribute *attr, char *buf)
      86                 :            : {
      87                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
      88                 :          0 :         const char *p;
      89                 :            : 
      90         [ #  # ]:          0 :         if (port_dev->usb3_lpm_u1_permit) {
      91         [ #  # ]:          0 :                 if (port_dev->usb3_lpm_u2_permit)
      92                 :            :                         p = "u1_u2";
      93                 :            :                 else
      94                 :          0 :                         p = "u1";
      95                 :            :         } else {
      96         [ #  # ]:          0 :                 if (port_dev->usb3_lpm_u2_permit)
      97                 :            :                         p = "u2";
      98                 :            :                 else
      99                 :          0 :                         p = "0";
     100                 :            :         }
     101                 :            : 
     102                 :          0 :         return sprintf(buf, "%s\n", p);
     103                 :            : }
     104                 :            : 
     105                 :          0 : static ssize_t usb3_lpm_permit_store(struct device *dev,
     106                 :            :                                struct device_attribute *attr,
     107                 :            :                                const char *buf, size_t count)
     108                 :            : {
     109                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
     110                 :          0 :         struct usb_device *udev = port_dev->child;
     111                 :          0 :         struct usb_hcd *hcd;
     112                 :            : 
     113         [ #  # ]:          0 :         if (!strncmp(buf, "u1_u2", 5)) {
     114                 :          0 :                 port_dev->usb3_lpm_u1_permit = 1;
     115                 :          0 :                 port_dev->usb3_lpm_u2_permit = 1;
     116                 :            : 
     117         [ #  # ]:          0 :         } else if (!strncmp(buf, "u1", 2)) {
     118                 :          0 :                 port_dev->usb3_lpm_u1_permit = 1;
     119                 :          0 :                 port_dev->usb3_lpm_u2_permit = 0;
     120                 :            : 
     121         [ #  # ]:          0 :         } else if (!strncmp(buf, "u2", 2)) {
     122                 :          0 :                 port_dev->usb3_lpm_u1_permit = 0;
     123                 :          0 :                 port_dev->usb3_lpm_u2_permit = 1;
     124                 :            : 
     125         [ #  # ]:          0 :         } else if (!strncmp(buf, "0", 1)) {
     126                 :          0 :                 port_dev->usb3_lpm_u1_permit = 0;
     127                 :          0 :                 port_dev->usb3_lpm_u2_permit = 0;
     128                 :            :         } else
     129                 :            :                 return -EINVAL;
     130                 :            : 
     131                 :            :         /* If device is connected to the port, disable or enable lpm
     132                 :            :          * to make new u1 u2 setting take effect immediately.
     133                 :            :          */
     134         [ #  # ]:          0 :         if (udev) {
     135         [ #  # ]:          0 :                 hcd = bus_to_hcd(udev->bus);
     136         [ #  # ]:          0 :                 if (!hcd)
     137                 :            :                         return -EINVAL;
     138                 :          0 :                 usb_lock_device(udev);
     139                 :          0 :                 mutex_lock(hcd->bandwidth_mutex);
     140         [ #  # ]:          0 :                 if (!usb_disable_lpm(udev))
     141                 :          0 :                         usb_enable_lpm(udev);
     142                 :          0 :                 mutex_unlock(hcd->bandwidth_mutex);
     143                 :          0 :                 usb_unlock_device(udev);
     144                 :            :         }
     145                 :            : 
     146                 :          0 :         return count;
     147                 :            : }
     148                 :            : static DEVICE_ATTR_RW(usb3_lpm_permit);
     149                 :            : 
     150                 :            : static struct attribute *port_dev_attrs[] = {
     151                 :            :         &dev_attr_connect_type.attr,
     152                 :            :         &dev_attr_location.attr,
     153                 :            :         &dev_attr_quirks.attr,
     154                 :            :         &dev_attr_over_current_count.attr,
     155                 :            :         NULL,
     156                 :            : };
     157                 :            : 
     158                 :            : static struct attribute_group port_dev_attr_grp = {
     159                 :            :         .attrs = port_dev_attrs,
     160                 :            : };
     161                 :            : 
     162                 :            : static const struct attribute_group *port_dev_group[] = {
     163                 :            :         &port_dev_attr_grp,
     164                 :            :         NULL,
     165                 :            : };
     166                 :            : 
     167                 :            : static struct attribute *port_dev_usb3_attrs[] = {
     168                 :            :         &dev_attr_usb3_lpm_permit.attr,
     169                 :            :         NULL,
     170                 :            : };
     171                 :            : 
     172                 :            : static struct attribute_group port_dev_usb3_attr_grp = {
     173                 :            :         .attrs = port_dev_usb3_attrs,
     174                 :            : };
     175                 :            : 
     176                 :            : static const struct attribute_group *port_dev_usb3_group[] = {
     177                 :            :         &port_dev_attr_grp,
     178                 :            :         &port_dev_usb3_attr_grp,
     179                 :            :         NULL,
     180                 :            : };
     181                 :            : 
     182                 :          0 : static void usb_port_device_release(struct device *dev)
     183                 :            : {
     184                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
     185                 :            : 
     186                 :          0 :         kfree(port_dev->req);
     187                 :          0 :         kfree(port_dev);
     188                 :          0 : }
     189                 :            : 
     190                 :            : #ifdef CONFIG_PM
     191                 :          0 : static int usb_port_runtime_resume(struct device *dev)
     192                 :            : {
     193                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
     194                 :          0 :         struct usb_device *hdev = to_usb_device(dev->parent->parent);
     195                 :          0 :         struct usb_interface *intf = to_usb_interface(dev->parent);
     196                 :          0 :         struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
     197                 :          0 :         struct usb_device *udev = port_dev->child;
     198                 :          0 :         struct usb_port *peer = port_dev->peer;
     199                 :          0 :         int port1 = port_dev->portnum;
     200                 :          0 :         int retval;
     201                 :            : 
     202         [ #  # ]:          0 :         if (!hub)
     203                 :            :                 return -EINVAL;
     204         [ #  # ]:          0 :         if (hub->in_reset) {
     205                 :          0 :                 set_bit(port1, hub->power_bits);
     206                 :          0 :                 return 0;
     207                 :            :         }
     208                 :            : 
     209                 :            :         /*
     210                 :            :          * Power on our usb3 peer before this usb2 port to prevent a usb3
     211                 :            :          * device from degrading to its usb2 connection
     212                 :            :          */
     213   [ #  #  #  # ]:          0 :         if (!port_dev->is_superspeed && peer)
     214                 :          0 :                 pm_runtime_get_sync(&peer->dev);
     215                 :            : 
     216                 :          0 :         retval = usb_autopm_get_interface(intf);
     217         [ #  # ]:          0 :         if (retval < 0)
     218                 :            :                 return retval;
     219                 :            : 
     220                 :          0 :         retval = usb_hub_set_port_power(hdev, hub, port1, true);
     221                 :          0 :         msleep(hub_power_on_good_delay(hub));
     222         [ #  # ]:          0 :         if (udev && !retval) {
     223                 :            :                 /*
     224                 :            :                  * Our preference is to simply wait for the port to reconnect,
     225                 :            :                  * as that is the lowest latency method to restart the port.
     226                 :            :                  * However, there are cases where toggling port power results in
     227                 :            :                  * the host port and the device port getting out of sync causing
     228                 :            :                  * a link training live lock.  Upon timeout, flag the port as
     229                 :            :                  * needing warm reset recovery (to be performed later by
     230                 :            :                  * usb_port_resume() as requested via usb_wakeup_notification())
     231                 :            :                  */
     232         [ #  # ]:          0 :                 if (hub_port_debounce_be_connected(hub, port1) < 0) {
     233                 :          0 :                         dev_dbg(&port_dev->dev, "reconnect timeout\n");
     234         [ #  # ]:          0 :                         if (hub_is_superspeed(hdev))
     235                 :          0 :                                 set_bit(port1, hub->warm_reset_bits);
     236                 :            :                 }
     237                 :            : 
     238                 :            :                 /* Force the child awake to revalidate after the power loss. */
     239         [ #  # ]:          0 :                 if (!test_and_set_bit(port1, hub->child_usage_bits)) {
     240                 :          0 :                         pm_runtime_get_noresume(&port_dev->dev);
     241                 :          0 :                         pm_request_resume(&udev->dev);
     242                 :            :                 }
     243                 :            :         }
     244                 :            : 
     245                 :          0 :         usb_autopm_put_interface(intf);
     246                 :            : 
     247                 :          0 :         return retval;
     248                 :            : }
     249                 :            : 
     250                 :          0 : static int usb_port_runtime_suspend(struct device *dev)
     251                 :            : {
     252                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
     253                 :          0 :         struct usb_device *hdev = to_usb_device(dev->parent->parent);
     254                 :          0 :         struct usb_interface *intf = to_usb_interface(dev->parent);
     255                 :          0 :         struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
     256                 :          0 :         struct usb_port *peer = port_dev->peer;
     257                 :          0 :         int port1 = port_dev->portnum;
     258                 :          0 :         int retval;
     259                 :            : 
     260         [ #  # ]:          0 :         if (!hub)
     261                 :            :                 return -EINVAL;
     262         [ #  # ]:          0 :         if (hub->in_reset)
     263                 :            :                 return -EBUSY;
     264                 :            : 
     265         [ #  # ]:          0 :         if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF)
     266                 :            :                         == PM_QOS_FLAGS_ALL)
     267                 :            :                 return -EAGAIN;
     268                 :            : 
     269         [ #  # ]:          0 :         if (usb_port_block_power_off)
     270                 :            :                 return -EBUSY;
     271                 :            : 
     272                 :          0 :         retval = usb_autopm_get_interface(intf);
     273         [ #  # ]:          0 :         if (retval < 0)
     274                 :            :                 return retval;
     275                 :            : 
     276                 :          0 :         retval = usb_hub_set_port_power(hdev, hub, port1, false);
     277                 :          0 :         usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
     278         [ #  # ]:          0 :         if (!port_dev->is_superspeed)
     279                 :          0 :                 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
     280                 :          0 :         usb_autopm_put_interface(intf);
     281                 :            : 
     282                 :            :         /*
     283                 :            :          * Our peer usb3 port may now be able to suspend, so
     284                 :            :          * asynchronously queue a suspend request to observe that this
     285                 :            :          * usb2 port is now off.
     286                 :            :          */
     287   [ #  #  #  # ]:          0 :         if (!port_dev->is_superspeed && peer)
     288                 :          0 :                 pm_runtime_put(&peer->dev);
     289                 :            : 
     290                 :            :         return retval;
     291                 :            : }
     292                 :            : #endif
     293                 :            : 
     294                 :          0 : static void usb_port_shutdown(struct device *dev)
     295                 :            : {
     296                 :          0 :         struct usb_port *port_dev = to_usb_port(dev);
     297                 :            : 
     298         [ #  # ]:          0 :         if (port_dev->child)
     299                 :          0 :                 usb_disable_usb2_hardware_lpm(port_dev->child);
     300                 :          0 : }
     301                 :            : 
     302                 :            : static const struct dev_pm_ops usb_port_pm_ops = {
     303                 :            : #ifdef CONFIG_PM
     304                 :            :         .runtime_suspend =      usb_port_runtime_suspend,
     305                 :            :         .runtime_resume =       usb_port_runtime_resume,
     306                 :            : #endif
     307                 :            : };
     308                 :            : 
     309                 :            : struct device_type usb_port_device_type = {
     310                 :            :         .name =         "usb_port",
     311                 :            :         .release =      usb_port_device_release,
     312                 :            :         .pm =           &usb_port_pm_ops,
     313                 :            : };
     314                 :            : 
     315                 :            : static struct device_driver usb_port_driver = {
     316                 :            :         .name = "usb",
     317                 :            :         .owner = THIS_MODULE,
     318                 :            :         .shutdown = usb_port_shutdown,
     319                 :            : };
     320                 :            : 
     321                 :          0 : static int link_peers(struct usb_port *left, struct usb_port *right)
     322                 :            : {
     323                 :          0 :         struct usb_port *ss_port, *hs_port;
     324                 :          0 :         int rc;
     325                 :            : 
     326   [ #  #  #  # ]:          0 :         if (left->peer == right && right->peer == left)
     327                 :            :                 return 0;
     328                 :            : 
     329   [ #  #  #  # ]:          0 :         if (left->peer || right->peer) {
     330                 :            :                 struct usb_port *lpeer = left->peer;
     331                 :            :                 struct usb_port *rpeer = right->peer;
     332                 :            :                 char *method;
     333                 :            : 
     334                 :            :                 if (left->location && left->location == right->location)
     335                 :            :                         method = "location";
     336                 :            :                 else
     337                 :            :                         method = "default";
     338                 :            : 
     339                 :            :                 pr_debug("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
     340                 :            :                         dev_name(&left->dev), dev_name(&right->dev), method,
     341                 :            :                         dev_name(&left->dev),
     342                 :            :                         lpeer ? dev_name(&lpeer->dev) : "none",
     343                 :            :                         dev_name(&right->dev),
     344                 :            :                         rpeer ? dev_name(&rpeer->dev) : "none");
     345                 :            :                 return -EBUSY;
     346                 :            :         }
     347                 :            : 
     348                 :          0 :         rc = sysfs_create_link(&left->dev.kobj, &right->dev.kobj, "peer");
     349         [ #  # ]:          0 :         if (rc)
     350                 :            :                 return rc;
     351                 :          0 :         rc = sysfs_create_link(&right->dev.kobj, &left->dev.kobj, "peer");
     352         [ #  # ]:          0 :         if (rc) {
     353                 :          0 :                 sysfs_remove_link(&left->dev.kobj, "peer");
     354                 :          0 :                 return rc;
     355                 :            :         }
     356                 :            : 
     357                 :            :         /*
     358                 :            :          * We need to wake the HiSpeed port to make sure we don't race
     359                 :            :          * setting ->peer with usb_port_runtime_suspend().  Otherwise we
     360                 :            :          * may miss a suspend event for the SuperSpeed port.
     361                 :            :          */
     362         [ #  # ]:          0 :         if (left->is_superspeed) {
     363                 :          0 :                 ss_port = left;
     364         [ #  # ]:          0 :                 WARN_ON(right->is_superspeed);
     365                 :            :                 hs_port = right;
     366                 :            :         } else {
     367                 :          0 :                 ss_port = right;
     368         [ #  # ]:          0 :                 WARN_ON(!right->is_superspeed);
     369                 :            :                 hs_port = left;
     370                 :            :         }
     371                 :          0 :         pm_runtime_get_sync(&hs_port->dev);
     372                 :            : 
     373                 :          0 :         left->peer = right;
     374                 :          0 :         right->peer = left;
     375                 :            : 
     376                 :            :         /*
     377                 :            :          * The SuperSpeed reference is dropped when the HiSpeed port in
     378                 :            :          * this relationship suspends, i.e. when it is safe to allow a
     379                 :            :          * SuperSpeed connection to drop since there is no risk of a
     380                 :            :          * device degrading to its powered-off HiSpeed connection.
     381                 :            :          *
     382                 :            :          * Also, drop the HiSpeed ref taken above.
     383                 :            :          */
     384                 :          0 :         pm_runtime_get_sync(&ss_port->dev);
     385                 :          0 :         pm_runtime_put(&hs_port->dev);
     386                 :            : 
     387                 :          0 :         return 0;
     388                 :            : }
     389                 :            : 
     390                 :          0 : static void link_peers_report(struct usb_port *left, struct usb_port *right)
     391                 :            : {
     392                 :          0 :         int rc;
     393                 :            : 
     394                 :          0 :         rc = link_peers(left, right);
     395         [ #  # ]:          0 :         if (rc == 0) {
     396                 :            :                 dev_dbg(&left->dev, "peered to %s\n", dev_name(&right->dev));
     397                 :            :         } else {
     398                 :          0 :                 dev_dbg(&left->dev, "failed to peer to %s (%d)\n",
     399                 :            :                                 dev_name(&right->dev), rc);
     400         [ #  # ]:          0 :                 pr_warn_once("usb: port power management may be unreliable\n");
     401                 :          0 :                 usb_port_block_power_off = 1;
     402                 :            :         }
     403                 :          0 : }
     404                 :            : 
     405                 :          0 : static void unlink_peers(struct usb_port *left, struct usb_port *right)
     406                 :            : {
     407                 :          0 :         struct usb_port *ss_port, *hs_port;
     408                 :            : 
     409   [ #  #  #  #  :          0 :         WARN(right->peer != left || left->peer != right,
             #  #  #  # ]
     410                 :            :                         "%s and %s are not peers?\n",
     411                 :            :                         dev_name(&left->dev), dev_name(&right->dev));
     412                 :            : 
     413                 :            :         /*
     414                 :            :          * We wake the HiSpeed port to make sure we don't race its
     415                 :            :          * usb_port_runtime_resume() event which takes a SuperSpeed ref
     416                 :            :          * when ->peer is !NULL.
     417                 :            :          */
     418         [ #  # ]:          0 :         if (left->is_superspeed) {
     419                 :            :                 ss_port = left;
     420                 :            :                 hs_port = right;
     421                 :            :         } else {
     422                 :          0 :                 ss_port = right;
     423                 :          0 :                 hs_port = left;
     424                 :            :         }
     425                 :            : 
     426                 :          0 :         pm_runtime_get_sync(&hs_port->dev);
     427                 :            : 
     428                 :          0 :         sysfs_remove_link(&left->dev.kobj, "peer");
     429                 :          0 :         right->peer = NULL;
     430                 :          0 :         sysfs_remove_link(&right->dev.kobj, "peer");
     431                 :          0 :         left->peer = NULL;
     432                 :            : 
     433                 :            :         /* Drop the SuperSpeed ref held on behalf of the active HiSpeed port */
     434                 :          0 :         pm_runtime_put(&ss_port->dev);
     435                 :            : 
     436                 :            :         /* Drop the ref taken above */
     437                 :          0 :         pm_runtime_put(&hs_port->dev);
     438                 :          0 : }
     439                 :            : 
     440                 :            : /*
     441                 :            :  * For each usb hub device in the system check to see if it is in the
     442                 :            :  * peer domain of the given port_dev, and if it is check to see if it
     443                 :            :  * has a port that matches the given port by location
     444                 :            :  */
     445                 :          0 : static int match_location(struct usb_device *peer_hdev, void *p)
     446                 :            : {
     447                 :          0 :         int port1;
     448                 :          0 :         struct usb_hcd *hcd, *peer_hcd;
     449                 :          0 :         struct usb_port *port_dev = p, *peer;
     450                 :          0 :         struct usb_hub *peer_hub = usb_hub_to_struct_hub(peer_hdev);
     451                 :          0 :         struct usb_device *hdev = to_usb_device(port_dev->dev.parent->parent);
     452                 :            : 
     453         [ #  # ]:          0 :         if (!peer_hub)
     454                 :            :                 return 0;
     455                 :            : 
     456         [ #  # ]:          0 :         hcd = bus_to_hcd(hdev->bus);
     457                 :          0 :         peer_hcd = bus_to_hcd(peer_hdev->bus);
     458                 :            :         /* peer_hcd is provisional until we verify it against the known peer */
     459         [ #  # ]:          0 :         if (peer_hcd != hcd->shared_hcd)
     460                 :            :                 return 0;
     461                 :            : 
     462         [ #  # ]:          0 :         for (port1 = 1; port1 <= peer_hdev->maxchild; port1++) {
     463                 :          0 :                 peer = peer_hub->ports[port1 - 1];
     464   [ #  #  #  # ]:          0 :                 if (peer && peer->location == port_dev->location) {
     465                 :          0 :                         link_peers_report(port_dev, peer);
     466                 :          0 :                         return 1; /* done */
     467                 :            :                 }
     468                 :            :         }
     469                 :            : 
     470                 :            :         return 0;
     471                 :            : }
     472                 :            : 
     473                 :            : /*
     474                 :            :  * Find the peer port either via explicit platform firmware "location"
     475                 :            :  * data, the peer hcd for root hubs, or the upstream peer relationship
     476                 :            :  * for all other hubs.
     477                 :            :  */
     478                 :            : static void find_and_link_peer(struct usb_hub *hub, int port1)
     479                 :            : {
     480                 :            :         struct usb_port *port_dev = hub->ports[port1 - 1], *peer;
     481                 :            :         struct usb_device *hdev = hub->hdev;
     482                 :            :         struct usb_device *peer_hdev;
     483                 :            :         struct usb_hub *peer_hub;
     484                 :            : 
     485                 :            :         /*
     486                 :            :          * If location data is available then we can only peer this port
     487                 :            :          * by a location match, not the default peer (lest we create a
     488                 :            :          * situation where we need to go back and undo a default peering
     489                 :            :          * when the port is later peered by location data)
     490                 :            :          */
     491                 :            :         if (port_dev->location) {
     492                 :            :                 /* we link the peer in match_location() if found */
     493                 :            :                 usb_for_each_dev(port_dev, match_location);
     494                 :            :                 return;
     495                 :            :         } else if (!hdev->parent) {
     496                 :            :                 struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
     497                 :            :                 struct usb_hcd *peer_hcd = hcd->shared_hcd;
     498                 :            : 
     499                 :            :                 if (!peer_hcd)
     500                 :            :                         return;
     501                 :            : 
     502                 :            :                 peer_hdev = peer_hcd->self.root_hub;
     503                 :            :         } else {
     504                 :            :                 struct usb_port *upstream;
     505                 :            :                 struct usb_device *parent = hdev->parent;
     506                 :            :                 struct usb_hub *parent_hub = usb_hub_to_struct_hub(parent);
     507                 :            : 
     508                 :            :                 if (!parent_hub)
     509                 :            :                         return;
     510                 :            : 
     511                 :            :                 upstream = parent_hub->ports[hdev->portnum - 1];
     512                 :            :                 if (!upstream || !upstream->peer)
     513                 :            :                         return;
     514                 :            : 
     515                 :            :                 peer_hdev = upstream->peer->child;
     516                 :            :         }
     517                 :            : 
     518                 :            :         peer_hub = usb_hub_to_struct_hub(peer_hdev);
     519                 :            :         if (!peer_hub || port1 > peer_hdev->maxchild)
     520                 :            :                 return;
     521                 :            : 
     522                 :            :         /*
     523                 :            :          * we found a valid default peer, last check is to make sure it
     524                 :            :          * does not have location data
     525                 :            :          */
     526                 :            :         peer = peer_hub->ports[port1 - 1];
     527                 :            :         if (peer && peer->location == 0)
     528                 :            :                 link_peers_report(port_dev, peer);
     529                 :            : }
     530                 :            : 
     531                 :          0 : int usb_hub_create_port_device(struct usb_hub *hub, int port1)
     532                 :            : {
     533                 :          0 :         struct usb_port *port_dev;
     534                 :          0 :         struct usb_device *hdev = hub->hdev;
     535                 :          0 :         int retval;
     536                 :            : 
     537                 :          0 :         port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
     538         [ #  # ]:          0 :         if (!port_dev)
     539                 :            :                 return -ENOMEM;
     540                 :            : 
     541                 :          0 :         port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL);
     542         [ #  # ]:          0 :         if (!port_dev->req) {
     543                 :          0 :                 kfree(port_dev);
     544                 :          0 :                 return -ENOMEM;
     545                 :            :         }
     546                 :            : 
     547                 :          0 :         hub->ports[port1 - 1] = port_dev;
     548                 :          0 :         port_dev->portnum = port1;
     549                 :          0 :         set_bit(port1, hub->power_bits);
     550                 :          0 :         port_dev->dev.parent = hub->intfdev;
     551         [ #  # ]:          0 :         if (hub_is_superspeed(hdev)) {
     552                 :          0 :                 port_dev->usb3_lpm_u1_permit = 1;
     553                 :          0 :                 port_dev->usb3_lpm_u2_permit = 1;
     554                 :          0 :                 port_dev->dev.groups = port_dev_usb3_group;
     555                 :            :         } else
     556                 :          0 :                 port_dev->dev.groups = port_dev_group;
     557                 :          0 :         port_dev->dev.type = &usb_port_device_type;
     558                 :          0 :         port_dev->dev.driver = &usb_port_driver;
     559         [ #  # ]:          0 :         if (hub_is_superspeed(hub->hdev))
     560                 :          0 :                 port_dev->is_superspeed = 1;
     561         [ #  # ]:          0 :         dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
     562                 :            :                         port1);
     563                 :          0 :         mutex_init(&port_dev->status_lock);
     564                 :          0 :         retval = device_register(&port_dev->dev);
     565         [ #  # ]:          0 :         if (retval) {
     566                 :          0 :                 put_device(&port_dev->dev);
     567                 :          0 :                 return retval;
     568                 :            :         }
     569                 :            : 
     570                 :            :         /* Set default policy of port-poweroff disabled. */
     571                 :          0 :         retval = dev_pm_qos_add_request(&port_dev->dev, port_dev->req,
     572                 :            :                         DEV_PM_QOS_FLAGS, PM_QOS_FLAG_NO_POWER_OFF);
     573         [ #  # ]:          0 :         if (retval < 0) {
     574                 :          0 :                 device_unregister(&port_dev->dev);
     575                 :          0 :                 return retval;
     576                 :            :         }
     577                 :            : 
     578                 :          0 :         find_and_link_peer(hub, port1);
     579                 :            : 
     580                 :            :         /*
     581                 :            :          * Enable runtime pm and hold a refernce that hub_configure()
     582                 :            :          * will drop once the PM_QOS_NO_POWER_OFF flag state has been set
     583                 :            :          * and the hub has been fully registered (hdev->maxchild set).
     584                 :            :          */
     585                 :          0 :         pm_runtime_set_active(&port_dev->dev);
     586                 :          0 :         pm_runtime_get_noresume(&port_dev->dev);
     587                 :          0 :         pm_runtime_enable(&port_dev->dev);
     588         [ #  # ]:          0 :         device_enable_async_suspend(&port_dev->dev);
     589                 :            : 
     590                 :            :         /*
     591                 :            :          * Keep hidden the ability to enable port-poweroff if the hub
     592                 :            :          * does not support power switching.
     593                 :            :          */
     594   [ #  #  #  # ]:          0 :         if (!hub_is_port_power_switchable(hub))
     595                 :            :                 return 0;
     596                 :            : 
     597                 :            :         /* Attempt to let userspace take over the policy. */
     598                 :          0 :         retval = dev_pm_qos_expose_flags(&port_dev->dev,
     599                 :            :                         PM_QOS_FLAG_NO_POWER_OFF);
     600         [ #  # ]:          0 :         if (retval < 0) {
     601                 :          0 :                 dev_warn(&port_dev->dev, "failed to expose pm_qos_no_poweroff\n");
     602                 :          0 :                 return 0;
     603                 :            :         }
     604                 :            : 
     605                 :            :         /* Userspace owns the policy, drop the kernel 'no_poweroff' request. */
     606                 :          0 :         retval = dev_pm_qos_remove_request(port_dev->req);
     607         [ #  # ]:          0 :         if (retval >= 0) {
     608                 :          0 :                 kfree(port_dev->req);
     609                 :          0 :                 port_dev->req = NULL;
     610                 :            :         }
     611                 :            :         return 0;
     612                 :            : }
     613                 :            : 
     614                 :          0 : void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
     615                 :            : {
     616                 :          0 :         struct usb_port *port_dev = hub->ports[port1 - 1];
     617                 :          0 :         struct usb_port *peer;
     618                 :            : 
     619                 :          0 :         peer = port_dev->peer;
     620         [ #  # ]:          0 :         if (peer)
     621                 :          0 :                 unlink_peers(port_dev, peer);
     622                 :          0 :         device_unregister(&port_dev->dev);
     623                 :          0 : }

Generated by: LCOV version 1.14