aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/lvstest.c
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2017-08-23 03:35:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-08-28 05:43:39 -0400
commitf624ec70b464cb603efb9707234f59b6a502056d (patch)
treef0d2836e0433cf22ce1bb24956b1f202ebd1d939 /drivers/usb/misc/lvstest.c
parent4b562bd2b1862dd90f76baba06250d83e90d9261 (diff)
usb: misc: lvstest: add entry to place port in compliance mode
Add support for the SuperSpeed Link Layer test case TD.7.34 which requires the operator to place the port into compliance mode, and to subsequently bring it out via reset. Historically according to the (now deprecated) USB 3.0 specification a SuperSpeed host downstream port would automatically transition to Compliance mode from the Polling state if LFPS polling times out. However the language in USB 3.1 as well as xHCI 1.1 states it may be required to explicitly enable this transition. For such hosts this is done by sending a SET_FEATURE(PORT_LINK_STATE) with the state set to Compliance to the root hub port. Similar to the other supported commands, to do this via sysfs: echo > /sys/bus/usb/devices/2-0\:1.0/enable_compliance According to xHCI 1.1 section 4.19.1.2.4.1, this enables the transition to compliance mode upon LFPS timeout. Note that this can only be issued when the port is in disconnected state. And in order to disable this behavior on subsequent transitions, a warm reset should be issued. So add another entry to do that: echo > /sys/bus/usb/devices/2-0\:1.0/warm_reset In general these attributes can also be useful for other USB SuperSpeed compliance tests such as electrical and eye diagram testing which require CPn patterns to be transmitted. Signed-off-by: Jack Pham <jackp@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/misc/lvstest.c')
-rw-r--r--drivers/usb/misc/lvstest.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index 2142132a1f82..ddddd6387f66 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -178,6 +178,25 @@ static ssize_t hot_reset_store(struct device *dev,
178} 178}
179static DEVICE_ATTR_WO(hot_reset); 179static DEVICE_ATTR_WO(hot_reset);
180 180
181static ssize_t warm_reset_store(struct device *dev,
182 struct device_attribute *attr, const char *buf, size_t count)
183{
184 struct usb_interface *intf = to_usb_interface(dev);
185 struct usb_device *hdev = interface_to_usbdev(intf);
186 struct lvs_rh *lvs = usb_get_intfdata(intf);
187 int ret;
188
189 ret = lvs_rh_set_port_feature(hdev, lvs->portnum,
190 USB_PORT_FEAT_BH_PORT_RESET);
191 if (ret < 0) {
192 dev_err(dev, "can't issue warm reset %d\n", ret);
193 return ret;
194 }
195
196 return count;
197}
198static DEVICE_ATTR_WO(warm_reset);
199
181static ssize_t u2_timeout_store(struct device *dev, 200static ssize_t u2_timeout_store(struct device *dev,
182 struct device_attribute *attr, const char *buf, size_t count) 201 struct device_attribute *attr, const char *buf, size_t count)
183{ 202{
@@ -274,13 +293,35 @@ free_desc:
274} 293}
275static DEVICE_ATTR_WO(get_dev_desc); 294static DEVICE_ATTR_WO(get_dev_desc);
276 295
296static ssize_t enable_compliance_store(struct device *dev,
297 struct device_attribute *attr, const char *buf, size_t count)
298{
299 struct usb_interface *intf = to_usb_interface(dev);
300 struct usb_device *hdev = interface_to_usbdev(intf);
301 struct lvs_rh *lvs = usb_get_intfdata(intf);
302 int ret;
303
304 ret = lvs_rh_set_port_feature(hdev,
305 lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3,
306 USB_PORT_FEAT_LINK_STATE);
307 if (ret < 0) {
308 dev_err(dev, "can't enable compliance mode %d\n", ret);
309 return ret;
310 }
311
312 return count;
313}
314static DEVICE_ATTR_WO(enable_compliance);
315
277static struct attribute *lvs_attributes[] = { 316static struct attribute *lvs_attributes[] = {
278 &dev_attr_get_dev_desc.attr, 317 &dev_attr_get_dev_desc.attr,
279 &dev_attr_u1_timeout.attr, 318 &dev_attr_u1_timeout.attr,
280 &dev_attr_u2_timeout.attr, 319 &dev_attr_u2_timeout.attr,
281 &dev_attr_hot_reset.attr, 320 &dev_attr_hot_reset.attr,
321 &dev_attr_warm_reset.attr,
282 &dev_attr_u3_entry.attr, 322 &dev_attr_u3_entry.attr,
283 &dev_attr_u3_exit.attr, 323 &dev_attr_u3_exit.attr,
324 &dev_attr_enable_compliance.attr,
284 NULL 325 NULL
285}; 326};
286 327