aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-05-02 14:57:41 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:41 -0400
commitcdda479f15cd13fa50a913ca85129c0437cc7b91 (patch)
tree5189c428d5f23f738dbf3e8e555c6f48da540b3a /drivers/usb/gadget
parent910f8d0cede74beff1eee93cf9cf2a28d7600e66 (diff)
USB gadget: video class function driver
This USB video class function driver implements a video capture device from the host's point of view. It creates a V4L2 output device on the gadget's side to transfer data from a userspace application over USB. The UVC-specific descriptors are passed by the gadget driver to the UVC function driver, making them completely configurable without any modification to the function's driver code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/f_uvc.c661
-rw-r--r--drivers/usb/gadget/f_uvc.h376
-rw-r--r--drivers/usb/gadget/uvc.h241
-rw-r--r--drivers/usb/gadget/uvc_queue.c583
-rw-r--r--drivers/usb/gadget/uvc_queue.h89
-rw-r--r--drivers/usb/gadget/uvc_v4l2.c374
-rw-r--r--drivers/usb/gadget/uvc_video.c386
7 files changed, 2710 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
new file mode 100644
index 000000000000..fc2611f8b326
--- /dev/null
+++ b/drivers/usb/gadget/f_uvc.c
@@ -0,0 +1,661 @@
1/*
2 * uvc_gadget.c -- USB Video Class Gadget driver
3 *
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/errno.h>
17#include <linux/fs.h>
18#include <linux/list.h>
19#include <linux/mutex.h>
20#include <linux/usb/ch9.h>
21#include <linux/usb/gadget.h>
22#include <linux/usb/video.h>
23#include <linux/vmalloc.h>
24#include <linux/wait.h>
25
26#include <media/v4l2-dev.h>
27#include <media/v4l2-event.h>
28
29#include "uvc.h"
30
31unsigned int uvc_trace_param;
32
33/* --------------------------------------------------------------------------
34 * Function descriptors
35 */
36
37/* string IDs are assigned dynamically */
38
39#define UVC_STRING_ASSOCIATION_IDX 0
40#define UVC_STRING_CONTROL_IDX 1
41#define UVC_STRING_STREAMING_IDX 2
42
43static struct usb_string uvc_en_us_strings[] = {
44 [UVC_STRING_ASSOCIATION_IDX].s = "UVC Camera",
45 [UVC_STRING_CONTROL_IDX].s = "Video Control",
46 [UVC_STRING_STREAMING_IDX].s = "Video Streaming",
47 { }
48};
49
50static struct usb_gadget_strings uvc_stringtab = {
51 .language = 0x0409, /* en-us */
52 .strings = uvc_en_us_strings,
53};
54
55static struct usb_gadget_strings *uvc_function_strings[] = {
56 &uvc_stringtab,
57 NULL,
58};
59
60#define UVC_INTF_VIDEO_CONTROL 0
61#define UVC_INTF_VIDEO_STREAMING 1
62
63static struct usb_interface_assoc_descriptor uvc_iad __initdata = {
64 .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
65 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
66 .bFirstInterface = 0,
67 .bInterfaceCount = 2,
68 .bFunctionClass = USB_CLASS_VIDEO,
69 .bFunctionSubClass = 0x03,
70 .bFunctionProtocol = 0x00,
71 .iFunction = 0,
72};
73
74static struct usb_interface_descriptor uvc_control_intf __initdata = {
75 .bLength = USB_DT_INTERFACE_SIZE,
76 .bDescriptorType = USB_DT_INTERFACE,
77 .bInterfaceNumber = UVC_INTF_VIDEO_CONTROL,
78 .bAlternateSetting = 0,
79 .bNumEndpoints = 1,
80 .bInterfaceClass = USB_CLASS_VIDEO,
81 .bInterfaceSubClass = 0x01,
82 .bInterfaceProtocol = 0x00,
83 .iInterface = 0,
84};
85
86static struct usb_endpoint_descriptor uvc_control_ep __initdata = {
87 .bLength = USB_DT_ENDPOINT_SIZE,
88 .bDescriptorType = USB_DT_ENDPOINT,
89 .bEndpointAddress = USB_DIR_IN,
90 .bmAttributes = USB_ENDPOINT_XFER_INT,
91 .wMaxPacketSize = cpu_to_le16(16),
92 .bInterval = 8,
93};
94
95static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = {
96 .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE,
97 .bDescriptorType = USB_DT_CS_ENDPOINT,
98 .bDescriptorSubType = UVC_EP_INTERRUPT,
99 .wMaxTransferSize = cpu_to_le16(16),
100};
101
102static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = {
103 .bLength = USB_DT_INTERFACE_SIZE,
104 .bDescriptorType = USB_DT_INTERFACE,
105 .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING,
106 .bAlternateSetting = 0,
107 .bNumEndpoints = 0,
108 .bInterfaceClass = USB_CLASS_VIDEO,
109 .bInterfaceSubClass = 0x02,
110 .bInterfaceProtocol = 0x00,
111 .iInterface = 0,
112};
113
114static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = {
115 .bLength = USB_DT_INTERFACE_SIZE,
116 .bDescriptorType = USB_DT_INTERFACE,
117 .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING,
118 .bAlternateSetting = 1,
119 .bNumEndpoints = 1,
120 .bInterfaceClass = USB_CLASS_VIDEO,
121 .bInterfaceSubClass = 0x02,
122 .bInterfaceProtocol = 0x00,
123 .iInterface = 0,
124};
125
126static struct usb_endpoint_descriptor uvc_streaming_ep = {
127 .bLength = USB_DT_ENDPOINT_SIZE,
128 .bDescriptorType = USB_DT_ENDPOINT,
129 .bEndpointAddress = USB_DIR_IN,
130 .bmAttributes = USB_ENDPOINT_XFER_ISOC,
131 .wMaxPacketSize = cpu_to_le16(512),
132 .bInterval = 1,
133};
134
135static const struct usb_descriptor_header * const uvc_fs_streaming[] = {
136 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
137 (struct usb_descriptor_header *) &uvc_streaming_ep,
138 NULL,
139};
140
141static const struct usb_descriptor_header * const uvc_hs_streaming[] = {
142 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
143 (struct usb_descriptor_header *) &uvc_streaming_ep,
144 NULL,
145};
146
147/* --------------------------------------------------------------------------
148 * Control requests
149 */
150
151static void
152uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
153{
154 struct uvc_device *uvc = req->context;
155 struct v4l2_event v4l2_event;
156 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
157
158 if (uvc->event_setup_out) {
159 uvc->event_setup_out = 0;
160
161 memset(&v4l2_event, 0, sizeof(v4l2_event));
162 v4l2_event.type = UVC_EVENT_DATA;
163 uvc_event->data.length = req->actual;
164 memcpy(&uvc_event->data.data, req->buf, req->actual);
165 v4l2_event_queue(uvc->vdev, &v4l2_event);
166 }
167}
168
169static int
170uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
171{
172 struct uvc_device *uvc = to_uvc(f);
173 struct v4l2_event v4l2_event;
174 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
175
176 /* printk(KERN_INFO "setup request %02x %02x value %04x index %04x %04x\n",
177 * ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue),
178 * le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength));
179 */
180
181 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) {
182 INFO(f->config->cdev, "invalid request type\n");
183 return -EINVAL;
184 }
185
186 /* Stall too big requests. */
187 if (le16_to_cpu(ctrl->wLength) > UVC_MAX_REQUEST_SIZE)
188 return -EINVAL;
189
190 memset(&v4l2_event, 0, sizeof(v4l2_event));
191 v4l2_event.type = UVC_EVENT_SETUP;
192 memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
193 v4l2_event_queue(uvc->vdev, &v4l2_event);
194
195 return 0;
196}
197
198static int
199uvc_function_get_alt(struct usb_function *f, unsigned interface)
200{
201 struct uvc_device *uvc = to_uvc(f);
202
203 INFO(f->config->cdev, "uvc_function_get_alt(%u)\n", interface);
204
205 if (interface == uvc->control_intf)
206 return 0;
207 else if (interface != uvc->streaming_intf)
208 return -EINVAL;
209 else
210 return uvc->state == UVC_STATE_STREAMING ? 1 : 0;
211}
212
213static int
214uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
215{
216 struct uvc_device *uvc = to_uvc(f);
217 struct v4l2_event v4l2_event;
218 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
219
220 INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt);
221
222 if (interface == uvc->control_intf) {
223 if (alt)
224 return -EINVAL;
225
226 if (uvc->state == UVC_STATE_DISCONNECTED) {
227 memset(&v4l2_event, 0, sizeof(v4l2_event));
228 v4l2_event.type = UVC_EVENT_CONNECT;
229 uvc_event->speed = f->config->cdev->gadget->speed;
230 v4l2_event_queue(uvc->vdev, &v4l2_event);
231
232 uvc->state = UVC_STATE_CONNECTED;
233 }
234
235 return 0;
236 }
237
238 if (interface != uvc->streaming_intf)
239 return -EINVAL;
240
241 /* TODO
242 if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep))
243 return alt ? -EINVAL : 0;
244 */
245
246 switch (alt) {
247 case 0:
248 if (uvc->state != UVC_STATE_STREAMING)
249 return 0;
250
251 if (uvc->video.ep)
252 usb_ep_disable(uvc->video.ep);
253
254 memset(&v4l2_event, 0, sizeof(v4l2_event));
255 v4l2_event.type = UVC_EVENT_STREAMOFF;
256 v4l2_event_queue(uvc->vdev, &v4l2_event);
257
258 uvc->state = UVC_STATE_CONNECTED;
259 break;
260
261 case 1:
262 if (uvc->state != UVC_STATE_CONNECTED)
263 return 0;
264
265 if (uvc->video.ep)
266 usb_ep_enable(uvc->video.ep, &uvc_streaming_ep);
267
268 memset(&v4l2_event, 0, sizeof(v4l2_event));
269 v4l2_event.type = UVC_EVENT_STREAMON;
270 v4l2_event_queue(uvc->vdev, &v4l2_event);
271
272 uvc->state = UVC_STATE_STREAMING;
273 break;
274
275 default:
276 return -EINVAL;
277 }
278
279 return 0;
280}
281
282static void
283uvc_function_disable(struct usb_function *f)
284{
285 struct uvc_device *uvc = to_uvc(f);
286 struct v4l2_event v4l2_event;
287
288 INFO(f->config->cdev, "uvc_function_disable\n");
289
290 memset(&v4l2_event, 0, sizeof(v4l2_event));
291 v4l2_event.type = UVC_EVENT_DISCONNECT;
292 v4l2_event_queue(uvc->vdev, &v4l2_event);
293
294 uvc->state = UVC_STATE_DISCONNECTED;
295}
296
297/* --------------------------------------------------------------------------
298 * Connection / disconnection
299 */
300
301void
302uvc_function_connect(struct uvc_device *uvc)
303{
304 struct usb_composite_dev *cdev = uvc->func.config->cdev;
305 int ret;
306
307 if ((ret = usb_function_activate(&uvc->func)) < 0)
308 INFO(cdev, "UVC connect failed with %d\n", ret);
309}
310
311void
312uvc_function_disconnect(struct uvc_device *uvc)
313{
314 struct usb_composite_dev *cdev = uvc->func.config->cdev;
315 int ret;
316
317 if ((ret = usb_function_deactivate(&uvc->func)) < 0)
318 INFO(cdev, "UVC disconnect failed with %d\n", ret);
319}
320
321/* --------------------------------------------------------------------------
322 * USB probe and disconnect
323 */
324
325static int
326uvc_register_video(struct uvc_device *uvc)
327{
328 struct usb_composite_dev *cdev = uvc->func.config->cdev;
329 struct video_device *video;
330
331 /* TODO reference counting. */
332 video = video_device_alloc();
333 if (video == NULL)
334 return -ENOMEM;
335
336 video->parent = &cdev->gadget->dev;
337 video->minor = -1;
338 video->fops = &uvc_v4l2_fops;
339 video->release = video_device_release;
340 strncpy(video->name, cdev->gadget->name, sizeof(video->name));
341
342 uvc->vdev = video;
343 video_set_drvdata(video, uvc);
344
345 return video_register_device(video, VFL_TYPE_GRABBER, -1);
346}
347
348#define UVC_COPY_DESCRIPTOR(mem, dst, desc) \
349 do { \
350 memcpy(mem, desc, (desc)->bLength); \
351 *(dst)++ = mem; \
352 mem += (desc)->bLength; \
353 } while (0);
354
355#define UVC_COPY_DESCRIPTORS(mem, dst, src) \
356 do { \
357 const struct usb_descriptor_header * const *__src; \
358 for (__src = src; *__src; ++__src) { \
359 memcpy(mem, *__src, (*__src)->bLength); \
360 *dst++ = mem; \
361 mem += (*__src)->bLength; \
362 } \
363 } while (0)
364
365static struct usb_descriptor_header ** __init
366uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
367{
368 struct uvc_input_header_descriptor *uvc_streaming_header;
369 struct uvc_header_descriptor *uvc_control_header;
370 const struct uvc_descriptor_header * const *uvc_streaming_cls;
371 const struct usb_descriptor_header * const *uvc_streaming_std;
372 const struct usb_descriptor_header * const *src;
373 struct usb_descriptor_header **dst;
374 struct usb_descriptor_header **hdr;
375 unsigned int control_size;
376 unsigned int streaming_size;
377 unsigned int n_desc;
378 unsigned int bytes;
379 void *mem;
380
381 uvc_streaming_cls = (speed == USB_SPEED_FULL)
382 ? uvc->desc.fs_streaming : uvc->desc.hs_streaming;
383 uvc_streaming_std = (speed == USB_SPEED_FULL)
384 ? uvc_fs_streaming : uvc_hs_streaming;
385
386 /* Descriptors layout
387 *
388 * uvc_iad
389 * uvc_control_intf
390 * Class-specific UVC control descriptors
391 * uvc_control_ep
392 * uvc_control_cs_ep
393 * uvc_streaming_intf_alt0
394 * Class-specific UVC streaming descriptors
395 * uvc_{fs|hs}_streaming
396 */
397
398 /* Count descriptors and compute their size. */
399 control_size = 0;
400 streaming_size = 0;
401 bytes = uvc_iad.bLength + uvc_control_intf.bLength
402 + uvc_control_ep.bLength + uvc_control_cs_ep.bLength
403 + uvc_streaming_intf_alt0.bLength;
404 n_desc = 5;
405
406 for (src = (const struct usb_descriptor_header**)uvc->desc.control; *src; ++src) {
407 control_size += (*src)->bLength;
408 bytes += (*src)->bLength;
409 n_desc++;
410 }
411 for (src = (const struct usb_descriptor_header**)uvc_streaming_cls; *src; ++src) {
412 streaming_size += (*src)->bLength;
413 bytes += (*src)->bLength;
414 n_desc++;
415 }
416 for (src = uvc_streaming_std; *src; ++src) {
417 bytes += (*src)->bLength;
418 n_desc++;
419 }
420
421 mem = kmalloc((n_desc + 1) * sizeof(*src) + bytes, GFP_KERNEL);
422 if (mem == NULL)
423 return NULL;
424
425 hdr = mem;
426 dst = mem;
427 mem += (n_desc + 1) * sizeof(*src);
428
429 /* Copy the descriptors. */
430 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_iad);
431 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_intf);
432
433 uvc_control_header = mem;
434 UVC_COPY_DESCRIPTORS(mem, dst,
435 (const struct usb_descriptor_header**)uvc->desc.control);
436 uvc_control_header->wTotalLength = cpu_to_le16(control_size);
437 uvc_control_header->bInCollection = 1;
438 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf;
439
440 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep);
441 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep);
442 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0);
443
444 uvc_streaming_header = mem;
445 UVC_COPY_DESCRIPTORS(mem, dst,
446 (const struct usb_descriptor_header**)uvc_streaming_cls);
447 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size);
448 uvc_streaming_header->bEndpointAddress = uvc_streaming_ep.bEndpointAddress;
449
450 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std);
451
452 *dst = NULL;
453 return hdr;
454}
455
456static void
457uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
458{
459 struct usb_composite_dev *cdev = c->cdev;
460 struct uvc_device *uvc = to_uvc(f);
461
462 INFO(cdev, "uvc_function_unbind\n");
463
464 if (uvc->vdev) {
465 if (uvc->vdev->minor == -1)
466 video_device_release(uvc->vdev);
467 else
468 video_unregister_device(uvc->vdev);
469 uvc->vdev = NULL;
470 }
471
472 if (uvc->control_ep)
473 uvc->control_ep->driver_data = NULL;
474 if (uvc->video.ep)
475 uvc->video.ep->driver_data = NULL;
476
477 if (uvc->control_req) {
478 usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
479 kfree(uvc->control_buf);
480 }
481
482 kfree(f->descriptors);
483 kfree(f->hs_descriptors);
484
485 kfree(uvc);
486}
487
488static int __init
489uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
490{
491 struct usb_composite_dev *cdev = c->cdev;
492 struct uvc_device *uvc = to_uvc(f);
493 struct usb_ep *ep;
494 int ret = -EINVAL;
495
496 INFO(cdev, "uvc_function_bind\n");
497
498 /* Allocate endpoints. */
499 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
500 if (!ep) {
501 INFO(cdev, "Unable to allocate control EP\n");
502 goto error;
503 }
504 uvc->control_ep = ep;
505 ep->driver_data = uvc;
506
507 ep = usb_ep_autoconfig(cdev->gadget, &uvc_streaming_ep);
508 if (!ep) {
509 INFO(cdev, "Unable to allocate streaming EP\n");
510 goto error;
511 }
512 uvc->video.ep = ep;
513 ep->driver_data = uvc;
514
515 /* Allocate interface IDs. */
516 if ((ret = usb_interface_id(c, f)) < 0)
517 goto error;
518 uvc_iad.bFirstInterface = ret;
519 uvc_control_intf.bInterfaceNumber = ret;
520 uvc->control_intf = ret;
521
522 if ((ret = usb_interface_id(c, f)) < 0)
523 goto error;
524 uvc_streaming_intf_alt0.bInterfaceNumber = ret;
525 uvc_streaming_intf_alt1.bInterfaceNumber = ret;
526 uvc->streaming_intf = ret;
527
528 /* Copy descriptors. */
529 f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
530 f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
531
532 /* Preallocate control endpoint request. */
533 uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
534 uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL);
535 if (uvc->control_req == NULL || uvc->control_buf == NULL) {
536 ret = -ENOMEM;
537 goto error;
538 }
539
540 uvc->control_req->buf = uvc->control_buf;
541 uvc->control_req->complete = uvc_function_ep0_complete;
542 uvc->control_req->context = uvc;
543
544 /* Avoid letting this gadget enumerate until the userspace server is
545 * active.
546 */
547 if ((ret = usb_function_deactivate(f)) < 0)
548 goto error;
549
550 /* Initialise video. */
551 ret = uvc_video_init(&uvc->video);
552 if (ret < 0)
553 goto error;
554
555 /* Register a V4L2 device. */
556 ret = uvc_register_video(uvc);
557 if (ret < 0) {
558 printk(KERN_INFO "Unable to register video device\n");
559 goto error;
560 }
561
562 return 0;
563
564error:
565 uvc_function_unbind(c, f);
566 return ret;
567}
568
569/* --------------------------------------------------------------------------
570 * USB gadget function
571 */
572
573/**
574 * uvc_bind_config - add a UVC function to a configuration
575 * @c: the configuration to support the UVC instance
576 * Context: single threaded during gadget setup
577 *
578 * Returns zero on success, else negative errno.
579 *
580 * Caller must have called @uvc_setup(). Caller is also responsible for
581 * calling @uvc_cleanup() before module unload.
582 */
583int __init
584uvc_bind_config(struct usb_configuration *c,
585 const struct uvc_descriptor_header * const *control,
586 const struct uvc_descriptor_header * const *fs_streaming,
587 const struct uvc_descriptor_header * const *hs_streaming)
588{
589 struct uvc_device *uvc;
590 int ret = 0;
591
592 /* TODO Check if the USB device controller supports the required
593 * features.
594 */
595 if (!gadget_is_dualspeed(c->cdev->gadget))
596 return -EINVAL;
597
598 uvc = kzalloc(sizeof(*uvc), GFP_KERNEL);
599 if (uvc == NULL)
600 return -ENOMEM;
601
602 uvc->state = UVC_STATE_DISCONNECTED;
603
604 /* Validate the descriptors. */
605 if (control == NULL || control[0] == NULL ||
606 control[0]->bDescriptorSubType != UVC_DT_HEADER)
607 goto error;
608
609 if (fs_streaming == NULL || fs_streaming[0] == NULL ||
610 fs_streaming[0]->bDescriptorSubType != UVC_DT_INPUT_HEADER)
611 goto error;
612
613 if (hs_streaming == NULL || hs_streaming[0] == NULL ||
614 hs_streaming[0]->bDescriptorSubType != UVC_DT_INPUT_HEADER)
615 goto error;
616
617 uvc->desc.control = control;
618 uvc->desc.fs_streaming = fs_streaming;
619 uvc->desc.hs_streaming = hs_streaming;
620
621 /* Allocate string descriptor numbers. */
622 if ((ret = usb_string_id(c->cdev)) < 0)
623 goto error;
624 uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret;
625 uvc_iad.iFunction = ret;
626
627 if ((ret = usb_string_id(c->cdev)) < 0)
628 goto error;
629 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret;
630 uvc_control_intf.iInterface = ret;
631
632 if ((ret = usb_string_id(c->cdev)) < 0)
633 goto error;
634 uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret;
635 uvc_streaming_intf_alt0.iInterface = ret;
636 uvc_streaming_intf_alt1.iInterface = ret;
637
638 /* Register the function. */
639 uvc->func.name = "uvc";
640 uvc->func.strings = uvc_function_strings;
641 uvc->func.bind = uvc_function_bind;
642 uvc->func.unbind = uvc_function_unbind;
643 uvc->func.get_alt = uvc_function_get_alt;
644 uvc->func.set_alt = uvc_function_set_alt;
645 uvc->func.disable = uvc_function_disable;
646 uvc->func.setup = uvc_function_setup;
647
648 ret = usb_add_function(c, &uvc->func);
649 if (ret)
650 kfree(uvc);
651
652 return 0;
653
654error:
655 kfree(uvc);
656 return ret;
657}
658
659module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
660MODULE_PARM_DESC(trace, "Trace level bitmask");
661
diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h
new file mode 100644
index 000000000000..8a5db7c4fe7c
--- /dev/null
+++ b/drivers/usb/gadget/f_uvc.h
@@ -0,0 +1,376 @@
1/*
2 * f_uvc.h -- USB Video Class Gadget driver
3 *
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#ifndef _F_UVC_H_
15#define _F_UVC_H_
16
17#include <linux/usb/composite.h>
18
19#define USB_CLASS_VIDEO_CONTROL 1
20#define USB_CLASS_VIDEO_STREAMING 2
21
22struct uvc_descriptor_header {
23 __u8 bLength;
24 __u8 bDescriptorType;
25 __u8 bDescriptorSubType;
26} __attribute__ ((packed));
27
28struct uvc_header_descriptor {
29 __u8 bLength;
30 __u8 bDescriptorType;
31 __u8 bDescriptorSubType;
32 __u16 bcdUVC;
33 __u16 wTotalLength;
34 __u32 dwClockFrequency;
35 __u8 bInCollection;
36 __u8 baInterfaceNr[];
37} __attribute__((__packed__));
38
39#define UVC_HEADER_DESCRIPTOR(n) uvc_header_descriptor_##n
40
41#define DECLARE_UVC_HEADER_DESCRIPTOR(n) \
42struct UVC_HEADER_DESCRIPTOR(n) { \
43 __u8 bLength; \
44 __u8 bDescriptorType; \
45 __u8 bDescriptorSubType; \
46 __u16 bcdUVC; \
47 __u16 wTotalLength; \
48 __u32 dwClockFrequency; \
49 __u8 bInCollection; \
50 __u8 baInterfaceNr[n]; \
51} __attribute__ ((packed))
52
53struct uvc_input_terminal_descriptor {
54 __u8 bLength;
55 __u8 bDescriptorType;
56 __u8 bDescriptorSubType;
57 __u8 bTerminalID;
58 __u16 wTerminalType;
59 __u8 bAssocTerminal;
60 __u8 iTerminal;
61} __attribute__((__packed__));
62
63struct uvc_output_terminal_descriptor {
64 __u8 bLength;
65 __u8 bDescriptorType;
66 __u8 bDescriptorSubType;
67 __u8 bTerminalID;
68 __u16 wTerminalType;
69 __u8 bAssocTerminal;
70 __u8 bSourceID;
71 __u8 iTerminal;
72} __attribute__((__packed__));
73
74struct uvc_camera_terminal_descriptor {
75 __u8 bLength;
76 __u8 bDescriptorType;
77 __u8 bDescriptorSubType;
78 __u8 bTerminalID;
79 __u16 wTerminalType;
80 __u8 bAssocTerminal;
81 __u8 iTerminal;
82 __u16 wObjectiveFocalLengthMin;
83 __u16 wObjectiveFocalLengthMax;
84 __u16 wOcularFocalLength;
85 __u8 bControlSize;
86 __u8 bmControls[3];
87} __attribute__((__packed__));
88
89struct uvc_selector_unit_descriptor {
90 __u8 bLength;
91 __u8 bDescriptorType;
92 __u8 bDescriptorSubType;
93 __u8 bUnitID;
94 __u8 bNrInPins;
95 __u8 baSourceID[0];
96 __u8 iSelector;
97} __attribute__((__packed__));
98
99#define UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
100 uvc_selector_unit_descriptor_##n
101
102#define DECLARE_UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
103struct UVC_SELECTOR_UNIT_DESCRIPTOR(n) { \
104 __u8 bLength; \
105 __u8 bDescriptorType; \
106 __u8 bDescriptorSubType; \
107 __u8 bUnitID; \
108 __u8 bNrInPins; \
109 __u8 baSourceID[n]; \
110 __u8 iSelector; \
111} __attribute__ ((packed))
112
113struct uvc_processing_unit_descriptor {
114 __u8 bLength;
115 __u8 bDescriptorType;
116 __u8 bDescriptorSubType;
117 __u8 bUnitID;
118 __u8 bSourceID;
119 __u16 wMaxMultiplier;
120 __u8 bControlSize;
121 __u8 bmControls[2];
122 __u8 iProcessing;
123} __attribute__((__packed__));
124
125struct uvc_extension_unit_descriptor {
126 __u8 bLength;
127 __u8 bDescriptorType;
128 __u8 bDescriptorSubType;
129 __u8 bUnitID;
130 __u8 guidExtensionCode[16];
131 __u8 bNumControls;
132 __u8 bNrInPins;
133 __u8 baSourceID[0];
134 __u8 bControlSize;
135 __u8 bmControls[0];
136 __u8 iExtension;
137} __attribute__((__packed__));
138
139#define UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
140 uvc_extension_unit_descriptor_##p_##n
141
142#define DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
143struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \
144 __u8 bLength; \
145 __u8 bDescriptorType; \
146 __u8 bDescriptorSubType; \
147 __u8 bUnitID; \
148 __u8 guidExtensionCode[16]; \
149 __u8 bNumControls; \
150 __u8 bNrInPins; \
151 __u8 baSourceID[p]; \
152 __u8 bControlSize; \
153 __u8 bmControls[n]; \
154 __u8 iExtension; \
155} __attribute__ ((packed))
156
157struct uvc_control_endpoint_descriptor {
158 __u8 bLength;
159 __u8 bDescriptorType;
160 __u8 bDescriptorSubType;
161 __u16 wMaxTransferSize;
162} __attribute__((__packed__));
163
164#define UVC_DT_HEADER 1
165#define UVC_DT_INPUT_TERMINAL 2
166#define UVC_DT_OUTPUT_TERMINAL 3
167#define UVC_DT_SELECTOR_UNIT 4
168#define UVC_DT_PROCESSING_UNIT 5
169#define UVC_DT_EXTENSION_UNIT 6
170
171#define UVC_DT_HEADER_SIZE(n) (12+(n))
172#define UVC_DT_INPUT_TERMINAL_SIZE 8
173#define UVC_DT_OUTPUT_TERMINAL_SIZE 9
174#define UVC_DT_CAMERA_TERMINAL_SIZE(n) (15+(n))
175#define UVC_DT_SELECTOR_UNIT_SIZE(n) (6+(n))
176#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n))
177#define UVC_DT_EXTENSION_UNIT_SIZE(p,n) (24+(p)+(n))
178#define UVC_DT_CONTROL_ENDPOINT_SIZE 5
179
180struct uvc_input_header_descriptor {
181 __u8 bLength;
182 __u8 bDescriptorType;
183 __u8 bDescriptorSubType;
184 __u8 bNumFormats;
185 __u16 wTotalLength;
186 __u8 bEndpointAddress;
187 __u8 bmInfo;
188 __u8 bTerminalLink;
189 __u8 bStillCaptureMethod;
190 __u8 bTriggerSupport;
191 __u8 bTriggerUsage;
192 __u8 bControlSize;
193 __u8 bmaControls[];
194} __attribute__((__packed__));
195
196#define UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
197 uvc_input_header_descriptor_##n_##p
198
199#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
200struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { \
201 __u8 bLength; \
202 __u8 bDescriptorType; \
203 __u8 bDescriptorSubType; \
204 __u8 bNumFormats; \
205 __u16 wTotalLength; \
206 __u8 bEndpointAddress; \
207 __u8 bmInfo; \
208 __u8 bTerminalLink; \
209 __u8 bStillCaptureMethod; \
210 __u8 bTriggerSupport; \
211 __u8 bTriggerUsage; \
212 __u8 bControlSize; \
213 __u8 bmaControls[p][n]; \
214} __attribute__ ((packed))
215
216struct uvc_output_header_descriptor {
217 __u8 bLength;
218 __u8 bDescriptorType;
219 __u8 bDescriptorSubType;
220 __u8 bNumFormats;
221 __u16 wTotalLength;
222 __u8 bEndpointAddress;
223 __u8 bTerminalLink;
224 __u8 bControlSize;
225 __u8 bmaControls[];
226} __attribute__((__packed__));
227
228#define UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
229 uvc_output_header_descriptor_##n_##p
230
231#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
232struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { \
233 __u8 bLength; \
234 __u8 bDescriptorType; \
235 __u8 bDescriptorSubType; \
236 __u8 bNumFormats; \
237 __u16 wTotalLength; \
238 __u8 bEndpointAddress; \
239 __u8 bTerminalLink; \
240 __u8 bControlSize; \
241 __u8 bmaControls[p][n]; \
242} __attribute__ ((packed))
243
244struct uvc_format_uncompressed {
245 __u8 bLength;
246 __u8 bDescriptorType;
247 __u8 bDescriptorSubType;
248 __u8 bFormatIndex;
249 __u8 bNumFrameDescriptors;
250 __u8 guidFormat[16];
251 __u8 bBitsPerPixel;
252 __u8 bDefaultFrameIndex;
253 __u8 bAspectRatioX;
254 __u8 bAspectRatioY;
255 __u8 bmInterfaceFlags;
256 __u8 bCopyProtect;
257} __attribute__((__packed__));
258
259struct uvc_frame_uncompressed {
260 __u8 bLength;
261 __u8 bDescriptorType;
262 __u8 bDescriptorSubType;
263 __u8 bFrameIndex;
264 __u8 bmCapabilities;
265 __u16 wWidth;
266 __u16 wHeight;
267 __u32 dwMinBitRate;
268 __u32 dwMaxBitRate;
269 __u32 dwMaxVideoFrameBufferSize;
270 __u32 dwDefaultFrameInterval;
271 __u8 bFrameIntervalType;
272 __u32 dwFrameInterval[];
273} __attribute__((__packed__));
274
275#define UVC_FRAME_UNCOMPRESSED(n) \
276 uvc_frame_uncompressed_##n
277
278#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) \
279struct UVC_FRAME_UNCOMPRESSED(n) { \
280 __u8 bLength; \
281 __u8 bDescriptorType; \
282 __u8 bDescriptorSubType; \
283 __u8 bFrameIndex; \
284 __u8 bmCapabilities; \
285 __u16 wWidth; \
286 __u16 wHeight; \
287 __u32 dwMinBitRate; \
288 __u32 dwMaxBitRate; \
289 __u32 dwMaxVideoFrameBufferSize; \
290 __u32 dwDefaultFrameInterval; \
291 __u8 bFrameIntervalType; \
292 __u32 dwFrameInterval[n]; \
293} __attribute__ ((packed))
294
295struct uvc_format_mjpeg {
296 __u8 bLength;
297 __u8 bDescriptorType;
298 __u8 bDescriptorSubType;
299 __u8 bFormatIndex;
300 __u8 bNumFrameDescriptors;
301 __u8 bmFlags;
302 __u8 bDefaultFrameIndex;
303 __u8 bAspectRatioX;
304 __u8 bAspectRatioY;
305 __u8 bmInterfaceFlags;
306 __u8 bCopyProtect;
307} __attribute__((__packed__));
308
309struct uvc_frame_mjpeg {
310 __u8 bLength;
311 __u8 bDescriptorType;
312 __u8 bDescriptorSubType;
313 __u8 bFrameIndex;
314 __u8 bmCapabilities;
315 __u16 wWidth;
316 __u16 wHeight;
317 __u32 dwMinBitRate;
318 __u32 dwMaxBitRate;
319 __u32 dwMaxVideoFrameBufferSize;
320 __u32 dwDefaultFrameInterval;
321 __u8 bFrameIntervalType;
322 __u32 dwFrameInterval[];
323} __attribute__((__packed__));
324
325#define UVC_FRAME_MJPEG(n) \
326 uvc_frame_mjpeg_##n
327
328#define DECLARE_UVC_FRAME_MJPEG(n) \
329struct UVC_FRAME_MJPEG(n) { \
330 __u8 bLength; \
331 __u8 bDescriptorType; \
332 __u8 bDescriptorSubType; \
333 __u8 bFrameIndex; \
334 __u8 bmCapabilities; \
335 __u16 wWidth; \
336 __u16 wHeight; \
337 __u32 dwMinBitRate; \
338 __u32 dwMaxBitRate; \
339 __u32 dwMaxVideoFrameBufferSize; \
340 __u32 dwDefaultFrameInterval; \
341 __u8 bFrameIntervalType; \
342 __u32 dwFrameInterval[n]; \
343} __attribute__ ((packed))
344
345struct uvc_color_matching_descriptor {
346 __u8 bLength;
347 __u8 bDescriptorType;
348 __u8 bDescriptorSubType;
349 __u8 bColorPrimaries;
350 __u8 bTransferCharacteristics;
351 __u8 bMatrixCoefficients;
352} __attribute__((__packed__));
353
354#define UVC_DT_INPUT_HEADER 1
355#define UVC_DT_OUTPUT_HEADER 2
356#define UVC_DT_FORMAT_UNCOMPRESSED 4
357#define UVC_DT_FRAME_UNCOMPRESSED 5
358#define UVC_DT_FORMAT_MJPEG 6
359#define UVC_DT_FRAME_MJPEG 7
360#define UVC_DT_COLOR_MATCHING 13
361
362#define UVC_DT_INPUT_HEADER_SIZE(n, p) (13+(n*p))
363#define UVC_DT_OUTPUT_HEADER_SIZE(n, p) (9+(n*p))
364#define UVC_DT_FORMAT_UNCOMPRESSED_SIZE 27
365#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26+4*(n))
366#define UVC_DT_FORMAT_MJPEG_SIZE 11
367#define UVC_DT_FRAME_MJPEG_SIZE(n) (26+4*(n))
368#define UVC_DT_COLOR_MATCHING_SIZE 6
369
370extern int uvc_bind_config(struct usb_configuration *c,
371 const struct uvc_descriptor_header * const *control,
372 const struct uvc_descriptor_header * const *fs_streaming,
373 const struct uvc_descriptor_header * const *hs_streaming);
374
375#endif /* _F_UVC_H_ */
376
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h
new file mode 100644
index 000000000000..0a705e63c936
--- /dev/null
+++ b/drivers/usb/gadget/uvc.h
@@ -0,0 +1,241 @@
1/*
2 * uvc_gadget.h -- USB Video Class Gadget driver
3 *
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#ifndef _UVC_GADGET_H_
15#define _UVC_GADGET_H_
16
17#include <linux/ioctl.h>
18#include <linux/types.h>
19#include <linux/usb/ch9.h>
20
21#define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0)
22#define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0)
23#define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1)
24#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2)
25#define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3)
26#define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4)
27#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
28#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5)
29
30struct uvc_request_data
31{
32 unsigned int length;
33 __u8 data[60];
34};
35
36struct uvc_event
37{
38 union {
39 enum usb_device_speed speed;
40 struct usb_ctrlrequest req;
41 struct uvc_request_data data;
42 };
43};
44
45#define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data)
46
47#define UVC_INTF_CONTROL 0
48#define UVC_INTF_STREAMING 1
49
50/* ------------------------------------------------------------------------
51 * UVC constants & structures
52 */
53
54/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
55#define UVC_STREAM_EOH (1 << 7)
56#define UVC_STREAM_ERR (1 << 6)
57#define UVC_STREAM_STI (1 << 5)
58#define UVC_STREAM_RES (1 << 4)
59#define UVC_STREAM_SCR (1 << 3)
60#define UVC_STREAM_PTS (1 << 2)
61#define UVC_STREAM_EOF (1 << 1)
62#define UVC_STREAM_FID (1 << 0)
63
64struct uvc_streaming_control {
65 __u16 bmHint;
66 __u8 bFormatIndex;
67 __u8 bFrameIndex;
68 __u32 dwFrameInterval;
69 __u16 wKeyFrameRate;
70 __u16 wPFrameRate;
71 __u16 wCompQuality;
72 __u16 wCompWindowSize;
73 __u16 wDelay;
74 __u32 dwMaxVideoFrameSize;
75 __u32 dwMaxPayloadTransferSize;
76 __u32 dwClockFrequency;
77 __u8 bmFramingInfo;
78 __u8 bPreferedVersion;
79 __u8 bMinVersion;
80 __u8 bMaxVersion;
81} __attribute__((__packed__));
82
83/* ------------------------------------------------------------------------
84 * Debugging, printing and logging
85 */
86
87#ifdef __KERNEL__
88
89#include <linux/usb.h> /* For usb_endpoint_* */
90#include <linux/usb/gadget.h>
91#include <linux/videodev2.h>
92#include <media/v4l2-fh.h>
93
94#include "uvc_queue.h"
95
96#define UVC_TRACE_PROBE (1 << 0)
97#define UVC_TRACE_DESCR (1 << 1)
98#define UVC_TRACE_CONTROL (1 << 2)
99#define UVC_TRACE_FORMAT (1 << 3)
100#define UVC_TRACE_CAPTURE (1 << 4)
101#define UVC_TRACE_CALLS (1 << 5)
102#define UVC_TRACE_IOCTL (1 << 6)
103#define UVC_TRACE_FRAME (1 << 7)
104#define UVC_TRACE_SUSPEND (1 << 8)
105#define UVC_TRACE_STATUS (1 << 9)
106
107#define UVC_WARN_MINMAX 0
108#define UVC_WARN_PROBE_DEF 1
109
110extern unsigned int uvc_trace_param;
111
112#define uvc_trace(flag, msg...) \
113 do { \
114 if (uvc_trace_param & flag) \
115 printk(KERN_DEBUG "uvcvideo: " msg); \
116 } while (0)
117
118#define uvc_warn_once(dev, warn, msg...) \
119 do { \
120 if (!test_and_set_bit(warn, &dev->warnings)) \
121 printk(KERN_INFO "uvcvideo: " msg); \
122 } while (0)
123
124#define uvc_printk(level, msg...) \
125 printk(level "uvcvideo: " msg)
126
127/* ------------------------------------------------------------------------
128 * Driver specific constants
129 */
130
131#define DRIVER_VERSION "0.1.0"
132#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0)
133
134#define DMA_ADDR_INVALID (~(dma_addr_t)0)
135
136#define UVC_NUM_REQUESTS 4
137#define UVC_MAX_REQUEST_SIZE 64
138#define UVC_MAX_EVENTS 4
139
140#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
141#define USB_CLASS_MISC 0xef
142
143/* ------------------------------------------------------------------------
144 * Structures
145 */
146
147struct uvc_video
148{
149 struct usb_ep *ep;
150
151 /* Frame parameters */
152 u8 bpp;
153 u32 fcc;
154 unsigned int width;
155 unsigned int height;
156 unsigned int imagesize;
157
158 /* Requests */
159 unsigned int req_size;
160 struct usb_request *req[UVC_NUM_REQUESTS];
161 __u8 *req_buffer[UVC_NUM_REQUESTS];
162 struct list_head req_free;
163 spinlock_t req_lock;
164
165 void (*encode) (struct usb_request *req, struct uvc_video *video,
166 struct uvc_buffer *buf);
167
168 /* Context data used by the completion handler */
169 __u32 payload_size;
170 __u32 max_payload_size;
171
172 struct uvc_video_queue queue;
173 unsigned int fid;
174};
175
176enum uvc_state
177{
178 UVC_STATE_DISCONNECTED,
179 UVC_STATE_CONNECTED,
180 UVC_STATE_STREAMING,
181};
182
183struct uvc_device
184{
185 struct video_device *vdev;
186 enum uvc_state state;
187 struct usb_function func;
188 struct uvc_video video;
189
190 /* Descriptors */
191 struct {
192 const struct uvc_descriptor_header * const *control;
193 const struct uvc_descriptor_header * const *fs_streaming;
194 const struct uvc_descriptor_header * const *hs_streaming;
195 } desc;
196
197 unsigned int control_intf;
198 struct usb_ep *control_ep;
199 struct usb_request *control_req;
200 void *control_buf;
201
202 unsigned int streaming_intf;
203
204 /* Events */
205 unsigned int event_length;
206 unsigned int event_setup_out : 1;
207};
208
209static inline struct uvc_device *to_uvc(struct usb_function *f)
210{
211 return container_of(f, struct uvc_device, func);
212}
213
214struct uvc_file_handle
215{
216 struct v4l2_fh vfh;
217 struct uvc_video *device;
218};
219
220#define to_uvc_file_handle(handle) \
221 container_of(handle, struct uvc_file_handle, vfh)
222
223extern struct v4l2_file_operations uvc_v4l2_fops;
224
225/* ------------------------------------------------------------------------
226 * Functions
227 */
228
229extern int uvc_video_enable(struct uvc_video *video, int enable);
230extern int uvc_video_init(struct uvc_video *video);
231extern int uvc_video_pump(struct uvc_video *video);
232
233extern void uvc_endpoint_stream(struct uvc_device *dev);
234
235extern void uvc_function_connect(struct uvc_device *uvc);
236extern void uvc_function_disconnect(struct uvc_device *uvc);
237
238#endif /* __KERNEL__ */
239
240#endif /* _UVC_GADGET_H_ */
241
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
new file mode 100644
index 000000000000..43891991bf21
--- /dev/null
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -0,0 +1,583 @@
1/*
2 * uvc_queue.c -- USB Video Class driver - Buffers management
3 *
4 * Copyright (C) 2005-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <linux/list.h>
17#include <linux/module.h>
18#include <linux/usb.h>
19#include <linux/videodev2.h>
20#include <linux/vmalloc.h>
21#include <linux/wait.h>
22#include <asm/atomic.h>
23
24#include "uvc.h"
25
26/* ------------------------------------------------------------------------
27 * Video buffers queue management.
28 *
29 * Video queues is initialized by uvc_queue_init(). The function performs
30 * basic initialization of the uvc_video_queue struct and never fails.
31 *
32 * Video buffer allocation and freeing are performed by uvc_alloc_buffers and
33 * uvc_free_buffers respectively. The former acquires the video queue lock,
34 * while the later must be called with the lock held (so that allocation can
35 * free previously allocated buffers). Trying to free buffers that are mapped
36 * to user space will return -EBUSY.
37 *
38 * Video buffers are managed using two queues. However, unlike most USB video
39 * drivers that use an in queue and an out queue, we use a main queue to hold
40 * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
41 * hold empty buffers. This design (copied from video-buf) minimizes locking
42 * in interrupt, as only one queue is shared between interrupt and user
43 * contexts.
44 *
45 * Use cases
46 * ---------
47 *
48 * Unless stated otherwise, all operations that modify the irq buffers queue
49 * are protected by the irq spinlock.
50 *
51 * 1. The user queues the buffers, starts streaming and dequeues a buffer.
52 *
53 * The buffers are added to the main and irq queues. Both operations are
54 * protected by the queue lock, and the later is protected by the irq
55 * spinlock as well.
56 *
57 * The completion handler fetches a buffer from the irq queue and fills it
58 * with video data. If no buffer is available (irq queue empty), the handler
59 * returns immediately.
60 *
61 * When the buffer is full, the completion handler removes it from the irq
62 * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
63 * At that point, any process waiting on the buffer will be woken up. If a
64 * process tries to dequeue a buffer after it has been marked ready, the
65 * dequeing will succeed immediately.
66 *
67 * 2. Buffers are queued, user is waiting on a buffer and the device gets
68 * disconnected.
69 *
70 * When the device is disconnected, the kernel calls the completion handler
71 * with an appropriate status code. The handler marks all buffers in the
72 * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so
73 * that any process waiting on a buffer gets woken up.
74 *
75 * Waking up up the first buffer on the irq list is not enough, as the
76 * process waiting on the buffer might restart the dequeue operation
77 * immediately.
78 *
79 */
80
81void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
82{
83 mutex_init(&queue->mutex);
84 spin_lock_init(&queue->irqlock);
85 INIT_LIST_HEAD(&queue->mainqueue);
86 INIT_LIST_HEAD(&queue->irqqueue);
87 queue->type = type;
88}
89
90/*
91 * Allocate the video buffers.
92 *
93 * Pages are reserved to make sure they will not be swapped, as they will be
94 * filled in the URB completion handler.
95 *
96 * Buffers will be individually mapped, so they must all be page aligned.
97 */
98int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
99 unsigned int buflength)
100{
101 unsigned int bufsize = PAGE_ALIGN(buflength);
102 unsigned int i;
103 void *mem = NULL;
104 int ret;
105
106 if (nbuffers > UVC_MAX_VIDEO_BUFFERS)
107 nbuffers = UVC_MAX_VIDEO_BUFFERS;
108
109 mutex_lock(&queue->mutex);
110
111 if ((ret = uvc_free_buffers(queue)) < 0)
112 goto done;
113
114 /* Bail out if no buffers should be allocated. */
115 if (nbuffers == 0)
116 goto done;
117
118 /* Decrement the number of buffers until allocation succeeds. */
119 for (; nbuffers > 0; --nbuffers) {
120 mem = vmalloc_32(nbuffers * bufsize);
121 if (mem != NULL)
122 break;
123 }
124
125 if (mem == NULL) {
126 ret = -ENOMEM;
127 goto done;
128 }
129
130 for (i = 0; i < nbuffers; ++i) {
131 memset(&queue->buffer[i], 0, sizeof queue->buffer[i]);
132 queue->buffer[i].buf.index = i;
133 queue->buffer[i].buf.m.offset = i * bufsize;
134 queue->buffer[i].buf.length = buflength;
135 queue->buffer[i].buf.type = queue->type;
136 queue->buffer[i].buf.sequence = 0;
137 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
138 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
139 queue->buffer[i].buf.flags = 0;
140 init_waitqueue_head(&queue->buffer[i].wait);
141 }
142
143 queue->mem = mem;
144 queue->count = nbuffers;
145 queue->buf_size = bufsize;
146 ret = nbuffers;
147
148done:
149 mutex_unlock(&queue->mutex);
150 return ret;
151}
152
153/*
154 * Free the video buffers.
155 *
156 * This function must be called with the queue lock held.
157 */
158int uvc_free_buffers(struct uvc_video_queue *queue)
159{
160 unsigned int i;
161
162 for (i = 0; i < queue->count; ++i) {
163 if (queue->buffer[i].vma_use_count != 0)
164 return -EBUSY;
165 }
166
167 if (queue->count) {
168 vfree(queue->mem);
169 queue->count = 0;
170 }
171
172 return 0;
173}
174
175static void __uvc_query_buffer(struct uvc_buffer *buf,
176 struct v4l2_buffer *v4l2_buf)
177{
178 memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);
179
180 if (buf->vma_use_count)
181 v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED;
182
183 switch (buf->state) {
184 case UVC_BUF_STATE_ERROR:
185 case UVC_BUF_STATE_DONE:
186 v4l2_buf->flags |= V4L2_BUF_FLAG_DONE;
187 break;
188 case UVC_BUF_STATE_QUEUED:
189 case UVC_BUF_STATE_ACTIVE:
190 v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
191 break;
192 case UVC_BUF_STATE_IDLE:
193 default:
194 break;
195 }
196}
197
198int uvc_query_buffer(struct uvc_video_queue *queue,
199 struct v4l2_buffer *v4l2_buf)
200{
201 int ret = 0;
202
203 mutex_lock(&queue->mutex);
204 if (v4l2_buf->index >= queue->count) {
205 ret = -EINVAL;
206 goto done;
207 }
208
209 __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
210
211done:
212 mutex_unlock(&queue->mutex);
213 return ret;
214}
215
216/*
217 * Queue a video buffer. Attempting to queue a buffer that has already been
218 * queued will return -EINVAL.
219 */
220int uvc_queue_buffer(struct uvc_video_queue *queue,
221 struct v4l2_buffer *v4l2_buf)
222{
223 struct uvc_buffer *buf;
224 unsigned long flags;
225 int ret = 0;
226
227 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
228
229 if (v4l2_buf->type != queue->type ||
230 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
231 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
232 "and/or memory (%u).\n", v4l2_buf->type,
233 v4l2_buf->memory);
234 return -EINVAL;
235 }
236
237 mutex_lock(&queue->mutex);
238 if (v4l2_buf->index >= queue->count) {
239 uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
240 ret = -EINVAL;
241 goto done;
242 }
243
244 buf = &queue->buffer[v4l2_buf->index];
245 if (buf->state != UVC_BUF_STATE_IDLE) {
246 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state "
247 "(%u).\n", buf->state);
248 ret = -EINVAL;
249 goto done;
250 }
251
252 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
253 v4l2_buf->bytesused > buf->buf.length) {
254 uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
255 ret = -EINVAL;
256 goto done;
257 }
258
259 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
260 buf->buf.bytesused = 0;
261 else
262 buf->buf.bytesused = v4l2_buf->bytesused;
263
264 spin_lock_irqsave(&queue->irqlock, flags);
265 if (queue->flags & UVC_QUEUE_DISCONNECTED) {
266 spin_unlock_irqrestore(&queue->irqlock, flags);
267 ret = -ENODEV;
268 goto done;
269 }
270 buf->state = UVC_BUF_STATE_QUEUED;
271
272 ret = (queue->flags & UVC_QUEUE_PAUSED) != 0;
273 queue->flags &= ~UVC_QUEUE_PAUSED;
274
275 list_add_tail(&buf->stream, &queue->mainqueue);
276 list_add_tail(&buf->queue, &queue->irqqueue);
277 spin_unlock_irqrestore(&queue->irqlock, flags);
278
279done:
280 mutex_unlock(&queue->mutex);
281 return ret;
282}
283
284static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
285{
286 if (nonblocking) {
287 return (buf->state != UVC_BUF_STATE_QUEUED &&
288 buf->state != UVC_BUF_STATE_ACTIVE)
289 ? 0 : -EAGAIN;
290 }
291
292 return wait_event_interruptible(buf->wait,
293 buf->state != UVC_BUF_STATE_QUEUED &&
294 buf->state != UVC_BUF_STATE_ACTIVE);
295}
296
297/*
298 * Dequeue a video buffer. If nonblocking is false, block until a buffer is
299 * available.
300 */
301int uvc_dequeue_buffer(struct uvc_video_queue *queue,
302 struct v4l2_buffer *v4l2_buf, int nonblocking)
303{
304 struct uvc_buffer *buf;
305 int ret = 0;
306
307 if (v4l2_buf->type != queue->type ||
308 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
309 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
310 "and/or memory (%u).\n", v4l2_buf->type,
311 v4l2_buf->memory);
312 return -EINVAL;
313 }
314
315 mutex_lock(&queue->mutex);
316 if (list_empty(&queue->mainqueue)) {
317 uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
318 ret = -EINVAL;
319 goto done;
320 }
321
322 buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
323 if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
324 goto done;
325
326 uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
327 buf->buf.index, buf->state, buf->buf.bytesused);
328
329 switch (buf->state) {
330 case UVC_BUF_STATE_ERROR:
331 uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data "
332 "(transmission error).\n");
333 ret = -EIO;
334 case UVC_BUF_STATE_DONE:
335 buf->state = UVC_BUF_STATE_IDLE;
336 break;
337
338 case UVC_BUF_STATE_IDLE:
339 case UVC_BUF_STATE_QUEUED:
340 case UVC_BUF_STATE_ACTIVE:
341 default:
342 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
343 "(driver bug?).\n", buf->state);
344 ret = -EINVAL;
345 goto done;
346 }
347
348 list_del(&buf->stream);
349 __uvc_query_buffer(buf, v4l2_buf);
350
351done:
352 mutex_unlock(&queue->mutex);
353 return ret;
354}
355
356/*
357 * Poll the video queue.
358 *
359 * This function implements video queue polling and is intended to be used by
360 * the device poll handler.
361 */
362unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
363 poll_table *wait)
364{
365 struct uvc_buffer *buf;
366 unsigned int mask = 0;
367
368 mutex_lock(&queue->mutex);
369 if (list_empty(&queue->mainqueue))
370 goto done;
371
372 buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
373
374 poll_wait(file, &buf->wait, wait);
375 if (buf->state == UVC_BUF_STATE_DONE ||
376 buf->state == UVC_BUF_STATE_ERROR)
377 mask |= POLLOUT | POLLWRNORM;
378
379done:
380 mutex_unlock(&queue->mutex);
381 return mask;
382}
383
384/*
385 * VMA operations.
386 */
387static void uvc_vm_open(struct vm_area_struct *vma)
388{
389 struct uvc_buffer *buffer = vma->vm_private_data;
390 buffer->vma_use_count++;
391}
392
393static void uvc_vm_close(struct vm_area_struct *vma)
394{
395 struct uvc_buffer *buffer = vma->vm_private_data;
396 buffer->vma_use_count--;
397}
398
399static struct vm_operations_struct uvc_vm_ops = {
400 .open = uvc_vm_open,
401 .close = uvc_vm_close,
402};
403
404/*
405 * Memory-map a buffer.
406 *
407 * This function implements video buffer memory mapping and is intended to be
408 * used by the device mmap handler.
409 */
410int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
411{
412 struct uvc_buffer *uninitialized_var(buffer);
413 struct page *page;
414 unsigned long addr, start, size;
415 unsigned int i;
416 int ret = 0;
417
418 start = vma->vm_start;
419 size = vma->vm_end - vma->vm_start;
420
421 mutex_lock(&queue->mutex);
422
423 for (i = 0; i < queue->count; ++i) {
424 buffer = &queue->buffer[i];
425 if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
426 break;
427 }
428
429 if (i == queue->count || size != queue->buf_size) {
430 ret = -EINVAL;
431 goto done;
432 }
433
434 /*
435 * VM_IO marks the area as being an mmaped region for I/O to a
436 * device. It also prevents the region from being core dumped.
437 */
438 vma->vm_flags |= VM_IO;
439
440 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
441 while (size > 0) {
442 page = vmalloc_to_page((void *)addr);
443 if ((ret = vm_insert_page(vma, start, page)) < 0)
444 goto done;
445
446 start += PAGE_SIZE;
447 addr += PAGE_SIZE;
448 size -= PAGE_SIZE;
449 }
450
451 vma->vm_ops = &uvc_vm_ops;
452 vma->vm_private_data = buffer;
453 uvc_vm_open(vma);
454
455done:
456 mutex_unlock(&queue->mutex);
457 return ret;
458}
459
460/*
461 * Enable or disable the video buffers queue.
462 *
463 * The queue must be enabled before starting video acquisition and must be
464 * disabled after stopping it. This ensures that the video buffers queue
465 * state can be properly initialized before buffers are accessed from the
466 * interrupt handler.
467 *
468 * Enabling the video queue initializes parameters (such as sequence number,
469 * sync pattern, ...). If the queue is already enabled, return -EBUSY.
470 *
471 * Disabling the video queue cancels the queue and removes all buffers from
472 * the main queue.
473 *
474 * This function can't be called from interrupt context. Use
475 * uvc_queue_cancel() instead.
476 */
477int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
478{
479 unsigned int i;
480 int ret = 0;
481
482 mutex_lock(&queue->mutex);
483 if (enable) {
484 if (uvc_queue_streaming(queue)) {
485 ret = -EBUSY;
486 goto done;
487 }
488 queue->sequence = 0;
489 queue->flags |= UVC_QUEUE_STREAMING;
490 queue->buf_used = 0;
491 } else {
492 uvc_queue_cancel(queue, 0);
493 INIT_LIST_HEAD(&queue->mainqueue);
494
495 for (i = 0; i < queue->count; ++i)
496 queue->buffer[i].state = UVC_BUF_STATE_IDLE;
497
498 queue->flags &= ~UVC_QUEUE_STREAMING;
499 }
500
501done:
502 mutex_unlock(&queue->mutex);
503 return ret;
504}
505
506/*
507 * Cancel the video buffers queue.
508 *
509 * Cancelling the queue marks all buffers on the irq queue as erroneous,
510 * wakes them up and removes them from the queue.
511 *
512 * If the disconnect parameter is set, further calls to uvc_queue_buffer will
513 * fail with -ENODEV.
514 *
515 * This function acquires the irq spinlock and can be called from interrupt
516 * context.
517 */
518void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
519{
520 struct uvc_buffer *buf;
521 unsigned long flags;
522
523 spin_lock_irqsave(&queue->irqlock, flags);
524 while (!list_empty(&queue->irqqueue)) {
525 buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
526 queue);
527 list_del(&buf->queue);
528 buf->state = UVC_BUF_STATE_ERROR;
529 wake_up(&buf->wait);
530 }
531 /* This must be protected by the irqlock spinlock to avoid race
532 * conditions between uvc_queue_buffer and the disconnection event that
533 * could result in an interruptible wait in uvc_dequeue_buffer. Do not
534 * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
535 * state outside the queue code.
536 */
537 if (disconnect)
538 queue->flags |= UVC_QUEUE_DISCONNECTED;
539 spin_unlock_irqrestore(&queue->irqlock, flags);
540}
541
542struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
543 struct uvc_buffer *buf)
544{
545 struct uvc_buffer *nextbuf;
546 unsigned long flags;
547
548 if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
549 buf->buf.length != buf->buf.bytesused) {
550 buf->state = UVC_BUF_STATE_QUEUED;
551 buf->buf.bytesused = 0;
552 return buf;
553 }
554
555 spin_lock_irqsave(&queue->irqlock, flags);
556 list_del(&buf->queue);
557 if (!list_empty(&queue->irqqueue))
558 nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
559 queue);
560 else
561 nextbuf = NULL;
562 spin_unlock_irqrestore(&queue->irqlock, flags);
563
564 buf->buf.sequence = queue->sequence++;
565 do_gettimeofday(&buf->buf.timestamp);
566
567 wake_up(&buf->wait);
568 return nextbuf;
569}
570
571struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue)
572{
573 struct uvc_buffer *buf = NULL;
574
575 if (!list_empty(&queue->irqqueue))
576 buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
577 queue);
578 else
579 queue->flags |= UVC_QUEUE_PAUSED;
580
581 return buf;
582}
583
diff --git a/drivers/usb/gadget/uvc_queue.h b/drivers/usb/gadget/uvc_queue.h
new file mode 100644
index 000000000000..7f5a33fe7ae2
--- /dev/null
+++ b/drivers/usb/gadget/uvc_queue.h
@@ -0,0 +1,89 @@
1#ifndef _UVC_QUEUE_H_
2#define _UVC_QUEUE_H_
3
4#ifdef __KERNEL__
5
6#include <linux/kernel.h>
7#include <linux/poll.h>
8#include <linux/videodev2.h>
9
10/* Maximum frame size in bytes, for sanity checking. */
11#define UVC_MAX_FRAME_SIZE (16*1024*1024)
12/* Maximum number of video buffers. */
13#define UVC_MAX_VIDEO_BUFFERS 32
14
15/* ------------------------------------------------------------------------
16 * Structures.
17 */
18
19enum uvc_buffer_state {
20 UVC_BUF_STATE_IDLE = 0,
21 UVC_BUF_STATE_QUEUED = 1,
22 UVC_BUF_STATE_ACTIVE = 2,
23 UVC_BUF_STATE_DONE = 3,
24 UVC_BUF_STATE_ERROR = 4,
25};
26
27struct uvc_buffer {
28 unsigned long vma_use_count;
29 struct list_head stream;
30
31 /* Touched by interrupt handler. */
32 struct v4l2_buffer buf;
33 struct list_head queue;
34 wait_queue_head_t wait;
35 enum uvc_buffer_state state;
36};
37
38#define UVC_QUEUE_STREAMING (1 << 0)
39#define UVC_QUEUE_DISCONNECTED (1 << 1)
40#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2)
41#define UVC_QUEUE_PAUSED (1 << 3)
42
43struct uvc_video_queue {
44 enum v4l2_buf_type type;
45
46 void *mem;
47 unsigned int flags;
48 __u32 sequence;
49
50 unsigned int count;
51 unsigned int buf_size;
52 unsigned int buf_used;
53 struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS];
54 struct mutex mutex; /* protects buffers and mainqueue */
55 spinlock_t irqlock; /* protects irqqueue */
56
57 struct list_head mainqueue;
58 struct list_head irqqueue;
59};
60
61extern void uvc_queue_init(struct uvc_video_queue *queue,
62 enum v4l2_buf_type type);
63extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
64 unsigned int nbuffers, unsigned int buflength);
65extern int uvc_free_buffers(struct uvc_video_queue *queue);
66extern int uvc_query_buffer(struct uvc_video_queue *queue,
67 struct v4l2_buffer *v4l2_buf);
68extern int uvc_queue_buffer(struct uvc_video_queue *queue,
69 struct v4l2_buffer *v4l2_buf);
70extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
71 struct v4l2_buffer *v4l2_buf, int nonblocking);
72extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
73extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
74extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
75 struct uvc_buffer *buf);
76extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
77 struct file *file, poll_table *wait);
78extern int uvc_queue_mmap(struct uvc_video_queue *queue,
79 struct vm_area_struct *vma);
80static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
81{
82 return queue->flags & UVC_QUEUE_STREAMING;
83}
84extern struct uvc_buffer *uvc_queue_head(struct uvc_video_queue *queue);
85
86#endif /* __KERNEL__ */
87
88#endif /* _UVC_QUEUE_H_ */
89
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c
new file mode 100644
index 000000000000..a7989f29837e
--- /dev/null
+++ b/drivers/usb/gadget/uvc_v4l2.c
@@ -0,0 +1,374 @@
1/*
2 * uvc_v4l2.c -- USB Video Class Gadget driver
3 *
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/errno.h>
17#include <linux/list.h>
18#include <linux/mutex.h>
19#include <linux/version.h>
20#include <linux/videodev2.h>
21#include <linux/vmalloc.h>
22#include <linux/wait.h>
23
24#include <media/v4l2-dev.h>
25#include <media/v4l2-event.h>
26#include <media/v4l2-ioctl.h>
27
28#include "uvc.h"
29#include "uvc_queue.h"
30
31/* --------------------------------------------------------------------------
32 * Requests handling
33 */
34
35static int
36uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
37{
38 struct usb_composite_dev *cdev = uvc->func.config->cdev;
39 struct usb_request *req = uvc->control_req;
40
41 if (data->length < 0)
42 return usb_ep_set_halt(cdev->gadget->ep0);
43
44 req->length = min(uvc->event_length, data->length);
45 req->zero = data->length < uvc->event_length;
46 req->dma = DMA_ADDR_INVALID;
47
48 memcpy(req->buf, data->data, data->length);
49
50 return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
51}
52
53/* --------------------------------------------------------------------------
54 * V4L2
55 */
56
57struct uvc_format
58{
59 u8 bpp;
60 u32 fcc;
61};
62
63static struct uvc_format uvc_formats[] = {
64 { 16, V4L2_PIX_FMT_YUYV },
65 { 0, V4L2_PIX_FMT_MJPEG },
66};
67
68static int
69uvc_v4l2_get_format(struct uvc_video *video, struct v4l2_format *fmt)
70{
71 fmt->fmt.pix.pixelformat = video->fcc;
72 fmt->fmt.pix.width = video->width;
73 fmt->fmt.pix.height = video->height;
74 fmt->fmt.pix.field = V4L2_FIELD_NONE;
75 fmt->fmt.pix.bytesperline = video->bpp * video->width / 8;
76 fmt->fmt.pix.sizeimage = video->imagesize;
77 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
78 fmt->fmt.pix.priv = 0;
79
80 return 0;
81}
82
83static int
84uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt)
85{
86 struct uvc_format *format;
87 unsigned int imagesize;
88 unsigned int bpl;
89 unsigned int i;
90
91 for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) {
92 format = &uvc_formats[i];
93 if (format->fcc == fmt->fmt.pix.pixelformat)
94 break;
95 }
96
97 if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
98 printk(KERN_INFO "Unsupported format 0x%08x.\n",
99 fmt->fmt.pix.pixelformat);
100 return -EINVAL;
101 }
102
103 bpl = format->bpp * fmt->fmt.pix.width / 8;
104 imagesize = bpl ? bpl * fmt->fmt.pix.height : fmt->fmt.pix.sizeimage;
105
106 video->fcc = format->fcc;
107 video->bpp = format->bpp;
108 video->width = fmt->fmt.pix.width;
109 video->height = fmt->fmt.pix.height;
110 video->imagesize = imagesize;
111
112 fmt->fmt.pix.field = V4L2_FIELD_NONE;
113 fmt->fmt.pix.bytesperline = bpl;
114 fmt->fmt.pix.sizeimage = imagesize;
115 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
116 fmt->fmt.pix.priv = 0;
117
118 return 0;
119}
120
121static int
122uvc_v4l2_open(struct file *file)
123{
124 struct video_device *vdev = video_devdata(file);
125 struct uvc_device *uvc = video_get_drvdata(vdev);
126 struct uvc_file_handle *handle;
127 int ret;
128
129 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
130 if (handle == NULL)
131 return -ENOMEM;
132
133 ret = v4l2_fh_init(&handle->vfh, vdev);
134 if (ret < 0)
135 goto error;
136
137 ret = v4l2_event_init(&handle->vfh);
138 if (ret < 0)
139 goto error;
140
141 ret = v4l2_event_alloc(&handle->vfh, 8);
142 if (ret < 0)
143 goto error;
144
145 v4l2_fh_add(&handle->vfh);
146
147 handle->device = &uvc->video;
148 file->private_data = &handle->vfh;
149
150 uvc_function_connect(uvc);
151 return 0;
152
153error:
154 v4l2_fh_exit(&handle->vfh);
155 return ret;
156}
157
158static int
159uvc_v4l2_release(struct file *file)
160{
161 struct video_device *vdev = video_devdata(file);
162 struct uvc_device *uvc = video_get_drvdata(vdev);
163 struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
164 struct uvc_video *video = handle->device;
165
166 uvc_function_disconnect(uvc);
167
168 uvc_video_enable(video, 0);
169 mutex_lock(&video->queue.mutex);
170 if (uvc_free_buffers(&video->queue) < 0)
171 printk(KERN_ERR "uvc_v4l2_release: Unable to free "
172 "buffers.\n");
173 mutex_unlock(&video->queue.mutex);
174
175 file->private_data = NULL;
176 v4l2_fh_del(&handle->vfh);
177 v4l2_fh_exit(&handle->vfh);
178 kfree(handle);
179 return 0;
180}
181
182static long
183uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
184{
185 struct video_device *vdev = video_devdata(file);
186 struct uvc_device *uvc = video_get_drvdata(vdev);
187 struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
188 struct usb_composite_dev *cdev = uvc->func.config->cdev;
189 struct uvc_video *video = &uvc->video;
190 int ret = 0;
191
192 switch (cmd) {
193 /* Query capabilities */
194 case VIDIOC_QUERYCAP:
195 {
196 struct v4l2_capability *cap = arg;
197
198 memset(cap, 0, sizeof *cap);
199 strncpy(cap->driver, "g_uvc", sizeof(cap->driver));
200 strncpy(cap->card, cdev->gadget->name, sizeof(cap->card));
201 strncpy(cap->bus_info, dev_name(&cdev->gadget->dev),
202 sizeof cap->bus_info);
203 cap->version = DRIVER_VERSION_NUMBER;
204 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
205 break;
206 }
207
208 /* Get & Set format */
209 case VIDIOC_G_FMT:
210 {
211 struct v4l2_format *fmt = arg;
212
213 if (fmt->type != video->queue.type)
214 return -EINVAL;
215
216 return uvc_v4l2_get_format(video, fmt);
217 }
218
219 case VIDIOC_S_FMT:
220 {
221 struct v4l2_format *fmt = arg;
222
223 if (fmt->type != video->queue.type)
224 return -EINVAL;
225
226 return uvc_v4l2_set_format(video, fmt);
227 }
228
229 /* Buffers & streaming */
230 case VIDIOC_REQBUFS:
231 {
232 struct v4l2_requestbuffers *rb = arg;
233
234 if (rb->type != video->queue.type ||
235 rb->memory != V4L2_MEMORY_MMAP)
236 return -EINVAL;
237
238 ret = uvc_alloc_buffers(&video->queue, rb->count,
239 video->imagesize);
240 if (ret < 0)
241 return ret;
242
243 rb->count = ret;
244 ret = 0;
245 break;
246 }
247
248 case VIDIOC_QUERYBUF:
249 {
250 struct v4l2_buffer *buf = arg;
251
252 if (buf->type != video->queue.type)
253 return -EINVAL;
254
255 return uvc_query_buffer(&video->queue, buf);
256 }
257
258 case VIDIOC_QBUF:
259 if ((ret = uvc_queue_buffer(&video->queue, arg)) < 0)
260 return ret;
261
262 return uvc_video_pump(video);
263
264 case VIDIOC_DQBUF:
265 return uvc_dequeue_buffer(&video->queue, arg,
266 file->f_flags & O_NONBLOCK);
267
268 case VIDIOC_STREAMON:
269 {
270 int *type = arg;
271
272 if (*type != video->queue.type)
273 return -EINVAL;
274
275 return uvc_video_enable(video, 1);
276 }
277
278 case VIDIOC_STREAMOFF:
279 {
280 int *type = arg;
281
282 if (*type != video->queue.type)
283 return -EINVAL;
284
285 return uvc_video_enable(video, 0);
286 }
287
288 /* Events */
289 case VIDIOC_DQEVENT:
290 {
291 struct v4l2_event *event = arg;
292
293 ret = v4l2_event_dequeue(&handle->vfh, event,
294 file->f_flags & O_NONBLOCK);
295 if (ret == 0 && event->type == UVC_EVENT_SETUP) {
296 struct uvc_event *uvc_event = (void *)&event->u.data;
297
298 /* Tell the complete callback to generate an event for
299 * the next request that will be enqueued by
300 * uvc_event_write.
301 */
302 uvc->event_setup_out =
303 !(uvc_event->req.bRequestType & USB_DIR_IN);
304 uvc->event_length = uvc_event->req.wLength;
305 }
306
307 return ret;
308 }
309
310 case VIDIOC_SUBSCRIBE_EVENT:
311 {
312 struct v4l2_event_subscription *sub = arg;
313
314 if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
315 return -EINVAL;
316
317 return v4l2_event_subscribe(&handle->vfh, arg);
318 }
319
320 case VIDIOC_UNSUBSCRIBE_EVENT:
321 return v4l2_event_unsubscribe(&handle->vfh, arg);
322
323 case UVCIOC_SEND_RESPONSE:
324 ret = uvc_send_response(uvc, arg);
325 break;
326
327 default:
328 return -ENOIOCTLCMD;
329 }
330
331 return ret;
332}
333
334static long
335uvc_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
336{
337 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
338}
339
340static int
341uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
342{
343 struct video_device *vdev = video_devdata(file);
344 struct uvc_device *uvc = video_get_drvdata(vdev);
345
346 return uvc_queue_mmap(&uvc->video.queue, vma);
347}
348
349static unsigned int
350uvc_v4l2_poll(struct file *file, poll_table *wait)
351{
352 struct video_device *vdev = video_devdata(file);
353 struct uvc_device *uvc = video_get_drvdata(vdev);
354 struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
355 unsigned int mask = 0;
356
357 poll_wait(file, &handle->vfh.events->wait, wait);
358 if (v4l2_event_pending(&handle->vfh))
359 mask |= POLLPRI;
360
361 mask |= uvc_queue_poll(&uvc->video.queue, file, wait);
362
363 return mask;
364}
365
366struct v4l2_file_operations uvc_v4l2_fops = {
367 .owner = THIS_MODULE,
368 .open = uvc_v4l2_open,
369 .release = uvc_v4l2_release,
370 .ioctl = uvc_v4l2_ioctl,
371 .mmap = uvc_v4l2_mmap,
372 .poll = uvc_v4l2_poll,
373};
374
diff --git a/drivers/usb/gadget/uvc_video.c b/drivers/usb/gadget/uvc_video.c
new file mode 100644
index 000000000000..de8cbc46518d
--- /dev/null
+++ b/drivers/usb/gadget/uvc_video.c
@@ -0,0 +1,386 @@
1/*
2 * uvc_video.c -- USB Video Class Gadget driver
3 *
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/errno.h>
17#include <linux/usb/ch9.h>
18#include <linux/usb/gadget.h>
19
20#include <media/v4l2-dev.h>
21
22#include "uvc.h"
23#include "uvc_queue.h"
24
25/* --------------------------------------------------------------------------
26 * Video codecs
27 */
28
29static int
30uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
31 u8 *data, int len)
32{
33 data[0] = 2;
34 data[1] = UVC_STREAM_EOH | video->fid;
35
36 if (buf->buf.bytesused - video->queue.buf_used <= len - 2)
37 data[1] |= UVC_STREAM_EOF;
38
39 return 2;
40}
41
42static int
43uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
44 u8 *data, int len)
45{
46 struct uvc_video_queue *queue = &video->queue;
47 unsigned int nbytes;
48 void *mem;
49
50 /* Copy video data to the USB buffer. */
51 mem = queue->mem + buf->buf.m.offset + queue->buf_used;
52 nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
53
54 memcpy(data, mem, nbytes);
55 queue->buf_used += nbytes;
56
57 return nbytes;
58}
59
60static void
61uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
62 struct uvc_buffer *buf)
63{
64 void *mem = req->buf;
65 int len = video->req_size;
66 int ret;
67
68 /* Add a header at the beginning of the payload. */
69 if (video->payload_size == 0) {
70 ret = uvc_video_encode_header(video, buf, mem, len);
71 video->payload_size += ret;
72 mem += ret;
73 len -= ret;
74 }
75
76 /* Process video data. */
77 len = min((int)(video->max_payload_size - video->payload_size), len);
78 ret = uvc_video_encode_data(video, buf, mem, len);
79
80 video->payload_size += ret;
81 len -= ret;
82
83 req->length = video->req_size - len;
84 req->zero = video->payload_size == video->max_payload_size;
85
86 if (buf->buf.bytesused == video->queue.buf_used) {
87 video->queue.buf_used = 0;
88 buf->state = UVC_BUF_STATE_DONE;
89 uvc_queue_next_buffer(&video->queue, buf);
90 video->fid ^= UVC_STREAM_FID;
91
92 video->payload_size = 0;
93 }
94
95 if (video->payload_size == video->max_payload_size ||
96 buf->buf.bytesused == video->queue.buf_used)
97 video->payload_size = 0;
98}
99
100static void
101uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
102 struct uvc_buffer *buf)
103{
104 void *mem = req->buf;
105 int len = video->req_size;
106 int ret;
107
108 /* Add the header. */
109 ret = uvc_video_encode_header(video, buf, mem, len);
110 mem += ret;
111 len -= ret;
112
113 /* Process video data. */
114 ret = uvc_video_encode_data(video, buf, mem, len);
115 len -= ret;
116
117 req->length = video->req_size - len;
118
119 if (buf->buf.bytesused == video->queue.buf_used) {
120 video->queue.buf_used = 0;
121 buf->state = UVC_BUF_STATE_DONE;
122 uvc_queue_next_buffer(&video->queue, buf);
123 video->fid ^= UVC_STREAM_FID;
124 }
125}
126
127/* --------------------------------------------------------------------------
128 * Request handling
129 */
130
131/*
132 * I somehow feel that synchronisation won't be easy to achieve here. We have
133 * three events that control USB requests submission:
134 *
135 * - USB request completion: the completion handler will resubmit the request
136 * if a video buffer is available.
137 *
138 * - USB interface setting selection: in response to a SET_INTERFACE request,
139 * the handler will start streaming if a video buffer is available and if
140 * video is not currently streaming.
141 *
142 * - V4L2 buffer queueing: the driver will start streaming if video is not
143 * currently streaming.
144 *
145 * Race conditions between those 3 events might lead to deadlocks or other
146 * nasty side effects.
147 *
148 * The "video currently streaming" condition can't be detected by the irqqueue
149 * being empty, as a request can still be in flight. A separate "queue paused"
150 * flag is thus needed.
151 *
152 * The paused flag will be set when we try to retrieve the irqqueue head if the
153 * queue is empty, and cleared when we queue a buffer.
154 *
155 * The USB request completion handler will get the buffer at the irqqueue head
156 * under protection of the queue spinlock. If the queue is empty, the streaming
157 * paused flag will be set. Right after releasing the spinlock a userspace
158 * application can queue a buffer. The flag will then cleared, and the ioctl
159 * handler will restart the video stream.
160 */
161static void
162uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
163{
164 struct uvc_video *video = req->context;
165 struct uvc_buffer *buf;
166 unsigned long flags;
167 int ret;
168
169 switch (req->status) {
170 case 0:
171 break;
172
173 case -ESHUTDOWN:
174 printk(KERN_INFO "VS request cancelled.\n");
175 goto requeue;
176
177 default:
178 printk(KERN_INFO "VS request completed with status %d.\n",
179 req->status);
180 goto requeue;
181 }
182
183 spin_lock_irqsave(&video->queue.irqlock, flags);
184 buf = uvc_queue_head(&video->queue);
185 if (buf == NULL) {
186 spin_unlock_irqrestore(&video->queue.irqlock, flags);
187 goto requeue;
188 }
189
190 video->encode(req, video, buf);
191
192 if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) {
193 printk(KERN_INFO "Failed to queue request (%d).\n", ret);
194 usb_ep_set_halt(ep);
195 spin_unlock_irqrestore(&video->queue.irqlock, flags);
196 goto requeue;
197 }
198 spin_unlock_irqrestore(&video->queue.irqlock, flags);
199
200 return;
201
202requeue:
203 spin_lock_irqsave(&video->req_lock, flags);
204 list_add_tail(&req->list, &video->req_free);
205 spin_unlock_irqrestore(&video->req_lock, flags);
206}
207
208static int
209uvc_video_free_requests(struct uvc_video *video)
210{
211 unsigned int i;
212
213 for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
214 if (video->req[i]) {
215 usb_ep_free_request(video->ep, video->req[i]);
216 video->req[i] = NULL;
217 }
218
219 if (video->req_buffer[i]) {
220 kfree(video->req_buffer[i]);
221 video->req_buffer[i] = NULL;
222 }
223 }
224
225 INIT_LIST_HEAD(&video->req_free);
226 video->req_size = 0;
227 return 0;
228}
229
230static int
231uvc_video_alloc_requests(struct uvc_video *video)
232{
233 unsigned int i;
234 int ret = -ENOMEM;
235
236 BUG_ON(video->req_size);
237
238 for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
239 video->req_buffer[i] = kmalloc(video->ep->maxpacket, GFP_KERNEL);
240 if (video->req_buffer[i] == NULL)
241 goto error;
242
243 video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
244 if (video->req[i] == NULL)
245 goto error;
246
247 video->req[i]->buf = video->req_buffer[i];
248 video->req[i]->length = 0;
249 video->req[i]->dma = DMA_ADDR_INVALID;
250 video->req[i]->complete = uvc_video_complete;
251 video->req[i]->context = video;
252
253 list_add_tail(&video->req[i]->list, &video->req_free);
254 }
255
256 video->req_size = video->ep->maxpacket;
257 return 0;
258
259error:
260 uvc_video_free_requests(video);
261 return ret;
262}
263
264/* --------------------------------------------------------------------------
265 * Video streaming
266 */
267
268/*
269 * uvc_video_pump - Pump video data into the USB requests
270 *
271 * This function fills the available USB requests (listed in req_free) with
272 * video data from the queued buffers.
273 */
274int
275uvc_video_pump(struct uvc_video *video)
276{
277 struct usb_request *req;
278 struct uvc_buffer *buf;
279 unsigned long flags;
280 int ret;
281
282 /* FIXME TODO Race between uvc_video_pump and requests completion
283 * handler ???
284 */
285
286 while (1) {
287 /* Retrieve the first available USB request, protected by the
288 * request lock.
289 */
290 spin_lock_irqsave(&video->req_lock, flags);
291 if (list_empty(&video->req_free)) {
292 spin_unlock_irqrestore(&video->req_lock, flags);
293 return 0;
294 }
295 req = list_first_entry(&video->req_free, struct usb_request,
296 list);
297 list_del(&req->list);
298 spin_unlock_irqrestore(&video->req_lock, flags);
299
300 /* Retrieve the first available video buffer and fill the
301 * request, protected by the video queue irqlock.
302 */
303 spin_lock_irqsave(&video->queue.irqlock, flags);
304 buf = uvc_queue_head(&video->queue);
305 if (buf == NULL) {
306 spin_unlock_irqrestore(&video->queue.irqlock, flags);
307 break;
308 }
309
310 video->encode(req, video, buf);
311
312 /* Queue the USB request */
313 if ((ret = usb_ep_queue(video->ep, req, GFP_KERNEL)) < 0) {
314 printk(KERN_INFO "Failed to queue request (%d)\n", ret);
315 usb_ep_set_halt(video->ep);
316 spin_unlock_irqrestore(&video->queue.irqlock, flags);
317 break;
318 }
319 spin_unlock_irqrestore(&video->queue.irqlock, flags);
320 }
321
322 spin_lock_irqsave(&video->req_lock, flags);
323 list_add_tail(&req->list, &video->req_free);
324 spin_unlock_irqrestore(&video->req_lock, flags);
325 return 0;
326}
327
328/*
329 * Enable or disable the video stream.
330 */
331int
332uvc_video_enable(struct uvc_video *video, int enable)
333{
334 unsigned int i;
335 int ret;
336
337 if (video->ep == NULL) {
338 printk(KERN_INFO "Video enable failed, device is "
339 "uninitialized.\n");
340 return -ENODEV;
341 }
342
343 if (!enable) {
344 for (i = 0; i < UVC_NUM_REQUESTS; ++i)
345 usb_ep_dequeue(video->ep, video->req[i]);
346
347 uvc_video_free_requests(video);
348 uvc_queue_enable(&video->queue, 0);
349 return 0;
350 }
351
352 if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
353 return ret;
354
355 if ((ret = uvc_video_alloc_requests(video)) < 0)
356 return ret;
357
358 if (video->max_payload_size) {
359 video->encode = uvc_video_encode_bulk;
360 video->payload_size = 0;
361 } else
362 video->encode = uvc_video_encode_isoc;
363
364 return uvc_video_pump(video);
365}
366
367/*
368 * Initialize the UVC video stream.
369 */
370int
371uvc_video_init(struct uvc_video *video)
372{
373 INIT_LIST_HEAD(&video->req_free);
374 spin_lock_init(&video->req_lock);
375
376 video->fcc = V4L2_PIX_FMT_YUYV;
377 video->bpp = 16;
378 video->width = 320;
379 video->height = 240;
380 video->imagesize = 320 * 240 * 2;
381
382 /* Initialize the video buffers queue. */
383 uvc_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT);
384 return 0;
385}
386