1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/ch11.h>
22#include <linux/usb/hcd.h>
23#include <linux/usb/phy.h>
24
25struct lvs_rh {
26
27 struct usb_interface *intf;
28
29 bool present;
30
31 int portnum;
32
33 u8 buffer[8];
34
35 struct usb_hub_descriptor descriptor;
36
37 struct urb *urb;
38
39 struct work_struct rh_work;
40
41 struct usb_port_status port_status;
42};
43
44static struct usb_device *create_lvs_device(struct usb_interface *intf)
45{
46 struct usb_device *udev, *hdev;
47 struct usb_hcd *hcd;
48 struct lvs_rh *lvs = usb_get_intfdata(intf);
49
50 if (!lvs->present) {
51 dev_err(&intf->dev, "No LVS device is present\n");
52 return NULL;
53 }
54
55 hdev = interface_to_usbdev(intf);
56 hcd = bus_to_hcd(hdev->bus);
57
58 udev = usb_alloc_dev(hdev, hdev->bus, lvs->portnum);
59 if (!udev) {
60 dev_err(&intf->dev, "Could not allocate lvs udev\n");
61 return NULL;
62 }
63 udev->speed = USB_SPEED_SUPER;
64 udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
65 usb_set_device_state(udev, USB_STATE_DEFAULT);
66
67 if (hcd->driver->enable_device) {
68 if (hcd->driver->enable_device(hcd, udev) < 0) {
69 dev_err(&intf->dev, "Failed to enable\n");
70 usb_put_dev(udev);
71 return NULL;
72 }
73 }
74
75 return udev;
76}
77
78static void destroy_lvs_device(struct usb_device *udev)
79{
80 struct usb_device *hdev = udev->parent;
81 struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
82
83 if (hcd->driver->free_dev)
84 hcd->driver->free_dev(hcd, udev);
85
86 usb_put_dev(udev);
87}
88
89static int lvs_rh_clear_port_feature(struct usb_device *hdev,
90 int port1, int feature)
91{
92 return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
93 USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
94 NULL, 0, 1000);
95}
96
97static int lvs_rh_set_port_feature(struct usb_device *hdev,
98 int port1, int feature)
99{
100 return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
101 USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
102 NULL, 0, 1000);
103}
104
105static ssize_t u3_entry_store(struct device *dev,
106 struct device_attribute *attr, const char *buf, size_t count)
107{
108 struct usb_interface *intf = to_usb_interface(dev);
109 struct usb_device *hdev = interface_to_usbdev(intf);
110 struct lvs_rh *lvs = usb_get_intfdata(intf);
111 struct usb_device *udev;
112 int ret;
113
114 udev = create_lvs_device(intf);
115 if (!udev) {
116 dev_err(dev, "failed to create lvs device\n");
117 return -ENOMEM;
118 }
119
120 ret = lvs_rh_set_port_feature(hdev, lvs->portnum,
121 USB_PORT_FEAT_SUSPEND);
122 if (ret < 0)
123 dev_err(dev, "can't issue U3 entry %d\n", ret);
124
125 destroy_lvs_device(udev);
126
127 if (ret < 0)
128 return ret;
129
130 return count;
131}
132static DEVICE_ATTR_WO(u3_entry);
133
134static ssize_t u3_exit_store(struct device *dev,
135 struct device_attribute *attr, const char *buf, size_t count)
136{
137 struct usb_interface *intf = to_usb_interface(dev);
138 struct usb_device *hdev = interface_to_usbdev(intf);
139 struct lvs_rh *lvs = usb_get_intfdata(intf);
140 struct usb_device *udev;
141 int ret;
142
143 udev = create_lvs_device(intf);
144 if (!udev) {
145 dev_err(dev, "failed to create lvs device\n");
146 return -ENOMEM;
147 }
148
149 ret = lvs_rh_clear_port_feature(hdev, lvs->portnum,
150 USB_PORT_FEAT_SUSPEND);
151 if (ret < 0)
152 dev_err(dev, "can't issue U3 exit %d\n", ret);
153
154 destroy_lvs_device(udev);
155
156 if (ret < 0)
157 return ret;
158
159 return count;
160}
161static DEVICE_ATTR_WO(u3_exit);
162
163static ssize_t hot_reset_store(struct device *dev,
164 struct device_attribute *attr, const char *buf, size_t count)
165{
166 struct usb_interface *intf = to_usb_interface(dev);
167 struct usb_device *hdev = interface_to_usbdev(intf);
168 struct lvs_rh *lvs = usb_get_intfdata(intf);
169 int ret;
170
171 ret = lvs_rh_set_port_feature(hdev, lvs->portnum,
172 USB_PORT_FEAT_RESET);
173 if (ret < 0) {
174 dev_err(dev, "can't issue hot reset %d\n", ret);
175 return ret;
176 }
177
178 return count;
179}
180static DEVICE_ATTR_WO(hot_reset);
181
182static ssize_t warm_reset_store(struct device *dev,
183 struct device_attribute *attr, const char *buf, size_t count)
184{
185 struct usb_interface *intf = to_usb_interface(dev);
186 struct usb_device *hdev = interface_to_usbdev(intf);
187 struct lvs_rh *lvs = usb_get_intfdata(intf);
188 int ret;
189
190 ret = lvs_rh_set_port_feature(hdev, lvs->portnum,
191 USB_PORT_FEAT_BH_PORT_RESET);
192 if (ret < 0) {
193 dev_err(dev, "can't issue warm reset %d\n", ret);
194 return ret;
195 }
196
197 return count;
198}
199static DEVICE_ATTR_WO(warm_reset);
200
201static ssize_t u2_timeout_store(struct device *dev,
202 struct device_attribute *attr, const char *buf, size_t count)
203{
204 struct usb_interface *intf = to_usb_interface(dev);
205 struct usb_device *hdev = interface_to_usbdev(intf);
206 struct lvs_rh *lvs = usb_get_intfdata(intf);
207 unsigned long val;
208 int ret;
209
210 ret = kstrtoul(buf, 10, &val);
211 if (ret < 0) {
212 dev_err(dev, "couldn't parse string %d\n", ret);
213 return ret;
214 }
215
216 if (val > 127)
217 return -EINVAL;
218
219 ret = lvs_rh_set_port_feature(hdev, lvs->portnum | (val << 8),
220 USB_PORT_FEAT_U2_TIMEOUT);
221 if (ret < 0) {
222 dev_err(dev, "Error %d while setting U2 timeout %ld\n", ret, val);
223 return ret;
224 }
225
226 return count;
227}
228static DEVICE_ATTR_WO(u2_timeout);
229
230static ssize_t u1_timeout_store(struct device *dev,
231 struct device_attribute *attr, const char *buf, size_t count)
232{
233 struct usb_interface *intf = to_usb_interface(dev);
234 struct usb_device *hdev = interface_to_usbdev(intf);
235 struct lvs_rh *lvs = usb_get_intfdata(intf);
236 unsigned long val;
237 int ret;
238
239 ret = kstrtoul(buf, 10, &val);
240 if (ret < 0) {
241 dev_err(dev, "couldn't parse string %d\n", ret);
242 return ret;
243 }
244
245 if (val > 127)
246 return -EINVAL;
247
248 ret = lvs_rh_set_port_feature(hdev, lvs->portnum | (val << 8),
249 USB_PORT_FEAT_U1_TIMEOUT);
250 if (ret < 0) {
251 dev_err(dev, "Error %d while setting U1 timeout %ld\n", ret, val);
252 return ret;
253 }
254
255 return count;
256}
257static DEVICE_ATTR_WO(u1_timeout);
258
259static ssize_t get_dev_desc_store(struct device *dev,
260 struct device_attribute *attr, const char *buf, size_t count)
261{
262 struct usb_interface *intf = to_usb_interface(dev);
263 struct usb_device *udev;
264 struct usb_device_descriptor *descriptor;
265 int ret;
266
267 descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL);
268 if (!descriptor)
269 return -ENOMEM;
270
271 udev = create_lvs_device(intf);
272 if (!udev) {
273 dev_err(dev, "failed to create lvs device\n");
274 ret = -ENOMEM;
275 goto free_desc;
276 }
277
278 ret = usb_control_msg(udev, (PIPE_CONTROL << 30) | USB_DIR_IN,
279 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8,
280 0, descriptor, sizeof(*descriptor),
281 USB_CTRL_GET_TIMEOUT);
282 if (ret < 0)
283 dev_err(dev, "can't read device descriptor %d\n", ret);
284
285 destroy_lvs_device(udev);
286
287free_desc:
288 kfree(descriptor);
289
290 if (ret < 0)
291 return ret;
292
293 return count;
294}
295static DEVICE_ATTR_WO(get_dev_desc);
296
297static ssize_t enable_compliance_store(struct device *dev,
298 struct device_attribute *attr, const char *buf, size_t count)
299{
300 struct usb_interface *intf = to_usb_interface(dev);
301 struct usb_device *hdev = interface_to_usbdev(intf);
302 struct lvs_rh *lvs = usb_get_intfdata(intf);
303 int ret;
304
305 ret = lvs_rh_set_port_feature(hdev,
306 lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3,
307 USB_PORT_FEAT_LINK_STATE);
308 if (ret < 0) {
309 dev_err(dev, "can't enable compliance mode %d\n", ret);
310 return ret;
311 }
312
313 return count;
314}
315static DEVICE_ATTR_WO(enable_compliance);
316
317static struct attribute *lvs_attributes[] = {
318 &dev_attr_get_dev_desc.attr,
319 &dev_attr_u1_timeout.attr,
320 &dev_attr_u2_timeout.attr,
321 &dev_attr_hot_reset.attr,
322 &dev_attr_warm_reset.attr,
323 &dev_attr_u3_entry.attr,
324 &dev_attr_u3_exit.attr,
325 &dev_attr_enable_compliance.attr,
326 NULL
327};
328
329static const struct attribute_group lvs_attr_group = {
330 .attrs = lvs_attributes,
331};
332
333static void lvs_rh_work(struct work_struct *work)
334{
335 struct lvs_rh *lvs = container_of(work, struct lvs_rh, rh_work);
336 struct usb_interface *intf = lvs->intf;
337 struct usb_device *hdev = interface_to_usbdev(intf);
338 struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
339 struct usb_hub_descriptor *descriptor = &lvs->descriptor;
340 struct usb_port_status *port_status = &lvs->port_status;
341 int i, ret = 0;
342 u16 portchange;
343
344
345 for (i = 1; i <= descriptor->bNbrPorts; i++) {
346 ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
347 USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, i,
348 port_status, sizeof(*port_status), 1000);
349 if (ret < 4)
350 continue;
351
352 portchange = le16_to_cpu(port_status->wPortChange);
353
354 if (portchange & USB_PORT_STAT_C_LINK_STATE)
355 lvs_rh_clear_port_feature(hdev, i,
356 USB_PORT_FEAT_C_PORT_LINK_STATE);
357 if (portchange & USB_PORT_STAT_C_ENABLE)
358 lvs_rh_clear_port_feature(hdev, i,
359 USB_PORT_FEAT_C_ENABLE);
360 if (portchange & USB_PORT_STAT_C_RESET)
361 lvs_rh_clear_port_feature(hdev, i,
362 USB_PORT_FEAT_C_RESET);
363 if (portchange & USB_PORT_STAT_C_BH_RESET)
364 lvs_rh_clear_port_feature(hdev, i,
365 USB_PORT_FEAT_C_BH_PORT_RESET);
366 if (portchange & USB_PORT_STAT_C_CONNECTION) {
367 lvs_rh_clear_port_feature(hdev, i,
368 USB_PORT_FEAT_C_CONNECTION);
369
370 if (le16_to_cpu(port_status->wPortStatus) &
371 USB_PORT_STAT_CONNECTION) {
372 lvs->present = true;
373 lvs->portnum = i;
374 if (hcd->usb_phy)
375 usb_phy_notify_connect(hcd->usb_phy,
376 USB_SPEED_SUPER);
377 } else {
378 lvs->present = false;
379 if (hcd->usb_phy)
380 usb_phy_notify_disconnect(hcd->usb_phy,
381 USB_SPEED_SUPER);
382 }
383 break;
384 }
385 }
386
387 ret = usb_submit_urb(lvs->urb, GFP_KERNEL);
388 if (ret != 0 && ret != -ENODEV && ret != -EPERM)
389 dev_err(&intf->dev, "urb resubmit error %d\n", ret);
390}
391
392static void lvs_rh_irq(struct urb *urb)
393{
394 struct lvs_rh *lvs = urb->context;
395
396 schedule_work(&lvs->rh_work);
397}
398
399static int lvs_rh_probe(struct usb_interface *intf,
400 const struct usb_device_id *id)
401{
402 struct usb_device *hdev;
403 struct usb_host_interface *desc;
404 struct usb_endpoint_descriptor *endpoint;
405 struct lvs_rh *lvs;
406 unsigned int pipe;
407 int ret, maxp;
408
409 hdev = interface_to_usbdev(intf);
410 desc = intf->cur_altsetting;
411
412 ret = usb_find_int_in_endpoint(desc, &endpoint);
413 if (ret)
414 return ret;
415
416
417 if (hdev->descriptor.bDeviceProtocol != USB_HUB_PR_SS || hdev->parent) {
418 dev_err(&intf->dev, "Bind LVS driver with SS root Hub only\n");
419 return -EINVAL;
420 }
421
422 lvs = devm_kzalloc(&intf->dev, sizeof(*lvs), GFP_KERNEL);
423 if (!lvs)
424 return -ENOMEM;
425
426 lvs->intf = intf;
427 usb_set_intfdata(intf, lvs);
428
429
430 ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
431 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
432 USB_DT_SS_HUB << 8, 0, &lvs->descriptor,
433 USB_DT_SS_HUB_SIZE, USB_CTRL_GET_TIMEOUT);
434 if (ret < (USB_DT_HUB_NONVAR_SIZE + 2)) {
435 dev_err(&hdev->dev, "wrong root hub descriptor read %d\n", ret);
436 return ret;
437 }
438
439
440 lvs->urb = usb_alloc_urb(0, GFP_KERNEL);
441 if (!lvs->urb)
442 return -ENOMEM;
443
444 INIT_WORK(&lvs->rh_work, lvs_rh_work);
445
446 ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group);
447 if (ret < 0) {
448 dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret);
449 goto free_urb;
450 }
451
452 pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);
453 maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe));
454 usb_fill_int_urb(lvs->urb, hdev, pipe, &lvs->buffer[0], maxp,
455 lvs_rh_irq, lvs, endpoint->bInterval);
456
457 ret = usb_submit_urb(lvs->urb, GFP_KERNEL);
458 if (ret < 0) {
459 dev_err(&intf->dev, "couldn't submit lvs urb %d\n", ret);
460 goto sysfs_remove;
461 }
462
463 return ret;
464
465sysfs_remove:
466 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group);
467free_urb:
468 usb_free_urb(lvs->urb);
469 return ret;
470}
471
472static void lvs_rh_disconnect(struct usb_interface *intf)
473{
474 struct lvs_rh *lvs = usb_get_intfdata(intf);
475
476 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group);
477 usb_poison_urb(lvs->urb);
478 flush_work(&lvs->rh_work);
479 usb_free_urb(lvs->urb);
480}
481
482static struct usb_driver lvs_driver = {
483 .name = "lvs",
484 .probe = lvs_rh_probe,
485 .disconnect = lvs_rh_disconnect,
486};
487
488module_usb_driver(lvs_driver);
489
490MODULE_DESCRIPTION("Link Layer Validation System Driver");
491MODULE_LICENSE("GPL");
492