From 6c815cebc391eaffe5fc34678cda3db794a72f97 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Mon, 2 Oct 2017 14:13:47 -0700 Subject: [PATCH] usb: misc: lvstest: allow specifying port for compliance mode In some cases when connecting to a test fixture the host port might not have triggered a connect change. As a result, dev->portnum does not get updated and an attempt to enable the port for compliance mode will pass 0 as the port number to the HCD, which is invalid. Instead allow the user to pass an explicit port number from the command line to specify the port to act on. Otherwise, if omitted, the behavior is the same as before. Change-Id: I2e323c9016915b2d535ac227fd6f3d5846aa4026 Signed-off-by: Jack Pham --- drivers/usb/misc/lvstest.c | 40 ++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 25ec5666a75e..b897146ba3d5 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c @@ -105,8 +105,14 @@ static ssize_t u3_entry_store(struct device *dev, struct usb_device *hdev = interface_to_usbdev(intf); struct lvs_rh *lvs = usb_get_intfdata(intf); struct usb_device *udev; + int port; int ret; + if (!kstrtoint(buf, 0, &port) || port >= 1 || port <= 255) { + lvs->portnum = port; + lvs->present = true; + } + udev = create_lvs_device(intf); if (!udev) { dev_err(dev, "failed to create lvs device\n"); @@ -134,8 +140,14 @@ static ssize_t u3_exit_store(struct device *dev, struct usb_device *hdev = interface_to_usbdev(intf); struct lvs_rh *lvs = usb_get_intfdata(intf); struct usb_device *udev; + int port; int ret; + if (!kstrtoint(buf, 0, &port) || port >= 1 || port <= 255) { + lvs->portnum = port; + lvs->present = true; + } + udev = create_lvs_device(intf); if (!udev) { dev_err(dev, "failed to create lvs device\n"); @@ -162,9 +174,13 @@ static ssize_t hot_reset_store(struct device *dev, struct usb_interface *intf = to_usb_interface(dev); struct usb_device *hdev = interface_to_usbdev(intf); struct lvs_rh *lvs = usb_get_intfdata(intf); + int port; int ret; - ret = lvs_rh_set_port_feature(hdev, lvs->portnum, + if (kstrtoint(buf, 0, &port) || port < 1 || port > 255) + port = lvs->portnum; + + ret = lvs_rh_set_port_feature(hdev, port, USB_PORT_FEAT_RESET); if (ret < 0) { dev_err(dev, "can't issue hot reset %d\n", ret); @@ -181,10 +197,13 @@ static ssize_t warm_reset_store(struct device *dev, struct usb_interface *intf = to_usb_interface(dev); struct usb_device *hdev = interface_to_usbdev(intf); struct lvs_rh *lvs = usb_get_intfdata(intf); + int port; int ret; - ret = lvs_rh_set_port_feature(hdev, lvs->portnum, - USB_PORT_FEAT_BH_PORT_RESET); + if (kstrtoint(buf, 0, &port) || port < 1 || port > 255) + port = lvs->portnum; + + ret = lvs_rh_set_port_feature(hdev, port, USB_PORT_FEAT_BH_PORT_RESET); if (ret < 0) { dev_err(dev, "can't issue warm reset %d\n", ret); return ret; @@ -256,9 +275,15 @@ static ssize_t get_dev_desc_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_interface *intf = to_usb_interface(dev); + struct lvs_rh *lvs = usb_get_intfdata(intf); struct usb_device *udev; struct usb_device_descriptor *descriptor; - int ret; + int ret, port; + + if (!kstrtoint(buf, 0, &port) || port >= 1 || port <= 255) { + lvs->portnum = port; + lvs->present = true; + } descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL); if (!descriptor) @@ -277,7 +302,6 @@ static ssize_t get_dev_desc_store(struct device *dev, USB_CTRL_GET_TIMEOUT); if (ret < 0) dev_err(dev, "can't read device descriptor %d\n", ret); - destroy_lvs_device(udev); free_desc: @@ -296,10 +320,14 @@ static ssize_t enable_compliance_store(struct device *dev, struct usb_interface *intf = to_usb_interface(dev); struct usb_device *hdev = interface_to_usbdev(intf); struct lvs_rh *lvs = usb_get_intfdata(intf); + int port; int ret; + if (kstrtoint(buf, 0, &port) || port < 1 || port > 255) + port = lvs->portnum; + ret = lvs_rh_set_port_feature(hdev, - lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3, + port | (USB_SS_PORT_LS_COMP_MOD << 3), USB_PORT_FEAT_LINK_STATE); if (ret < 0) { dev_err(dev, "can't enable compliance mode %d\n", ret);