MLK-9617-9 usb: core: hub: use a_set_b_hnp_en and b_hnp_en for otg fsm mode
authorLi Jun <B47624@freescale.com>
Fri, 10 Oct 2014 07:34:39 +0000 (15:34 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:47:13 +0000 (14:47 -0500)
Use a_set_b_hnp_en to identify if a host can succeed to set b_hnp_enable
for B device, use b_hnp_enable flag to identify if the connected OTG device
is HNP capable. So if the connected otg device is HNP capable but b_hnp_enable
is not set for A host, the host which support HNP polling should continue
enumeration to see if the B device can talk to it later by hnp polling.

Signed-off-by: Li Jun <b47624@freescale.com>
(cherry picked from commit b715d0773eea212a25d6b8c5d94530e12935fdaf)
(cherry picked from commit 454369742ce4dec01d89c946a28c3069fc23bbea)

drivers/usb/core/hub.c

index 208f221..948c01f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/usbdevice_fs.h>
 #include <linux/usb/hcd.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/otg-fsm.h>
 #include <linux/usb/quirks.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
@@ -2241,6 +2242,12 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
                                                                        err);
                                bus->b_hnp_enable = 0;
                        }
+
+                       if (bus->otg_fsm) {
+                               bus->otg_fsm->b_hnp_enable = 1;
+                               if (bus->b_hnp_enable)
+                                       bus->otg_fsm->a_set_b_hnp_en = 1;
+                       }
                } else if (desc->bLength == sizeof
                                (struct usb_otg_descriptor)) {
                        /* Set a_alt_hnp_support for legacy otg device */
@@ -2279,6 +2286,7 @@ static int usb_enumerate_device(struct usb_device *udev)
 {
        int err;
        struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+       struct otg_fsm *fsm = udev->bus->otg_fsm;
 
        if (udev->config == NULL) {
                err = usb_get_configuration(udev);
@@ -2310,8 +2318,10 @@ static int usb_enumerate_device(struct usb_device *udev)
                        err = usb_port_suspend(udev, PMSG_AUTO_SUSPEND);
                        if (err < 0)
                                dev_dbg(&udev->dev, "HNP fail, %d\n", err);
+                       return -ENOTSUPP;
+               } else if (!fsm || !fsm->b_hnp_enable || !fsm->hnp_polling) {
+                       return -ENOTSUPP;
                }
-               return -ENOTSUPP;
        }
 
        usb_detect_interface_quirks(udev);