blob: d86c3a36441ee998f8a8a8f8813ad5478d786281 [file] [log] [blame]
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * USB Raw Gadget driver.
4 * See Documentation/usb/raw-gadget.rst for more details.
5 *
Andrey Konovalov4c1934b2021-01-23 20:14:16 +01006 * Copyright (c) 2020 Google, Inc.
7 * Author: Andrey Konovalov <andreyknvl@gmail.com>
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01008 */
9
10#include <linux/compiler.h>
Andrey Konovalov97df5e52020-05-07 19:06:56 +020011#include <linux/ctype.h>
Andrey Konovalovf2c2e712020-02-24 17:13:03 +010012#include <linux/debugfs.h>
13#include <linux/delay.h>
14#include <linux/kref.h>
15#include <linux/miscdevice.h>
16#include <linux/module.h>
17#include <linux/semaphore.h>
18#include <linux/sched.h>
19#include <linux/slab.h>
20#include <linux/uaccess.h>
21#include <linux/wait.h>
22
23#include <linux/usb.h>
24#include <linux/usb/ch9.h>
25#include <linux/usb/ch11.h>
26#include <linux/usb/gadget.h>
27
28#include <uapi/linux/usb/raw_gadget.h>
29
30#define DRIVER_DESC "USB Raw Gadget"
31#define DRIVER_NAME "raw-gadget"
32
33MODULE_DESCRIPTION(DRIVER_DESC);
34MODULE_AUTHOR("Andrey Konovalov");
35MODULE_LICENSE("GPL");
36
37/*----------------------------------------------------------------------*/
38
39#define RAW_EVENT_QUEUE_SIZE 16
40
41struct raw_event_queue {
42 /* See the comment in raw_event_queue_fetch() for locking details. */
43 spinlock_t lock;
44 struct semaphore sema;
45 struct usb_raw_event *events[RAW_EVENT_QUEUE_SIZE];
46 int size;
47};
48
49static void raw_event_queue_init(struct raw_event_queue *queue)
50{
51 spin_lock_init(&queue->lock);
52 sema_init(&queue->sema, 0);
53 queue->size = 0;
54}
55
56static int raw_event_queue_add(struct raw_event_queue *queue,
57 enum usb_raw_event_type type, size_t length, const void *data)
58{
59 unsigned long flags;
60 struct usb_raw_event *event;
61
62 spin_lock_irqsave(&queue->lock, flags);
63 if (WARN_ON(queue->size >= RAW_EVENT_QUEUE_SIZE)) {
64 spin_unlock_irqrestore(&queue->lock, flags);
65 return -ENOMEM;
66 }
67 event = kmalloc(sizeof(*event) + length, GFP_ATOMIC);
68 if (!event) {
69 spin_unlock_irqrestore(&queue->lock, flags);
70 return -ENOMEM;
71 }
72 event->type = type;
73 event->length = length;
74 if (event->length)
75 memcpy(&event->data[0], data, length);
76 queue->events[queue->size] = event;
77 queue->size++;
78 up(&queue->sema);
79 spin_unlock_irqrestore(&queue->lock, flags);
80 return 0;
81}
82
83static struct usb_raw_event *raw_event_queue_fetch(
84 struct raw_event_queue *queue)
85{
Andrey Konovalovfdd10492020-04-07 16:47:54 +020086 int ret;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +010087 unsigned long flags;
88 struct usb_raw_event *event;
89
90 /*
91 * This function can be called concurrently. We first check that
92 * there's at least one event queued by decrementing the semaphore,
93 * and then take the lock to protect queue struct fields.
94 */
Andrey Konovalovfdd10492020-04-07 16:47:54 +020095 ret = down_interruptible(&queue->sema);
96 if (ret)
97 return ERR_PTR(ret);
Andrey Konovalovf2c2e712020-02-24 17:13:03 +010098 spin_lock_irqsave(&queue->lock, flags);
Andrey Konovalovfdd10492020-04-07 16:47:54 +020099 /*
100 * queue->size must have the same value as queue->sema counter (before
101 * the down_interruptible() call above), so this check is a fail-safe.
102 */
103 if (WARN_ON(!queue->size)) {
104 spin_unlock_irqrestore(&queue->lock, flags);
105 return ERR_PTR(-ENODEV);
106 }
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100107 event = queue->events[0];
108 queue->size--;
109 memmove(&queue->events[0], &queue->events[1],
110 queue->size * sizeof(queue->events[0]));
111 spin_unlock_irqrestore(&queue->lock, flags);
112 return event;
113}
114
115static void raw_event_queue_destroy(struct raw_event_queue *queue)
116{
117 int i;
118
119 for (i = 0; i < queue->size; i++)
120 kfree(queue->events[i]);
121 queue->size = 0;
122}
123
124/*----------------------------------------------------------------------*/
125
126struct raw_dev;
127
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100128enum ep_state {
129 STATE_EP_DISABLED,
130 STATE_EP_ENABLED,
131};
132
133struct raw_ep {
134 struct raw_dev *dev;
135 enum ep_state state;
136 struct usb_ep *ep;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200137 u8 addr;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100138 struct usb_request *req;
139 bool urb_queued;
140 bool disabling;
141 ssize_t status;
142};
143
144enum dev_state {
145 STATE_DEV_INVALID = 0,
146 STATE_DEV_OPENED,
147 STATE_DEV_INITIALIZED,
148 STATE_DEV_RUNNING,
149 STATE_DEV_CLOSED,
150 STATE_DEV_FAILED
151};
152
153struct raw_dev {
154 struct kref count;
155 spinlock_t lock;
156
157 const char *udc_name;
158 struct usb_gadget_driver driver;
159
160 /* Reference to misc device: */
161 struct device *dev;
162
163 /* Protected by lock: */
164 enum dev_state state;
165 bool gadget_registered;
166 struct usb_gadget *gadget;
167 struct usb_request *req;
168 bool ep0_in_pending;
169 bool ep0_out_pending;
170 bool ep0_urb_queued;
171 ssize_t ep0_status;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200172 struct raw_ep eps[USB_RAW_EPS_NUM_MAX];
173 int eps_num;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100174
175 struct completion ep0_done;
176 struct raw_event_queue queue;
177};
178
179static struct raw_dev *dev_new(void)
180{
181 struct raw_dev *dev;
182
183 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
184 if (!dev)
185 return NULL;
186 /* Matches kref_put() in raw_release(). */
187 kref_init(&dev->count);
188 spin_lock_init(&dev->lock);
189 init_completion(&dev->ep0_done);
190 raw_event_queue_init(&dev->queue);
191 return dev;
192}
193
194static void dev_free(struct kref *kref)
195{
196 struct raw_dev *dev = container_of(kref, struct raw_dev, count);
197 int i;
198
199 kfree(dev->udc_name);
200 kfree(dev->driver.udc_name);
201 if (dev->req) {
202 if (dev->ep0_urb_queued)
203 usb_ep_dequeue(dev->gadget->ep0, dev->req);
204 usb_ep_free_request(dev->gadget->ep0, dev->req);
205 }
206 raw_event_queue_destroy(&dev->queue);
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200207 for (i = 0; i < dev->eps_num; i++) {
Andrey Konovalovc61769b2020-05-07 19:06:57 +0200208 if (dev->eps[i].state == STATE_EP_DISABLED)
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100209 continue;
210 usb_ep_disable(dev->eps[i].ep);
211 usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req);
212 kfree(dev->eps[i].ep->desc);
213 dev->eps[i].state = STATE_EP_DISABLED;
214 }
215 kfree(dev);
216}
217
218/*----------------------------------------------------------------------*/
219
220static int raw_queue_event(struct raw_dev *dev,
221 enum usb_raw_event_type type, size_t length, const void *data)
222{
223 int ret = 0;
224 unsigned long flags;
225
226 ret = raw_event_queue_add(&dev->queue, type, length, data);
227 if (ret < 0) {
228 spin_lock_irqsave(&dev->lock, flags);
229 dev->state = STATE_DEV_FAILED;
230 spin_unlock_irqrestore(&dev->lock, flags);
231 }
232 return ret;
233}
234
235static void gadget_ep0_complete(struct usb_ep *ep, struct usb_request *req)
236{
237 struct raw_dev *dev = req->context;
238 unsigned long flags;
239
240 spin_lock_irqsave(&dev->lock, flags);
241 if (req->status)
242 dev->ep0_status = req->status;
243 else
244 dev->ep0_status = req->actual;
245 if (dev->ep0_in_pending)
246 dev->ep0_in_pending = false;
247 else
248 dev->ep0_out_pending = false;
249 spin_unlock_irqrestore(&dev->lock, flags);
250
251 complete(&dev->ep0_done);
252}
253
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200254static u8 get_ep_addr(const char *name)
255{
256 /* If the endpoint has fixed function (named as e.g. "ep12out-bulk"),
257 * parse the endpoint address from its name. We deliberately use
258 * deprecated simple_strtoul() function here, as the number isn't
259 * followed by '\0' nor '\n'.
260 */
261 if (isdigit(name[2]))
262 return simple_strtoul(&name[2], NULL, 10);
263 /* Otherwise the endpoint is configurable (named as e.g. "ep-a"). */
264 return USB_RAW_EP_ADDR_ANY;
265}
266
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100267static int gadget_bind(struct usb_gadget *gadget,
268 struct usb_gadget_driver *driver)
269{
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200270 int ret = 0, i = 0;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100271 struct raw_dev *dev = container_of(driver, struct raw_dev, driver);
272 struct usb_request *req;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200273 struct usb_ep *ep;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100274 unsigned long flags;
275
276 if (strcmp(gadget->name, dev->udc_name) != 0)
277 return -ENODEV;
278
279 set_gadget_data(gadget, dev);
280 req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
281 if (!req) {
282 dev_err(&gadget->dev, "usb_ep_alloc_request failed\n");
283 set_gadget_data(gadget, NULL);
284 return -ENOMEM;
285 }
286
287 spin_lock_irqsave(&dev->lock, flags);
288 dev->req = req;
289 dev->req->context = dev;
290 dev->req->complete = gadget_ep0_complete;
291 dev->gadget = gadget;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200292 gadget_for_each_ep(ep, dev->gadget) {
293 dev->eps[i].ep = ep;
294 dev->eps[i].addr = get_ep_addr(ep->name);
295 dev->eps[i].state = STATE_EP_DISABLED;
296 i++;
297 }
298 dev->eps_num = i;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100299 spin_unlock_irqrestore(&dev->lock, flags);
300
301 /* Matches kref_put() in gadget_unbind(). */
302 kref_get(&dev->count);
303
304 ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL);
305 if (ret < 0)
306 dev_err(&gadget->dev, "failed to queue event\n");
307
308 return ret;
309}
310
311static void gadget_unbind(struct usb_gadget *gadget)
312{
313 struct raw_dev *dev = get_gadget_data(gadget);
314
315 set_gadget_data(gadget, NULL);
316 /* Matches kref_get() in gadget_bind(). */
317 kref_put(&dev->count, dev_free);
318}
319
320static int gadget_setup(struct usb_gadget *gadget,
321 const struct usb_ctrlrequest *ctrl)
322{
323 int ret = 0;
324 struct raw_dev *dev = get_gadget_data(gadget);
325 unsigned long flags;
326
327 spin_lock_irqsave(&dev->lock, flags);
328 if (dev->state != STATE_DEV_RUNNING) {
329 dev_err(&gadget->dev, "ignoring, device is not running\n");
330 ret = -ENODEV;
331 goto out_unlock;
332 }
333 if (dev->ep0_in_pending || dev->ep0_out_pending) {
334 dev_dbg(&gadget->dev, "stalling, request already pending\n");
335 ret = -EBUSY;
336 goto out_unlock;
337 }
338 if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength)
339 dev->ep0_in_pending = true;
340 else
341 dev->ep0_out_pending = true;
342 spin_unlock_irqrestore(&dev->lock, flags);
343
344 ret = raw_queue_event(dev, USB_RAW_EVENT_CONTROL, sizeof(*ctrl), ctrl);
345 if (ret < 0)
346 dev_err(&gadget->dev, "failed to queue event\n");
347 goto out;
348
349out_unlock:
350 spin_unlock_irqrestore(&dev->lock, flags);
351out:
352 return ret;
353}
354
355/* These are currently unused but present in case UDC driver requires them. */
356static void gadget_disconnect(struct usb_gadget *gadget) { }
357static void gadget_suspend(struct usb_gadget *gadget) { }
358static void gadget_resume(struct usb_gadget *gadget) { }
359static void gadget_reset(struct usb_gadget *gadget) { }
360
361/*----------------------------------------------------------------------*/
362
363static struct miscdevice raw_misc_device;
364
365static int raw_open(struct inode *inode, struct file *fd)
366{
367 struct raw_dev *dev;
368
369 /* Nonblocking I/O is not supported yet. */
370 if (fd->f_flags & O_NONBLOCK)
371 return -EINVAL;
372
373 dev = dev_new();
374 if (!dev)
375 return -ENOMEM;
376 fd->private_data = dev;
377 dev->state = STATE_DEV_OPENED;
378 dev->dev = raw_misc_device.this_device;
379 return 0;
380}
381
382static int raw_release(struct inode *inode, struct file *fd)
383{
384 int ret = 0;
385 struct raw_dev *dev = fd->private_data;
386 unsigned long flags;
387 bool unregister = false;
388
389 spin_lock_irqsave(&dev->lock, flags);
390 dev->state = STATE_DEV_CLOSED;
391 if (!dev->gadget) {
392 spin_unlock_irqrestore(&dev->lock, flags);
393 goto out_put;
394 }
395 if (dev->gadget_registered)
396 unregister = true;
397 dev->gadget_registered = false;
398 spin_unlock_irqrestore(&dev->lock, flags);
399
400 if (unregister) {
401 ret = usb_gadget_unregister_driver(&dev->driver);
402 if (ret != 0)
403 dev_err(dev->dev,
404 "usb_gadget_unregister_driver() failed with %d\n",
405 ret);
406 /* Matches kref_get() in raw_ioctl_run(). */
407 kref_put(&dev->count, dev_free);
408 }
409
410out_put:
411 /* Matches dev_new() in raw_open(). */
412 kref_put(&dev->count, dev_free);
413 return ret;
414}
415
416/*----------------------------------------------------------------------*/
417
418static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
419{
420 int ret = 0;
421 struct usb_raw_init arg;
422 char *udc_driver_name;
423 char *udc_device_name;
424 unsigned long flags;
425
Dan Carpenter068fbff2020-04-06 17:51:19 +0300426 if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
427 return -EFAULT;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100428
429 switch (arg.speed) {
430 case USB_SPEED_UNKNOWN:
431 arg.speed = USB_SPEED_HIGH;
432 break;
433 case USB_SPEED_LOW:
434 case USB_SPEED_FULL:
435 case USB_SPEED_HIGH:
436 case USB_SPEED_SUPER:
437 break;
438 default:
439 return -EINVAL;
440 }
441
442 udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);
443 if (!udc_driver_name)
444 return -ENOMEM;
445 ret = strscpy(udc_driver_name, &arg.driver_name[0],
446 UDC_NAME_LENGTH_MAX);
447 if (ret < 0) {
448 kfree(udc_driver_name);
449 return ret;
450 }
451 ret = 0;
452
453 udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);
454 if (!udc_device_name) {
455 kfree(udc_driver_name);
456 return -ENOMEM;
457 }
458 ret = strscpy(udc_device_name, &arg.device_name[0],
459 UDC_NAME_LENGTH_MAX);
460 if (ret < 0) {
461 kfree(udc_driver_name);
462 kfree(udc_device_name);
463 return ret;
464 }
465 ret = 0;
466
467 spin_lock_irqsave(&dev->lock, flags);
468 if (dev->state != STATE_DEV_OPENED) {
469 dev_dbg(dev->dev, "fail, device is not opened\n");
470 kfree(udc_driver_name);
471 kfree(udc_device_name);
472 ret = -EINVAL;
473 goto out_unlock;
474 }
475 dev->udc_name = udc_driver_name;
476
477 dev->driver.function = DRIVER_DESC;
478 dev->driver.max_speed = arg.speed;
479 dev->driver.setup = gadget_setup;
480 dev->driver.disconnect = gadget_disconnect;
481 dev->driver.bind = gadget_bind;
482 dev->driver.unbind = gadget_unbind;
483 dev->driver.suspend = gadget_suspend;
484 dev->driver.resume = gadget_resume;
485 dev->driver.reset = gadget_reset;
486 dev->driver.driver.name = DRIVER_NAME;
487 dev->driver.udc_name = udc_device_name;
488 dev->driver.match_existing_only = 1;
489
490 dev->state = STATE_DEV_INITIALIZED;
491
492out_unlock:
493 spin_unlock_irqrestore(&dev->lock, flags);
494 return ret;
495}
496
497static int raw_ioctl_run(struct raw_dev *dev, unsigned long value)
498{
499 int ret = 0;
500 unsigned long flags;
501
502 if (value)
503 return -EINVAL;
504
505 spin_lock_irqsave(&dev->lock, flags);
506 if (dev->state != STATE_DEV_INITIALIZED) {
507 dev_dbg(dev->dev, "fail, device is not initialized\n");
508 ret = -EINVAL;
509 goto out_unlock;
510 }
511 spin_unlock_irqrestore(&dev->lock, flags);
512
513 ret = usb_gadget_probe_driver(&dev->driver);
514
515 spin_lock_irqsave(&dev->lock, flags);
516 if (ret) {
517 dev_err(dev->dev,
518 "fail, usb_gadget_probe_driver returned %d\n", ret);
519 dev->state = STATE_DEV_FAILED;
520 goto out_unlock;
521 }
522 dev->gadget_registered = true;
523 dev->state = STATE_DEV_RUNNING;
524 /* Matches kref_put() in raw_release(). */
525 kref_get(&dev->count);
526
527out_unlock:
528 spin_unlock_irqrestore(&dev->lock, flags);
529 return ret;
530}
531
532static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
533{
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100534 struct usb_raw_event arg;
535 unsigned long flags;
536 struct usb_raw_event *event;
537 uint32_t length;
538
Dan Carpenter068fbff2020-04-06 17:51:19 +0300539 if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
540 return -EFAULT;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100541
542 spin_lock_irqsave(&dev->lock, flags);
543 if (dev->state != STATE_DEV_RUNNING) {
544 dev_dbg(dev->dev, "fail, device is not running\n");
545 spin_unlock_irqrestore(&dev->lock, flags);
546 return -EINVAL;
547 }
548 if (!dev->gadget) {
549 dev_dbg(dev->dev, "fail, gadget is not bound\n");
550 spin_unlock_irqrestore(&dev->lock, flags);
551 return -EBUSY;
552 }
553 spin_unlock_irqrestore(&dev->lock, flags);
554
555 event = raw_event_queue_fetch(&dev->queue);
Andrey Konovalovfdd10492020-04-07 16:47:54 +0200556 if (PTR_ERR(event) == -EINTR) {
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100557 dev_dbg(&dev->gadget->dev, "event fetching interrupted\n");
558 return -EINTR;
559 }
Andrey Konovalovfdd10492020-04-07 16:47:54 +0200560 if (IS_ERR(event)) {
561 dev_err(&dev->gadget->dev, "failed to fetch event\n");
562 spin_lock_irqsave(&dev->lock, flags);
563 dev->state = STATE_DEV_FAILED;
564 spin_unlock_irqrestore(&dev->lock, flags);
565 return -ENODEV;
566 }
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100567 length = min(arg.length, event->length);
Zqiang129aa972020-10-27 15:30:44 +0800568 if (copy_to_user((void __user *)value, event, sizeof(*event) + length)) {
569 kfree(event);
Dan Carpenter068fbff2020-04-06 17:51:19 +0300570 return -EFAULT;
Zqiang129aa972020-10-27 15:30:44 +0800571 }
Dan Carpenter068fbff2020-04-06 17:51:19 +0300572
Zqiang129aa972020-10-27 15:30:44 +0800573 kfree(event);
Dan Carpenter068fbff2020-04-06 17:51:19 +0300574 return 0;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100575}
576
577static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
578 bool get_from_user)
579{
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100580 void *data;
581
Dan Carpenter068fbff2020-04-06 17:51:19 +0300582 if (copy_from_user(io, ptr, sizeof(*io)))
583 return ERR_PTR(-EFAULT);
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200584 if (io->ep >= USB_RAW_EPS_NUM_MAX)
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100585 return ERR_PTR(-EINVAL);
586 if (!usb_raw_io_flags_valid(io->flags))
587 return ERR_PTR(-EINVAL);
588 if (io->length > PAGE_SIZE)
589 return ERR_PTR(-EINVAL);
590 if (get_from_user)
591 data = memdup_user(ptr + sizeof(*io), io->length);
592 else {
593 data = kmalloc(io->length, GFP_KERNEL);
594 if (!data)
595 data = ERR_PTR(-ENOMEM);
596 }
597 return data;
598}
599
600static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io,
601 void *data, bool in)
602{
603 int ret = 0;
604 unsigned long flags;
605
606 spin_lock_irqsave(&dev->lock, flags);
607 if (dev->state != STATE_DEV_RUNNING) {
608 dev_dbg(dev->dev, "fail, device is not running\n");
609 ret = -EINVAL;
610 goto out_unlock;
611 }
612 if (!dev->gadget) {
613 dev_dbg(dev->dev, "fail, gadget is not bound\n");
614 ret = -EBUSY;
615 goto out_unlock;
616 }
617 if (dev->ep0_urb_queued) {
618 dev_dbg(&dev->gadget->dev, "fail, urb already queued\n");
619 ret = -EBUSY;
620 goto out_unlock;
621 }
622 if ((in && !dev->ep0_in_pending) ||
623 (!in && !dev->ep0_out_pending)) {
624 dev_dbg(&dev->gadget->dev, "fail, wrong direction\n");
625 ret = -EBUSY;
626 goto out_unlock;
627 }
628 if (WARN_ON(in && dev->ep0_out_pending)) {
629 ret = -ENODEV;
630 dev->state = STATE_DEV_FAILED;
631 goto out_done;
632 }
633 if (WARN_ON(!in && dev->ep0_in_pending)) {
634 ret = -ENODEV;
635 dev->state = STATE_DEV_FAILED;
636 goto out_done;
637 }
638
639 dev->req->buf = data;
640 dev->req->length = io->length;
641 dev->req->zero = usb_raw_io_flags_zero(io->flags);
642 dev->ep0_urb_queued = true;
643 spin_unlock_irqrestore(&dev->lock, flags);
644
645 ret = usb_ep_queue(dev->gadget->ep0, dev->req, GFP_KERNEL);
646 if (ret) {
647 dev_err(&dev->gadget->dev,
648 "fail, usb_ep_queue returned %d\n", ret);
649 spin_lock_irqsave(&dev->lock, flags);
650 dev->state = STATE_DEV_FAILED;
651 goto out_done;
652 }
653
654 ret = wait_for_completion_interruptible(&dev->ep0_done);
655 if (ret) {
656 dev_dbg(&dev->gadget->dev, "wait interrupted\n");
657 usb_ep_dequeue(dev->gadget->ep0, dev->req);
658 wait_for_completion(&dev->ep0_done);
659 spin_lock_irqsave(&dev->lock, flags);
660 goto out_done;
661 }
662
663 spin_lock_irqsave(&dev->lock, flags);
664 ret = dev->ep0_status;
665
666out_done:
667 dev->ep0_urb_queued = false;
668out_unlock:
669 spin_unlock_irqrestore(&dev->lock, flags);
670 return ret;
671}
672
673static int raw_ioctl_ep0_write(struct raw_dev *dev, unsigned long value)
674{
675 int ret = 0;
676 void *data;
677 struct usb_raw_ep_io io;
678
679 data = raw_alloc_io_data(&io, (void __user *)value, true);
680 if (IS_ERR(data))
681 return PTR_ERR(data);
682 ret = raw_process_ep0_io(dev, &io, data, true);
683 kfree(data);
684 return ret;
685}
686
687static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value)
688{
689 int ret = 0;
690 void *data;
691 struct usb_raw_ep_io io;
692 unsigned int length;
693
694 data = raw_alloc_io_data(&io, (void __user *)value, false);
695 if (IS_ERR(data))
696 return PTR_ERR(data);
697 ret = raw_process_ep0_io(dev, &io, data, false);
Andrey Konovalov6e507642020-05-07 19:06:54 +0200698 if (ret < 0)
Dan Carpenter068fbff2020-04-06 17:51:19 +0300699 goto free;
700
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100701 length = min(io.length, (unsigned int)ret);
Dan Carpenter068fbff2020-04-06 17:51:19 +0300702 if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
703 ret = -EFAULT;
Andrey Konovalov6e507642020-05-07 19:06:54 +0200704 else
705 ret = length;
Dan Carpenter068fbff2020-04-06 17:51:19 +0300706free:
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100707 kfree(data);
708 return ret;
709}
710
Andrey Konovalovc61769b2020-05-07 19:06:57 +0200711static int raw_ioctl_ep0_stall(struct raw_dev *dev, unsigned long value)
712{
713 int ret = 0;
714 unsigned long flags;
715
716 if (value)
717 return -EINVAL;
718 spin_lock_irqsave(&dev->lock, flags);
719 if (dev->state != STATE_DEV_RUNNING) {
720 dev_dbg(dev->dev, "fail, device is not running\n");
721 ret = -EINVAL;
722 goto out_unlock;
723 }
724 if (!dev->gadget) {
725 dev_dbg(dev->dev, "fail, gadget is not bound\n");
726 ret = -EBUSY;
727 goto out_unlock;
728 }
729 if (dev->ep0_urb_queued) {
730 dev_dbg(&dev->gadget->dev, "fail, urb already queued\n");
731 ret = -EBUSY;
732 goto out_unlock;
733 }
734 if (!dev->ep0_in_pending && !dev->ep0_out_pending) {
735 dev_dbg(&dev->gadget->dev, "fail, no request pending\n");
736 ret = -EBUSY;
737 goto out_unlock;
738 }
739
740 ret = usb_ep_set_halt(dev->gadget->ep0);
741 if (ret < 0)
742 dev_err(&dev->gadget->dev,
743 "fail, usb_ep_set_halt returned %d\n", ret);
744
745 if (dev->ep0_in_pending)
746 dev->ep0_in_pending = false;
747 else
748 dev->ep0_out_pending = false;
749
750out_unlock:
751 spin_unlock_irqrestore(&dev->lock, flags);
752 return ret;
753}
754
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100755static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)
756{
757 int ret = 0, i;
758 unsigned long flags;
759 struct usb_endpoint_descriptor *desc;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200760 struct raw_ep *ep;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100761
762 desc = memdup_user((void __user *)value, sizeof(*desc));
763 if (IS_ERR(desc))
764 return PTR_ERR(desc);
765
766 /*
767 * Endpoints with a maxpacket length of 0 can cause crashes in UDC
768 * drivers.
769 */
770 if (usb_endpoint_maxp(desc) == 0) {
771 dev_dbg(dev->dev, "fail, bad endpoint maxpacket\n");
772 kfree(desc);
773 return -EINVAL;
774 }
775
776 spin_lock_irqsave(&dev->lock, flags);
777 if (dev->state != STATE_DEV_RUNNING) {
778 dev_dbg(dev->dev, "fail, device is not running\n");
779 ret = -EINVAL;
780 goto out_free;
781 }
782 if (!dev->gadget) {
783 dev_dbg(dev->dev, "fail, gadget is not bound\n");
784 ret = -EBUSY;
785 goto out_free;
786 }
787
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200788 for (i = 0; i < dev->eps_num; i++) {
789 ep = &dev->eps[i];
790 if (ep->state != STATE_EP_DISABLED)
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100791 continue;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200792 if (ep->addr != usb_endpoint_num(desc) &&
793 ep->addr != USB_RAW_EP_ADDR_ANY)
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100794 continue;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200795 if (!usb_gadget_ep_match_desc(dev->gadget, ep->ep, desc, NULL))
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100796 continue;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200797 ep->ep->desc = desc;
798 ret = usb_ep_enable(ep->ep);
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100799 if (ret < 0) {
800 dev_err(&dev->gadget->dev,
801 "fail, usb_ep_enable returned %d\n", ret);
802 goto out_free;
803 }
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200804 ep->req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC);
805 if (!ep->req) {
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100806 dev_err(&dev->gadget->dev,
807 "fail, usb_ep_alloc_request failed\n");
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200808 usb_ep_disable(ep->ep);
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100809 ret = -ENOMEM;
810 goto out_free;
811 }
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200812 ep->state = STATE_EP_ENABLED;
813 ep->ep->driver_data = ep;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100814 ret = i;
815 goto out_unlock;
816 }
817
818 dev_dbg(&dev->gadget->dev, "fail, no gadget endpoints available\n");
819 ret = -EBUSY;
820
821out_free:
822 kfree(desc);
823out_unlock:
824 spin_unlock_irqrestore(&dev->lock, flags);
825 return ret;
826}
827
828static int raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value)
829{
830 int ret = 0, i = value;
831 unsigned long flags;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100832
833 spin_lock_irqsave(&dev->lock, flags);
834 if (dev->state != STATE_DEV_RUNNING) {
835 dev_dbg(dev->dev, "fail, device is not running\n");
836 ret = -EINVAL;
837 goto out_unlock;
838 }
839 if (!dev->gadget) {
840 dev_dbg(dev->dev, "fail, gadget is not bound\n");
841 ret = -EBUSY;
842 goto out_unlock;
843 }
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200844 if (i < 0 || i >= dev->eps_num) {
845 dev_dbg(dev->dev, "fail, invalid endpoint\n");
846 ret = -EBUSY;
847 goto out_unlock;
848 }
Andrey Konovalovc61769b2020-05-07 19:06:57 +0200849 if (dev->eps[i].state == STATE_EP_DISABLED) {
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100850 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");
851 ret = -EINVAL;
852 goto out_unlock;
853 }
854 if (dev->eps[i].disabling) {
855 dev_dbg(&dev->gadget->dev,
856 "fail, disable already in progress\n");
857 ret = -EINVAL;
858 goto out_unlock;
859 }
860 if (dev->eps[i].urb_queued) {
861 dev_dbg(&dev->gadget->dev,
862 "fail, waiting for urb completion\n");
863 ret = -EINVAL;
864 goto out_unlock;
865 }
866 dev->eps[i].disabling = true;
867 spin_unlock_irqrestore(&dev->lock, flags);
868
869 usb_ep_disable(dev->eps[i].ep);
870
871 spin_lock_irqsave(&dev->lock, flags);
872 usb_ep_free_request(dev->eps[i].ep, dev->eps[i].req);
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200873 kfree(dev->eps[i].ep->desc);
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100874 dev->eps[i].state = STATE_EP_DISABLED;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100875 dev->eps[i].disabling = false;
876
877out_unlock:
878 spin_unlock_irqrestore(&dev->lock, flags);
879 return ret;
880}
881
Andrey Konovalovc61769b2020-05-07 19:06:57 +0200882static int raw_ioctl_ep_set_clear_halt_wedge(struct raw_dev *dev,
883 unsigned long value, bool set, bool halt)
884{
885 int ret = 0, i = value;
886 unsigned long flags;
887
888 spin_lock_irqsave(&dev->lock, flags);
889 if (dev->state != STATE_DEV_RUNNING) {
890 dev_dbg(dev->dev, "fail, device is not running\n");
891 ret = -EINVAL;
892 goto out_unlock;
893 }
894 if (!dev->gadget) {
895 dev_dbg(dev->dev, "fail, gadget is not bound\n");
896 ret = -EBUSY;
897 goto out_unlock;
898 }
899 if (i < 0 || i >= dev->eps_num) {
900 dev_dbg(dev->dev, "fail, invalid endpoint\n");
901 ret = -EBUSY;
902 goto out_unlock;
903 }
904 if (dev->eps[i].state == STATE_EP_DISABLED) {
905 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");
906 ret = -EINVAL;
907 goto out_unlock;
908 }
909 if (dev->eps[i].disabling) {
910 dev_dbg(&dev->gadget->dev,
911 "fail, disable is in progress\n");
912 ret = -EINVAL;
913 goto out_unlock;
914 }
915 if (dev->eps[i].urb_queued) {
916 dev_dbg(&dev->gadget->dev,
917 "fail, waiting for urb completion\n");
918 ret = -EINVAL;
919 goto out_unlock;
920 }
921 if (usb_endpoint_xfer_isoc(dev->eps[i].ep->desc)) {
922 dev_dbg(&dev->gadget->dev,
923 "fail, can't halt/wedge ISO endpoint\n");
924 ret = -EINVAL;
925 goto out_unlock;
926 }
927
928 if (set && halt) {
929 ret = usb_ep_set_halt(dev->eps[i].ep);
930 if (ret < 0)
931 dev_err(&dev->gadget->dev,
932 "fail, usb_ep_set_halt returned %d\n", ret);
933 } else if (!set && halt) {
934 ret = usb_ep_clear_halt(dev->eps[i].ep);
935 if (ret < 0)
936 dev_err(&dev->gadget->dev,
937 "fail, usb_ep_clear_halt returned %d\n", ret);
938 } else if (set && !halt) {
939 ret = usb_ep_set_wedge(dev->eps[i].ep);
940 if (ret < 0)
941 dev_err(&dev->gadget->dev,
942 "fail, usb_ep_set_wedge returned %d\n", ret);
943 }
944
945out_unlock:
946 spin_unlock_irqrestore(&dev->lock, flags);
947 return ret;
948}
949
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100950static void gadget_ep_complete(struct usb_ep *ep, struct usb_request *req)
951{
952 struct raw_ep *r_ep = (struct raw_ep *)ep->driver_data;
953 struct raw_dev *dev = r_ep->dev;
954 unsigned long flags;
955
956 spin_lock_irqsave(&dev->lock, flags);
957 if (req->status)
958 r_ep->status = req->status;
959 else
960 r_ep->status = req->actual;
961 spin_unlock_irqrestore(&dev->lock, flags);
962
963 complete((struct completion *)req->context);
964}
965
966static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io,
967 void *data, bool in)
968{
969 int ret = 0;
970 unsigned long flags;
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200971 struct raw_ep *ep;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100972 DECLARE_COMPLETION_ONSTACK(done);
973
974 spin_lock_irqsave(&dev->lock, flags);
975 if (dev->state != STATE_DEV_RUNNING) {
976 dev_dbg(dev->dev, "fail, device is not running\n");
977 ret = -EINVAL;
978 goto out_unlock;
979 }
980 if (!dev->gadget) {
981 dev_dbg(dev->dev, "fail, gadget is not bound\n");
982 ret = -EBUSY;
983 goto out_unlock;
984 }
Andrey Konovalov97df5e52020-05-07 19:06:56 +0200985 if (io->ep >= dev->eps_num) {
986 dev_dbg(&dev->gadget->dev, "fail, invalid endpoint\n");
987 ret = -EINVAL;
988 goto out_unlock;
989 }
990 ep = &dev->eps[io->ep];
Andrey Konovalovf2c2e712020-02-24 17:13:03 +0100991 if (ep->state != STATE_EP_ENABLED) {
992 dev_dbg(&dev->gadget->dev, "fail, endpoint is not enabled\n");
993 ret = -EBUSY;
994 goto out_unlock;
995 }
996 if (ep->disabling) {
997 dev_dbg(&dev->gadget->dev,
998 "fail, endpoint is already being disabled\n");
999 ret = -EBUSY;
1000 goto out_unlock;
1001 }
1002 if (ep->urb_queued) {
1003 dev_dbg(&dev->gadget->dev, "fail, urb already queued\n");
1004 ret = -EBUSY;
1005 goto out_unlock;
1006 }
Jann Horn292d2c82022-01-26 21:52:14 +01001007 if (in != usb_endpoint_dir_in(ep->ep->desc)) {
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001008 dev_dbg(&dev->gadget->dev, "fail, wrong direction\n");
1009 ret = -EINVAL;
1010 goto out_unlock;
1011 }
1012
1013 ep->dev = dev;
1014 ep->req->context = &done;
1015 ep->req->complete = gadget_ep_complete;
1016 ep->req->buf = data;
1017 ep->req->length = io->length;
1018 ep->req->zero = usb_raw_io_flags_zero(io->flags);
1019 ep->urb_queued = true;
1020 spin_unlock_irqrestore(&dev->lock, flags);
1021
1022 ret = usb_ep_queue(ep->ep, ep->req, GFP_KERNEL);
1023 if (ret) {
1024 dev_err(&dev->gadget->dev,
1025 "fail, usb_ep_queue returned %d\n", ret);
1026 spin_lock_irqsave(&dev->lock, flags);
1027 dev->state = STATE_DEV_FAILED;
1028 goto out_done;
1029 }
1030
1031 ret = wait_for_completion_interruptible(&done);
1032 if (ret) {
1033 dev_dbg(&dev->gadget->dev, "wait interrupted\n");
1034 usb_ep_dequeue(ep->ep, ep->req);
1035 wait_for_completion(&done);
1036 spin_lock_irqsave(&dev->lock, flags);
1037 goto out_done;
1038 }
1039
1040 spin_lock_irqsave(&dev->lock, flags);
1041 ret = ep->status;
1042
1043out_done:
1044 ep->urb_queued = false;
1045out_unlock:
1046 spin_unlock_irqrestore(&dev->lock, flags);
1047 return ret;
1048}
1049
1050static int raw_ioctl_ep_write(struct raw_dev *dev, unsigned long value)
1051{
1052 int ret = 0;
1053 char *data;
1054 struct usb_raw_ep_io io;
1055
1056 data = raw_alloc_io_data(&io, (void __user *)value, true);
1057 if (IS_ERR(data))
1058 return PTR_ERR(data);
1059 ret = raw_process_ep_io(dev, &io, data, true);
1060 kfree(data);
1061 return ret;
1062}
1063
1064static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value)
1065{
1066 int ret = 0;
1067 char *data;
1068 struct usb_raw_ep_io io;
1069 unsigned int length;
1070
1071 data = raw_alloc_io_data(&io, (void __user *)value, false);
1072 if (IS_ERR(data))
1073 return PTR_ERR(data);
1074 ret = raw_process_ep_io(dev, &io, data, false);
Andrey Konovalov6e507642020-05-07 19:06:54 +02001075 if (ret < 0)
Dan Carpenter068fbff2020-04-06 17:51:19 +03001076 goto free;
1077
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001078 length = min(io.length, (unsigned int)ret);
Dan Carpenter068fbff2020-04-06 17:51:19 +03001079 if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
1080 ret = -EFAULT;
Andrey Konovalov6e507642020-05-07 19:06:54 +02001081 else
1082 ret = length;
Dan Carpenter068fbff2020-04-06 17:51:19 +03001083free:
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001084 kfree(data);
1085 return ret;
1086}
1087
1088static int raw_ioctl_configure(struct raw_dev *dev, unsigned long value)
1089{
1090 int ret = 0;
1091 unsigned long flags;
1092
1093 if (value)
1094 return -EINVAL;
1095 spin_lock_irqsave(&dev->lock, flags);
1096 if (dev->state != STATE_DEV_RUNNING) {
1097 dev_dbg(dev->dev, "fail, device is not running\n");
1098 ret = -EINVAL;
1099 goto out_unlock;
1100 }
1101 if (!dev->gadget) {
1102 dev_dbg(dev->dev, "fail, gadget is not bound\n");
1103 ret = -EBUSY;
1104 goto out_unlock;
1105 }
1106 usb_gadget_set_state(dev->gadget, USB_STATE_CONFIGURED);
1107
1108out_unlock:
1109 spin_unlock_irqrestore(&dev->lock, flags);
1110 return ret;
1111}
1112
1113static int raw_ioctl_vbus_draw(struct raw_dev *dev, unsigned long value)
1114{
1115 int ret = 0;
1116 unsigned long flags;
1117
1118 spin_lock_irqsave(&dev->lock, flags);
1119 if (dev->state != STATE_DEV_RUNNING) {
1120 dev_dbg(dev->dev, "fail, device is not running\n");
1121 ret = -EINVAL;
1122 goto out_unlock;
1123 }
1124 if (!dev->gadget) {
1125 dev_dbg(dev->dev, "fail, gadget is not bound\n");
1126 ret = -EBUSY;
1127 goto out_unlock;
1128 }
1129 usb_gadget_vbus_draw(dev->gadget, 2 * value);
1130
1131out_unlock:
1132 spin_unlock_irqrestore(&dev->lock, flags);
1133 return ret;
1134}
1135
Andrey Konovalov97df5e52020-05-07 19:06:56 +02001136static void fill_ep_caps(struct usb_ep_caps *caps,
1137 struct usb_raw_ep_caps *raw_caps)
1138{
1139 raw_caps->type_control = caps->type_control;
1140 raw_caps->type_iso = caps->type_iso;
1141 raw_caps->type_bulk = caps->type_bulk;
1142 raw_caps->type_int = caps->type_int;
1143 raw_caps->dir_in = caps->dir_in;
1144 raw_caps->dir_out = caps->dir_out;
1145}
1146
1147static void fill_ep_limits(struct usb_ep *ep, struct usb_raw_ep_limits *limits)
1148{
1149 limits->maxpacket_limit = ep->maxpacket_limit;
1150 limits->max_streams = ep->max_streams;
1151}
1152
1153static int raw_ioctl_eps_info(struct raw_dev *dev, unsigned long value)
1154{
1155 int ret = 0, i;
1156 unsigned long flags;
1157 struct usb_raw_eps_info *info;
1158 struct raw_ep *ep;
1159
1160 info = kmalloc(sizeof(*info), GFP_KERNEL);
1161 if (!info) {
1162 ret = -ENOMEM;
1163 goto out;
1164 }
1165
1166 spin_lock_irqsave(&dev->lock, flags);
1167 if (dev->state != STATE_DEV_RUNNING) {
1168 dev_dbg(dev->dev, "fail, device is not running\n");
1169 ret = -EINVAL;
1170 spin_unlock_irqrestore(&dev->lock, flags);
1171 goto out_free;
1172 }
1173 if (!dev->gadget) {
1174 dev_dbg(dev->dev, "fail, gadget is not bound\n");
1175 ret = -EBUSY;
1176 spin_unlock_irqrestore(&dev->lock, flags);
1177 goto out_free;
1178 }
1179
1180 memset(info, 0, sizeof(*info));
1181 for (i = 0; i < dev->eps_num; i++) {
1182 ep = &dev->eps[i];
1183 strscpy(&info->eps[i].name[0], ep->ep->name,
1184 USB_RAW_EP_NAME_MAX);
1185 info->eps[i].addr = ep->addr;
1186 fill_ep_caps(&ep->ep->caps, &info->eps[i].caps);
1187 fill_ep_limits(ep->ep, &info->eps[i].limits);
1188 }
1189 ret = dev->eps_num;
1190 spin_unlock_irqrestore(&dev->lock, flags);
1191
1192 if (copy_to_user((void __user *)value, info, sizeof(*info)))
1193 ret = -EFAULT;
1194
1195out_free:
1196 kfree(info);
1197out:
1198 return ret;
1199}
1200
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001201static long raw_ioctl(struct file *fd, unsigned int cmd, unsigned long value)
1202{
1203 struct raw_dev *dev = fd->private_data;
1204 int ret = 0;
1205
1206 if (!dev)
1207 return -EBUSY;
1208
1209 switch (cmd) {
1210 case USB_RAW_IOCTL_INIT:
1211 ret = raw_ioctl_init(dev, value);
1212 break;
1213 case USB_RAW_IOCTL_RUN:
1214 ret = raw_ioctl_run(dev, value);
1215 break;
1216 case USB_RAW_IOCTL_EVENT_FETCH:
1217 ret = raw_ioctl_event_fetch(dev, value);
1218 break;
1219 case USB_RAW_IOCTL_EP0_WRITE:
1220 ret = raw_ioctl_ep0_write(dev, value);
1221 break;
1222 case USB_RAW_IOCTL_EP0_READ:
1223 ret = raw_ioctl_ep0_read(dev, value);
1224 break;
1225 case USB_RAW_IOCTL_EP_ENABLE:
1226 ret = raw_ioctl_ep_enable(dev, value);
1227 break;
1228 case USB_RAW_IOCTL_EP_DISABLE:
1229 ret = raw_ioctl_ep_disable(dev, value);
1230 break;
1231 case USB_RAW_IOCTL_EP_WRITE:
1232 ret = raw_ioctl_ep_write(dev, value);
1233 break;
1234 case USB_RAW_IOCTL_EP_READ:
1235 ret = raw_ioctl_ep_read(dev, value);
1236 break;
1237 case USB_RAW_IOCTL_CONFIGURE:
1238 ret = raw_ioctl_configure(dev, value);
1239 break;
1240 case USB_RAW_IOCTL_VBUS_DRAW:
1241 ret = raw_ioctl_vbus_draw(dev, value);
1242 break;
Andrey Konovalov97df5e52020-05-07 19:06:56 +02001243 case USB_RAW_IOCTL_EPS_INFO:
1244 ret = raw_ioctl_eps_info(dev, value);
1245 break;
Andrey Konovalovc61769b2020-05-07 19:06:57 +02001246 case USB_RAW_IOCTL_EP0_STALL:
1247 ret = raw_ioctl_ep0_stall(dev, value);
1248 break;
1249 case USB_RAW_IOCTL_EP_SET_HALT:
1250 ret = raw_ioctl_ep_set_clear_halt_wedge(
1251 dev, value, true, true);
1252 break;
1253 case USB_RAW_IOCTL_EP_CLEAR_HALT:
1254 ret = raw_ioctl_ep_set_clear_halt_wedge(
1255 dev, value, false, true);
1256 break;
1257 case USB_RAW_IOCTL_EP_SET_WEDGE:
1258 ret = raw_ioctl_ep_set_clear_halt_wedge(
1259 dev, value, true, false);
1260 break;
Andrey Konovalovf2c2e712020-02-24 17:13:03 +01001261 default:
1262 ret = -EINVAL;
1263 }
1264
1265 return ret;
1266}
1267
1268/*----------------------------------------------------------------------*/
1269
1270static const struct file_operations raw_fops = {
1271 .open = raw_open,
1272 .unlocked_ioctl = raw_ioctl,
1273 .compat_ioctl = raw_ioctl,
1274 .release = raw_release,
1275 .llseek = no_llseek,
1276};
1277
1278static struct miscdevice raw_misc_device = {
1279 .minor = MISC_DYNAMIC_MINOR,
1280 .name = DRIVER_NAME,
1281 .fops = &raw_fops,
1282};
1283
1284module_misc_device(raw_misc_device);