usbip_device_driver.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
  3. * 2015 Samsung Electronics
  4. * Author: Igor Kotrasinski <i.kotrasinsk@samsung.com>
  5. *
  6. * Based on tools/usb/usbip/libsrc/usbip_host_driver.c, which is:
  7. * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  8. * 2005-2007 Takahiro Hirofuchi
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. #include <fcntl.h>
  24. #include <string.h>
  25. #include <linux/usb/ch9.h>
  26. #include <unistd.h>
  27. #include "usbip_host_common.h"
  28. #include "usbip_device_driver.h"
  29. #undef PROGNAME
  30. #define PROGNAME "libusbip"
  31. #define copy_descr_attr16(dev, descr, attr) \
  32. ((dev)->attr = le16toh((descr)->attr)) \
  33. #define copy_descr_attr(dev, descr, attr) \
  34. ((dev)->attr = (descr)->attr) \
  35. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
  36. static struct {
  37. enum usb_device_speed speed;
  38. const char *name;
  39. } speed_names[] = {
  40. {
  41. .speed = USB_SPEED_UNKNOWN,
  42. .name = "UNKNOWN",
  43. },
  44. {
  45. .speed = USB_SPEED_LOW,
  46. .name = "low-speed",
  47. },
  48. {
  49. .speed = USB_SPEED_FULL,
  50. .name = "full-speed",
  51. },
  52. {
  53. .speed = USB_SPEED_HIGH,
  54. .name = "high-speed",
  55. },
  56. {
  57. .speed = USB_SPEED_WIRELESS,
  58. .name = "wireless",
  59. },
  60. {
  61. .speed = USB_SPEED_SUPER,
  62. .name = "super-speed",
  63. },
  64. };
  65. static
  66. int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
  67. {
  68. const char *path, *name;
  69. char filepath[SYSFS_PATH_MAX];
  70. struct usb_device_descriptor descr;
  71. unsigned i;
  72. FILE *fd = NULL;
  73. struct udev_device *plat;
  74. const char *speed;
  75. int ret = 0;
  76. plat = udev_device_get_parent(sdev);
  77. path = udev_device_get_syspath(plat);
  78. snprintf(filepath, SYSFS_PATH_MAX, "%s/%s",
  79. path, VUDC_DEVICE_DESCR_FILE);
  80. fd = fopen(filepath, "r");
  81. if (!fd)
  82. return -1;
  83. ret = fread((char *) &descr, sizeof(descr), 1, fd);
  84. if (ret < 0)
  85. return -1;
  86. fclose(fd);
  87. copy_descr_attr(dev, &descr, bDeviceClass);
  88. copy_descr_attr(dev, &descr, bDeviceSubClass);
  89. copy_descr_attr(dev, &descr, bDeviceProtocol);
  90. copy_descr_attr(dev, &descr, bNumConfigurations);
  91. copy_descr_attr16(dev, &descr, idVendor);
  92. copy_descr_attr16(dev, &descr, idProduct);
  93. copy_descr_attr16(dev, &descr, bcdDevice);
  94. strncpy(dev->path, path, SYSFS_PATH_MAX);
  95. dev->speed = USB_SPEED_UNKNOWN;
  96. speed = udev_device_get_sysattr_value(sdev, "current_speed");
  97. if (speed) {
  98. for (i = 0; i < ARRAY_SIZE(speed_names); i++) {
  99. if (!strcmp(speed_names[i].name, speed)) {
  100. dev->speed = speed_names[i].speed;
  101. break;
  102. }
  103. }
  104. }
  105. /* Only used for user output, little sense to output them in general */
  106. dev->bNumInterfaces = 0;
  107. dev->bConfigurationValue = 0;
  108. dev->busnum = 0;
  109. name = udev_device_get_sysname(plat);
  110. strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE);
  111. return 0;
  112. }
  113. static int is_my_device(struct udev_device *dev)
  114. {
  115. const char *driver;
  116. driver = udev_device_get_property_value(dev, "USB_UDC_NAME");
  117. return driver != NULL && !strcmp(driver, USBIP_DEVICE_DRV_NAME);
  118. }
  119. static int usbip_device_driver_open(struct usbip_host_driver *hdriver)
  120. {
  121. int ret;
  122. hdriver->ndevs = 0;
  123. INIT_LIST_HEAD(&hdriver->edev_list);
  124. ret = usbip_generic_driver_open(hdriver);
  125. if (ret)
  126. err("please load " USBIP_CORE_MOD_NAME ".ko and "
  127. USBIP_DEVICE_DRV_NAME ".ko!");
  128. return ret;
  129. }
  130. struct usbip_host_driver device_driver = {
  131. .edev_list = LIST_HEAD_INIT(device_driver.edev_list),
  132. .udev_subsystem = "udc",
  133. .ops = {
  134. .open = usbip_device_driver_open,
  135. .close = usbip_generic_driver_close,
  136. .refresh_device_list = usbip_generic_refresh_device_list,
  137. .get_device = usbip_generic_get_device,
  138. .read_device = read_usb_vudc_device,
  139. .is_my_device = is_my_device,
  140. },
  141. };