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