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