vhci_sysfs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2003-2008 Takahiro Hirofuchi
  4. * Copyright (C) 2015-2016 Nobuo Iwata
  5. */
  6. #include <linux/kthread.h>
  7. #include <linux/file.h>
  8. #include <linux/net.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/slab.h>
  11. #include "usbip_common.h"
  12. #include "vhci.h"
  13. /* TODO: refine locking ?*/
  14. /*
  15. * output example:
  16. * hub port sta spd dev socket local_busid
  17. * hs 0000 004 000 00000000 c5a7bb80 1-2.3
  18. * ................................................
  19. * ss 0008 004 000 00000000 d8cee980 2-3.4
  20. * ................................................
  21. *
  22. * IP address can be retrieved from a socket pointer address by looking
  23. * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
  24. * port number and its peer IP address.
  25. */
  26. static void port_show_vhci(char **out, int hub, int port, struct vhci_device *vdev)
  27. {
  28. if (hub == HUB_SPEED_HIGH)
  29. *out += sprintf(*out, "hs %04u %03u ",
  30. port, vdev->ud.status);
  31. else /* hub == HUB_SPEED_SUPER */
  32. *out += sprintf(*out, "ss %04u %03u ",
  33. port, vdev->ud.status);
  34. if (vdev->ud.status == VDEV_ST_USED) {
  35. *out += sprintf(*out, "%03u %08x ",
  36. vdev->speed, vdev->devid);
  37. *out += sprintf(*out, "%16p %s",
  38. vdev->ud.tcp_socket,
  39. dev_name(&vdev->udev->dev));
  40. } else {
  41. *out += sprintf(*out, "000 00000000 ");
  42. *out += sprintf(*out, "0000000000000000 0-0");
  43. }
  44. *out += sprintf(*out, "\n");
  45. }
  46. /* Sysfs entry to show port status */
  47. static ssize_t status_show_vhci(int pdev_nr, char *out)
  48. {
  49. struct platform_device *pdev = vhcis[pdev_nr].pdev;
  50. struct vhci *vhci;
  51. struct usb_hcd *hcd;
  52. struct vhci_hcd *vhci_hcd;
  53. char *s = out;
  54. int i;
  55. unsigned long flags;
  56. if (!pdev || !out) {
  57. usbip_dbg_vhci_sysfs("show status error\n");
  58. return 0;
  59. }
  60. hcd = platform_get_drvdata(pdev);
  61. vhci_hcd = hcd_to_vhci_hcd(hcd);
  62. vhci = vhci_hcd->vhci;
  63. spin_lock_irqsave(&vhci->lock, flags);
  64. for (i = 0; i < VHCI_HC_PORTS; i++) {
  65. struct vhci_device *vdev = &vhci->vhci_hcd_hs->vdev[i];
  66. spin_lock(&vdev->ud.lock);
  67. port_show_vhci(&out, HUB_SPEED_HIGH,
  68. pdev_nr * VHCI_PORTS + i, vdev);
  69. spin_unlock(&vdev->ud.lock);
  70. }
  71. for (i = 0; i < VHCI_HC_PORTS; i++) {
  72. struct vhci_device *vdev = &vhci->vhci_hcd_ss->vdev[i];
  73. spin_lock(&vdev->ud.lock);
  74. port_show_vhci(&out, HUB_SPEED_SUPER,
  75. pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev);
  76. spin_unlock(&vdev->ud.lock);
  77. }
  78. spin_unlock_irqrestore(&vhci->lock, flags);
  79. return out - s;
  80. }
  81. static ssize_t status_show_not_ready(int pdev_nr, char *out)
  82. {
  83. char *s = out;
  84. int i = 0;
  85. for (i = 0; i < VHCI_HC_PORTS; i++) {
  86. out += sprintf(out, "hs %04u %03u ",
  87. (pdev_nr * VHCI_PORTS) + i,
  88. VDEV_ST_NOTASSIGNED);
  89. out += sprintf(out, "000 00000000 0000000000000000 0-0");
  90. out += sprintf(out, "\n");
  91. }
  92. for (i = 0; i < VHCI_HC_PORTS; i++) {
  93. out += sprintf(out, "ss %04u %03u ",
  94. (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i,
  95. VDEV_ST_NOTASSIGNED);
  96. out += sprintf(out, "000 00000000 0000000000000000 0-0");
  97. out += sprintf(out, "\n");
  98. }
  99. return out - s;
  100. }
  101. static int status_name_to_id(const char *name)
  102. {
  103. char *c;
  104. long val;
  105. int ret;
  106. c = strchr(name, '.');
  107. if (c == NULL)
  108. return 0;
  109. ret = kstrtol(c+1, 10, &val);
  110. if (ret < 0)
  111. return ret;
  112. return val;
  113. }
  114. static ssize_t status_show(struct device *dev,
  115. struct device_attribute *attr, char *out)
  116. {
  117. char *s = out;
  118. int pdev_nr;
  119. out += sprintf(out,
  120. "hub port sta spd dev socket local_busid\n");
  121. pdev_nr = status_name_to_id(attr->attr.name);
  122. if (pdev_nr < 0)
  123. out += status_show_not_ready(pdev_nr, out);
  124. else
  125. out += status_show_vhci(pdev_nr, out);
  126. return out - s;
  127. }
  128. static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
  129. char *out)
  130. {
  131. char *s = out;
  132. /*
  133. * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2.
  134. */
  135. out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers);
  136. return out - s;
  137. }
  138. static DEVICE_ATTR_RO(nports);
  139. /* Sysfs entry to shutdown a virtual connection */
  140. static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
  141. {
  142. struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
  143. struct vhci *vhci = vhci_hcd->vhci;
  144. unsigned long flags;
  145. usbip_dbg_vhci_sysfs("enter\n");
  146. /* lock */
  147. spin_lock_irqsave(&vhci->lock, flags);
  148. spin_lock(&vdev->ud.lock);
  149. if (vdev->ud.status == VDEV_ST_NULL) {
  150. pr_err("not connected %d\n", vdev->ud.status);
  151. /* unlock */
  152. spin_unlock(&vdev->ud.lock);
  153. spin_unlock_irqrestore(&vhci->lock, flags);
  154. return -EINVAL;
  155. }
  156. /* unlock */
  157. spin_unlock(&vdev->ud.lock);
  158. spin_unlock_irqrestore(&vhci->lock, flags);
  159. usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
  160. return 0;
  161. }
  162. static int valid_port(__u32 pdev_nr, __u32 rhport)
  163. {
  164. if (pdev_nr >= vhci_num_controllers) {
  165. pr_err("pdev %u\n", pdev_nr);
  166. return 0;
  167. }
  168. if (rhport >= VHCI_HC_PORTS) {
  169. pr_err("rhport %u\n", rhport);
  170. return 0;
  171. }
  172. return 1;
  173. }
  174. static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
  175. const char *buf, size_t count)
  176. {
  177. __u32 port = 0, pdev_nr = 0, rhport = 0;
  178. struct usb_hcd *hcd;
  179. struct vhci_hcd *vhci_hcd;
  180. int ret;
  181. if (kstrtoint(buf, 10, &port) < 0)
  182. return -EINVAL;
  183. pdev_nr = port_to_pdev_nr(port);
  184. rhport = port_to_rhport(port);
  185. if (!valid_port(pdev_nr, rhport))
  186. return -EINVAL;
  187. hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
  188. if (hcd == NULL) {
  189. dev_err(dev, "port is not ready %u\n", port);
  190. return -EAGAIN;
  191. }
  192. usbip_dbg_vhci_sysfs("rhport %d\n", rhport);
  193. if ((port / VHCI_HC_PORTS) % 2)
  194. vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_ss;
  195. else
  196. vhci_hcd = hcd_to_vhci_hcd(hcd)->vhci->vhci_hcd_hs;
  197. ret = vhci_port_disconnect(vhci_hcd, rhport);
  198. if (ret < 0)
  199. return -EINVAL;
  200. usbip_dbg_vhci_sysfs("Leave\n");
  201. return count;
  202. }
  203. static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
  204. static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed)
  205. {
  206. if (!valid_port(pdev_nr, rhport)) {
  207. return 0;
  208. }
  209. switch (speed) {
  210. case USB_SPEED_LOW:
  211. case USB_SPEED_FULL:
  212. case USB_SPEED_HIGH:
  213. case USB_SPEED_WIRELESS:
  214. case USB_SPEED_SUPER:
  215. break;
  216. default:
  217. pr_err("Failed attach request for unsupported USB speed: %s\n",
  218. usb_speed_string(speed));
  219. return 0;
  220. }
  221. return 1;
  222. }
  223. /* Sysfs entry to establish a virtual connection */
  224. /*
  225. * To start a new USB/IP attachment, a userland program needs to setup a TCP
  226. * connection and then write its socket descriptor with remote device
  227. * information into this sysfs file.
  228. *
  229. * A remote device is virtually attached to the root-hub port of @rhport with
  230. * @speed. @devid is embedded into a request to specify the remote device in a
  231. * server host.
  232. *
  233. * write() returns 0 on success, else negative errno.
  234. */
  235. static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
  236. const char *buf, size_t count)
  237. {
  238. struct socket *socket;
  239. int sockfd = 0;
  240. __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0;
  241. struct usb_hcd *hcd;
  242. struct vhci_hcd *vhci_hcd;
  243. struct vhci_device *vdev;
  244. struct vhci *vhci;
  245. int err;
  246. unsigned long flags;
  247. /*
  248. * @rhport: port number of vhci_hcd
  249. * @sockfd: socket descriptor of an established TCP connection
  250. * @devid: unique device identifier in a remote host
  251. * @speed: usb device speed in a remote host
  252. */
  253. if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4)
  254. return -EINVAL;
  255. pdev_nr = port_to_pdev_nr(port);
  256. rhport = port_to_rhport(port);
  257. usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n",
  258. port, pdev_nr, rhport);
  259. usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n",
  260. sockfd, devid, speed);
  261. /* check received parameters */
  262. if (!valid_args(pdev_nr, rhport, speed))
  263. return -EINVAL;
  264. hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
  265. if (hcd == NULL) {
  266. dev_err(dev, "port %d is not ready\n", port);
  267. return -EAGAIN;
  268. }
  269. vhci_hcd = hcd_to_vhci_hcd(hcd);
  270. vhci = vhci_hcd->vhci;
  271. if (speed == USB_SPEED_SUPER)
  272. vdev = &vhci->vhci_hcd_ss->vdev[rhport];
  273. else
  274. vdev = &vhci->vhci_hcd_hs->vdev[rhport];
  275. /* Extract socket from fd. */
  276. socket = sockfd_lookup(sockfd, &err);
  277. if (!socket)
  278. return -EINVAL;
  279. /* now need lock until setting vdev status as used */
  280. /* begin a lock */
  281. spin_lock_irqsave(&vhci->lock, flags);
  282. spin_lock(&vdev->ud.lock);
  283. if (vdev->ud.status != VDEV_ST_NULL) {
  284. /* end of the lock */
  285. spin_unlock(&vdev->ud.lock);
  286. spin_unlock_irqrestore(&vhci->lock, flags);
  287. sockfd_put(socket);
  288. dev_err(dev, "port %d already used\n", rhport);
  289. /*
  290. * Will be retried from userspace
  291. * if there's another free port.
  292. */
  293. return -EBUSY;
  294. }
  295. dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
  296. pdev_nr, rhport, sockfd);
  297. dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n",
  298. devid, speed, usb_speed_string(speed));
  299. vdev->devid = devid;
  300. vdev->speed = speed;
  301. vdev->ud.tcp_socket = socket;
  302. vdev->ud.status = VDEV_ST_NOTASSIGNED;
  303. spin_unlock(&vdev->ud.lock);
  304. spin_unlock_irqrestore(&vhci->lock, flags);
  305. /* end the lock */
  306. vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx");
  307. vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx");
  308. rh_port_connect(vdev, speed);
  309. return count;
  310. }
  311. static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
  312. #define MAX_STATUS_NAME 16
  313. struct status_attr {
  314. struct device_attribute attr;
  315. char name[MAX_STATUS_NAME+1];
  316. };
  317. static struct status_attr *status_attrs;
  318. static void set_status_attr(int id)
  319. {
  320. struct status_attr *status;
  321. status = status_attrs + id;
  322. if (id == 0)
  323. strcpy(status->name, "status");
  324. else
  325. snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id);
  326. status->attr.attr.name = status->name;
  327. status->attr.attr.mode = S_IRUGO;
  328. status->attr.show = status_show;
  329. sysfs_attr_init(&status->attr.attr);
  330. }
  331. static int init_status_attrs(void)
  332. {
  333. int id;
  334. status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr),
  335. GFP_KERNEL);
  336. if (status_attrs == NULL)
  337. return -ENOMEM;
  338. for (id = 0; id < vhci_num_controllers; id++)
  339. set_status_attr(id);
  340. return 0;
  341. }
  342. static void finish_status_attrs(void)
  343. {
  344. kfree(status_attrs);
  345. }
  346. struct attribute_group vhci_attr_group = {
  347. .attrs = NULL,
  348. };
  349. int vhci_init_attr_group(void)
  350. {
  351. struct attribute **attrs;
  352. int ret, i;
  353. attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *),
  354. GFP_KERNEL);
  355. if (attrs == NULL)
  356. return -ENOMEM;
  357. ret = init_status_attrs();
  358. if (ret) {
  359. kfree(attrs);
  360. return ret;
  361. }
  362. *attrs = &dev_attr_nports.attr;
  363. *(attrs + 1) = &dev_attr_detach.attr;
  364. *(attrs + 2) = &dev_attr_attach.attr;
  365. *(attrs + 3) = &dev_attr_usbip_debug.attr;
  366. for (i = 0; i < vhci_num_controllers; i++)
  367. *(attrs + i + 4) = &((status_attrs + i)->attr.attr);
  368. vhci_attr_group.attrs = attrs;
  369. return 0;
  370. }
  371. void vhci_finish_attr_group(void)
  372. {
  373. finish_status_attrs();
  374. kfree(vhci_attr_group.attrs);
  375. }