blob: 16fb4f85a6f62b529849ab67d209cfa9b7f5bb88 [file] [log] [blame]
Greg Kroah-Hartman5fd54ac2017-11-03 11:28:30 +01001// SPDX-License-Identifier: GPL-2.0+
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +01002/*
3 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
4 * Copyright (C) 2015-2016 Samsung Electronics
5 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
6 * Krzysztof Opasiak <k.opasiak@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/device.h>
23#include <linux/kernel.h>
24#include <linux/list.h>
25#include <linux/platform_device.h>
26#include <linux/usb.h>
27#include <linux/usb/gadget.h>
28#include <linux/usb/hcd.h>
29#include <linux/kthread.h>
30#include <linux/file.h>
31#include <linux/byteorder/generic.h>
32
33#include "usbip_common.h"
34#include "vudc.h"
35
36#define VIRTUAL_ENDPOINTS (1 /* ep0 */ + 15 /* in eps */ + 15 /* out eps */)
37
38/* urb-related structures alloc / free */
39
40
41static void free_urb(struct urb *urb)
42{
43 if (!urb)
44 return;
45
46 kfree(urb->setup_packet);
47 urb->setup_packet = NULL;
48
49 kfree(urb->transfer_buffer);
50 urb->transfer_buffer = NULL;
51
52 usb_free_urb(urb);
53}
54
55struct urbp *alloc_urbp(void)
56{
57 struct urbp *urb_p;
58
59 urb_p = kzalloc(sizeof(*urb_p), GFP_KERNEL);
60 if (!urb_p)
61 return urb_p;
62
63 urb_p->urb = NULL;
64 urb_p->ep = NULL;
65 INIT_LIST_HEAD(&urb_p->urb_entry);
66 return urb_p;
67}
68
69static void free_urbp(struct urbp *urb_p)
70{
71 kfree(urb_p);
72}
73
74void free_urbp_and_urb(struct urbp *urb_p)
75{
76 if (!urb_p)
77 return;
78 free_urb(urb_p->urb);
79 free_urbp(urb_p);
80}
81
82
83/* utilities ; almost verbatim from dummy_hcd.c */
84
85/* called with spinlock held */
86static void nuke(struct vudc *udc, struct vep *ep)
87{
88 struct vrequest *req;
89
90 while (!list_empty(&ep->req_queue)) {
91 req = list_first_entry(&ep->req_queue, struct vrequest,
92 req_entry);
93 list_del_init(&req->req_entry);
94 req->req.status = -ESHUTDOWN;
95
96 spin_unlock(&udc->lock);
97 usb_gadget_giveback_request(&ep->ep, &req->req);
98 spin_lock(&udc->lock);
99 }
100}
101
102/* caller must hold lock */
103static void stop_activity(struct vudc *udc)
104{
105 int i;
106 struct urbp *urb_p, *tmp;
107
108 udc->address = 0;
109
110 for (i = 0; i < VIRTUAL_ENDPOINTS; i++)
111 nuke(udc, &udc->ep[i]);
112
113 list_for_each_entry_safe(urb_p, tmp, &udc->urb_queue, urb_entry) {
114 list_del(&urb_p->urb_entry);
115 free_urbp_and_urb(urb_p);
116 }
117}
118
Krzysztof Opasiak0255cf92016-04-27 20:02:07 +0200119struct vep *vudc_find_endpoint(struct vudc *udc, u8 address)
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100120{
121 int i;
122
123 if ((address & ~USB_DIR_IN) == 0)
124 return &udc->ep[0];
125
126 for (i = 1; i < VIRTUAL_ENDPOINTS; i++) {
127 struct vep *ep = &udc->ep[i];
128
129 if (!ep->desc)
130 continue;
131 if (ep->desc->bEndpointAddress == address)
132 return ep;
133 }
134 return NULL;
135}
136
137/* gadget ops */
138
139/* FIXME - this will probably misbehave when suspend/resume is added */
140static int vgadget_get_frame(struct usb_gadget *_gadget)
141{
142 struct timeval now;
143 struct vudc *udc = usb_gadget_to_vudc(_gadget);
144
145 do_gettimeofday(&now);
146 return ((now.tv_sec - udc->start_time.tv_sec) * 1000 +
147 (now.tv_usec - udc->start_time.tv_usec) / 1000)
Arnd Bergmann15081e82017-11-07 11:39:56 +0100148 & 0x7FF;
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100149}
150
151static int vgadget_set_selfpowered(struct usb_gadget *_gadget, int value)
152{
153 struct vudc *udc = usb_gadget_to_vudc(_gadget);
154
155 if (value)
156 udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
157 else
158 udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
159 return 0;
160}
161
162static int vgadget_pullup(struct usb_gadget *_gadget, int value)
163{
164 struct vudc *udc = usb_gadget_to_vudc(_gadget);
165 unsigned long flags;
166 int ret;
167
168
169 spin_lock_irqsave(&udc->lock, flags);
170 value = !!value;
171 if (value == udc->pullup)
172 goto unlock;
173
174 udc->pullup = value;
175 if (value) {
176 udc->gadget.speed = min_t(u8, USB_SPEED_HIGH,
177 udc->driver->max_speed);
178 udc->ep[0].ep.maxpacket = 64;
179 /*
180 * This is the first place where we can ask our
181 * gadget driver for descriptors.
182 */
183 ret = get_gadget_descs(udc);
184 if (ret) {
185 dev_err(&udc->gadget.dev, "Unable go get desc: %d", ret);
186 goto unlock;
187 }
188
189 spin_unlock_irqrestore(&udc->lock, flags);
190 usbip_start_eh(&udc->ud);
191 } else {
192 /* Invalidate descriptors */
193 udc->desc_cached = 0;
194
195 spin_unlock_irqrestore(&udc->lock, flags);
196 usbip_event_add(&udc->ud, VUDC_EVENT_REMOVED);
197 usbip_stop_eh(&udc->ud); /* Wait for eh completion */
198 }
199
200 return 0;
201
202unlock:
203 spin_unlock_irqrestore(&udc->lock, flags);
204 return 0;
205}
206
207static int vgadget_udc_start(struct usb_gadget *g,
208 struct usb_gadget_driver *driver)
209{
210 struct vudc *udc = usb_gadget_to_vudc(g);
211 unsigned long flags;
212
213 spin_lock_irqsave(&udc->lock, flags);
214 udc->driver = driver;
215 udc->pullup = udc->connected = udc->desc_cached = 0;
216 spin_unlock_irqrestore(&udc->lock, flags);
217
218 return 0;
219}
220
221static int vgadget_udc_stop(struct usb_gadget *g)
222{
223 struct vudc *udc = usb_gadget_to_vudc(g);
224 unsigned long flags;
225
226 spin_lock_irqsave(&udc->lock, flags);
227 udc->driver = NULL;
228 spin_unlock_irqrestore(&udc->lock, flags);
229 return 0;
230}
231
232static const struct usb_gadget_ops vgadget_ops = {
233 .get_frame = vgadget_get_frame,
234 .set_selfpowered = vgadget_set_selfpowered,
235 .pullup = vgadget_pullup,
236 .udc_start = vgadget_udc_start,
237 .udc_stop = vgadget_udc_stop,
238};
239
240
241/* endpoint ops */
242
243static int vep_enable(struct usb_ep *_ep,
244 const struct usb_endpoint_descriptor *desc)
245{
Jai Krishna1f0c41d2016-10-25 14:32:32 +0530246 struct vep *ep;
247 struct vudc *udc;
248 unsigned int maxp;
249 unsigned long flags;
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100250
251 ep = to_vep(_ep);
252 udc = ep_to_vudc(ep);
253
254 if (!_ep || !desc || ep->desc || _ep->caps.type_control
255 || desc->bDescriptorType != USB_DT_ENDPOINT)
256 return -EINVAL;
257
258 if (!udc->driver)
259 return -ESHUTDOWN;
260
261 spin_lock_irqsave(&udc->lock, flags);
262
Felipe Balbi14f91dd2016-09-28 14:17:38 +0300263 maxp = usb_endpoint_maxp(desc);
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100264 _ep->maxpacket = maxp;
265 ep->desc = desc;
266 ep->type = usb_endpoint_type(desc);
267 ep->halted = ep->wedged = 0;
268
269 spin_unlock_irqrestore(&udc->lock, flags);
270
271 return 0;
272}
273
274static int vep_disable(struct usb_ep *_ep)
275{
276 struct vep *ep;
277 struct vudc *udc;
278 unsigned long flags;
279
280 ep = to_vep(_ep);
281 udc = ep_to_vudc(ep);
282 if (!_ep || !ep->desc || _ep->caps.type_control)
283 return -EINVAL;
284
285 spin_lock_irqsave(&udc->lock, flags);
286 ep->desc = NULL;
287 nuke(udc, ep);
288 spin_unlock_irqrestore(&udc->lock, flags);
289
290 return 0;
291}
292
293static struct usb_request *vep_alloc_request(struct usb_ep *_ep,
294 gfp_t mem_flags)
295{
296 struct vep *ep;
297 struct vrequest *req;
298
299 if (!_ep)
300 return NULL;
301 ep = to_vep(_ep);
302
303 req = kzalloc(sizeof(*req), mem_flags);
304 if (!req)
305 return NULL;
306
307 INIT_LIST_HEAD(&req->req_entry);
308
309 return &req->req;
310}
311
312static void vep_free_request(struct usb_ep *_ep, struct usb_request *_req)
313{
314 struct vrequest *req;
315
Krzysztof Opasiak2bdf6ea2016-04-27 20:00:26 +0200316 if (WARN_ON(!_ep || !_req))
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100317 return;
Krzysztof Opasiak2bdf6ea2016-04-27 20:00:26 +0200318
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100319 req = to_vrequest(_req);
320 kfree(req);
321}
322
323static int vep_queue(struct usb_ep *_ep, struct usb_request *_req,
324 gfp_t mem_flags)
325{
326 struct vep *ep;
327 struct vrequest *req;
328 struct vudc *udc;
329 unsigned long flags;
330
331 if (!_ep || !_req)
332 return -EINVAL;
333
334 ep = to_vep(_ep);
335 req = to_vrequest(_req);
336 udc = ep_to_vudc(ep);
337
338 spin_lock_irqsave(&udc->lock, flags);
339 _req->actual = 0;
340 _req->status = -EINPROGRESS;
341
342 list_add_tail(&req->req_entry, &ep->req_queue);
343 spin_unlock_irqrestore(&udc->lock, flags);
344
345 return 0;
346}
347
348static int vep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
349{
350 struct vep *ep;
351 struct vrequest *req;
352 struct vudc *udc;
353 struct vrequest *lst;
354 unsigned long flags;
355 int ret = -EINVAL;
356
357 if (!_ep || !_req)
358 return ret;
359
360 ep = to_vep(_ep);
361 req = to_vrequest(_req);
362 udc = req->udc;
363
364 if (!udc->driver)
365 return -ESHUTDOWN;
366
367 spin_lock_irqsave(&udc->lock, flags);
368 list_for_each_entry(lst, &ep->req_queue, req_entry) {
369 if (&lst->req == _req) {
370 list_del_init(&lst->req_entry);
371 _req->status = -ECONNRESET;
372 ret = 0;
373 break;
374 }
375 }
376 spin_unlock_irqrestore(&udc->lock, flags);
377
378 if (ret == 0)
379 usb_gadget_giveback_request(_ep, _req);
380
381 return ret;
382}
383
384static int
385vep_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
386{
387 struct vep *ep;
388 struct vudc *udc;
389 unsigned long flags;
390 int ret = 0;
391
392 ep = to_vep(_ep);
393 if (!_ep)
394 return -EINVAL;
395
396 udc = ep_to_vudc(ep);
397 if (!udc->driver)
398 return -ESHUTDOWN;
399
400 spin_lock_irqsave(&udc->lock, flags);
401 if (!value)
402 ep->halted = ep->wedged = 0;
403 else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
404 !list_empty(&ep->req_queue))
405 ret = -EAGAIN;
406 else {
407 ep->halted = 1;
408 if (wedged)
409 ep->wedged = 1;
410 }
411
412 spin_unlock_irqrestore(&udc->lock, flags);
413 return ret;
414}
415
416static int
417vep_set_halt(struct usb_ep *_ep, int value)
418{
419 return vep_set_halt_and_wedge(_ep, value, 0);
420}
421
422static int vep_set_wedge(struct usb_ep *_ep)
423{
424 return vep_set_halt_and_wedge(_ep, 1, 1);
425}
426
427static const struct usb_ep_ops vep_ops = {
428 .enable = vep_enable,
429 .disable = vep_disable,
430
431 .alloc_request = vep_alloc_request,
432 .free_request = vep_free_request,
433
434 .queue = vep_queue,
435 .dequeue = vep_dequeue,
436
437 .set_halt = vep_set_halt,
438 .set_wedge = vep_set_wedge,
439};
440
441
442/* shutdown / reset / error handlers */
443
444static void vudc_shutdown(struct usbip_device *ud)
445{
446 struct vudc *udc = container_of(ud, struct vudc, ud);
447 int call_disconnect = 0;
448 unsigned long flags;
449
450 dev_dbg(&udc->pdev->dev, "device shutdown");
451 if (ud->tcp_socket)
452 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
453
Dave Jones1328f7b2016-05-31 11:25:09 -0400454 if (ud->tcp_rx) {
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100455 kthread_stop_put(ud->tcp_rx);
456 ud->tcp_rx = NULL;
457 }
458 if (ud->tcp_tx) {
459 kthread_stop_put(ud->tcp_tx);
460 ud->tcp_tx = NULL;
461 }
462
463 if (ud->tcp_socket) {
464 sockfd_put(ud->tcp_socket);
465 ud->tcp_socket = NULL;
466 }
467
468 spin_lock_irqsave(&udc->lock, flags);
469 stop_activity(udc);
470 if (udc->connected && udc->driver->disconnect)
471 call_disconnect = 1;
472 udc->connected = 0;
473 spin_unlock_irqrestore(&udc->lock, flags);
474 if (call_disconnect)
475 udc->driver->disconnect(&udc->gadget);
476}
477
478static void vudc_device_reset(struct usbip_device *ud)
479{
480 struct vudc *udc = container_of(ud, struct vudc, ud);
481 unsigned long flags;
482
483 dev_dbg(&udc->pdev->dev, "device reset");
484 spin_lock_irqsave(&udc->lock, flags);
485 stop_activity(udc);
486 spin_unlock_irqrestore(&udc->lock, flags);
487 if (udc->driver)
488 usb_gadget_udc_reset(&udc->gadget, udc->driver);
489 spin_lock_irqsave(&ud->lock, flags);
490 ud->status = SDEV_ST_AVAILABLE;
491 spin_unlock_irqrestore(&ud->lock, flags);
492}
493
494static void vudc_device_unusable(struct usbip_device *ud)
495{
496 unsigned long flags;
497
498 spin_lock_irqsave(&ud->lock, flags);
499 ud->status = SDEV_ST_ERROR;
500 spin_unlock_irqrestore(&ud->lock, flags);
501}
502
503/* device setup / cleanup */
504
505struct vudc_device *alloc_vudc_device(int devid)
506{
507 struct vudc_device *udc_dev = NULL;
508
509 udc_dev = kzalloc(sizeof(*udc_dev), GFP_KERNEL);
510 if (!udc_dev)
511 goto out;
512
513 INIT_LIST_HEAD(&udc_dev->dev_entry);
514
515 udc_dev->pdev = platform_device_alloc(GADGET_NAME, devid);
516 if (!udc_dev->pdev) {
517 kfree(udc_dev);
518 udc_dev = NULL;
519 }
520
521out:
522 return udc_dev;
523}
524
525void put_vudc_device(struct vudc_device *udc_dev)
526{
527 platform_device_put(udc_dev->pdev);
528 kfree(udc_dev);
529}
530
531static int init_vudc_hw(struct vudc *udc)
532{
533 int i;
534 struct usbip_device *ud = &udc->ud;
535 struct vep *ep;
536
537 udc->ep = kcalloc(VIRTUAL_ENDPOINTS, sizeof(*udc->ep), GFP_KERNEL);
538 if (!udc->ep)
539 goto nomem_ep;
540
541 INIT_LIST_HEAD(&udc->gadget.ep_list);
542
543 /* create ep0 and 15 in, 15 out general purpose eps */
544 for (i = 0; i < VIRTUAL_ENDPOINTS; ++i) {
545 int is_out = i % 2;
546 int num = (i + 1) / 2;
547
548 ep = &udc->ep[i];
549
550 sprintf(ep->name, "ep%d%s", num,
551 i ? (is_out ? "out" : "in") : "");
552 ep->ep.name = ep->name;
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100553
554 ep->ep.ops = &vep_ops;
Krzysztof Opasiakb282a112016-12-02 18:42:22 +0100555
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100556 usb_ep_set_maxpacket_limit(&ep->ep, ~0);
557 ep->ep.max_streams = 16;
558 ep->gadget = &udc->gadget;
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100559 INIT_LIST_HEAD(&ep->req_queue);
Krzysztof Opasiakb282a112016-12-02 18:42:22 +0100560
561 if (i == 0) {
562 /* ep0 */
563 ep->ep.caps.type_control = true;
564 ep->ep.caps.dir_out = true;
565 ep->ep.caps.dir_in = true;
566
567 udc->gadget.ep0 = &ep->ep;
568 } else {
569 /* All other eps */
570 ep->ep.caps.type_iso = true;
571 ep->ep.caps.type_int = true;
572 ep->ep.caps.type_bulk = true;
573
574 if (is_out)
575 ep->ep.caps.dir_out = true;
576 else
577 ep->ep.caps.dir_in = true;
578
579 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
580 }
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100581 }
582
583 spin_lock_init(&udc->lock);
584 spin_lock_init(&udc->lock_tx);
585 INIT_LIST_HEAD(&udc->urb_queue);
586 INIT_LIST_HEAD(&udc->tx_queue);
587 init_waitqueue_head(&udc->tx_waitq);
588
589 spin_lock_init(&ud->lock);
590 ud->status = SDEV_ST_AVAILABLE;
591 ud->side = USBIP_VUDC;
592
593 ud->eh_ops.shutdown = vudc_shutdown;
594 ud->eh_ops.reset = vudc_device_reset;
595 ud->eh_ops.unusable = vudc_device_unusable;
596
Igor Kotrasinskib6a0ca12016-03-08 21:49:02 +0100597 v_init_timer(udc);
598 return 0;
599
600nomem_ep:
601 return -ENOMEM;
602}
603
604static void cleanup_vudc_hw(struct vudc *udc)
605{
606 kfree(udc->ep);
607}
608
609/* platform driver ops */
610
611int vudc_probe(struct platform_device *pdev)
612{
613 struct vudc *udc;
614 int ret = -ENOMEM;
615
616 udc = kzalloc(sizeof(*udc), GFP_KERNEL);
617 if (!udc)
618 goto out;
619
620 udc->gadget.name = GADGET_NAME;
621 udc->gadget.ops = &vgadget_ops;
622 udc->gadget.max_speed = USB_SPEED_HIGH;
623 udc->gadget.dev.parent = &pdev->dev;
624 udc->pdev = pdev;
625
626 ret = init_vudc_hw(udc);
627 if (ret)
628 goto err_init_vudc_hw;
629
630 ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
631 if (ret < 0)
632 goto err_add_udc;
633
634 ret = sysfs_create_group(&pdev->dev.kobj, &vudc_attr_group);
635 if (ret) {
636 dev_err(&udc->pdev->dev, "create sysfs files\n");
637 goto err_sysfs;
638 }
639
640 platform_set_drvdata(pdev, udc);
641
642 return ret;
643
644err_sysfs:
645 usb_del_gadget_udc(&udc->gadget);
646err_add_udc:
647 cleanup_vudc_hw(udc);
648err_init_vudc_hw:
649 kfree(udc);
650out:
651 return ret;
652}
653
654int vudc_remove(struct platform_device *pdev)
655{
656 struct vudc *udc = platform_get_drvdata(pdev);
657
658 sysfs_remove_group(&pdev->dev.kobj, &vudc_attr_group);
659 usb_del_gadget_udc(&udc->gadget);
660 cleanup_vudc_hw(udc);
661 kfree(udc);
662 return 0;
663}