linux/drivers/usb/gadget/uvc_video.c
<<
>>
Prefs
   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#include <linux/kernel.h>
  14#include <linux/device.h>
  15#include <linux/errno.h>
  16#include <linux/usb/ch9.h>
  17#include <linux/usb/gadget.h>
  18
  19#include <media/v4l2-dev.h>
  20
  21#include "uvc.h"
  22#include "uvc_queue.h"
  23
  24/* --------------------------------------------------------------------------
  25 * Video codecs
  26 */
  27
  28static int
  29uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
  30                u8 *data, int len)
  31{
  32        data[0] = 2;
  33        data[1] = UVC_STREAM_EOH | video->fid;
  34
  35        if (buf->buf.bytesused - video->queue.buf_used <= len - 2)
  36                data[1] |= UVC_STREAM_EOF;
  37
  38        return 2;
  39}
  40
  41static int
  42uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
  43                u8 *data, int len)
  44{
  45        struct uvc_video_queue *queue = &video->queue;
  46        unsigned int nbytes;
  47        void *mem;
  48
  49        /* Copy video data to the USB buffer. */
  50        mem = queue->mem + buf->buf.m.offset + queue->buf_used;
  51        nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
  52
  53        memcpy(data, mem, nbytes);
  54        queue->buf_used += nbytes;
  55
  56        return nbytes;
  57}
  58
  59static void
  60uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
  61                struct uvc_buffer *buf)
  62{
  63        void *mem = req->buf;
  64        int len = video->req_size;
  65        int ret;
  66
  67        /* Add a header at the beginning of the payload. */
  68        if (video->payload_size == 0) {
  69                ret = uvc_video_encode_header(video, buf, mem, len);
  70                video->payload_size += ret;
  71                mem += ret;
  72                len -= ret;
  73        }
  74
  75        /* Process video data. */
  76        len = min((int)(video->max_payload_size - video->payload_size), len);
  77        ret = uvc_video_encode_data(video, buf, mem, len);
  78
  79        video->payload_size += ret;
  80        len -= ret;
  81
  82        req->length = video->req_size - len;
  83        req->zero = video->payload_size == video->max_payload_size;
  84
  85        if (buf->buf.bytesused == video->queue.buf_used) {
  86                video->queue.buf_used = 0;
  87                buf->state = UVC_BUF_STATE_DONE;
  88                uvc_queue_next_buffer(&video->queue, buf);
  89                video->fid ^= UVC_STREAM_FID;
  90
  91                video->payload_size = 0;
  92        }
  93
  94        if (video->payload_size == video->max_payload_size ||
  95            buf->buf.bytesused == video->queue.buf_used)
  96                video->payload_size = 0;
  97}
  98
  99static void
 100uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
 101                struct uvc_buffer *buf)
 102{
 103        void *mem = req->buf;
 104        int len = video->req_size;
 105        int ret;
 106
 107        /* Add the header. */
 108        ret = uvc_video_encode_header(video, buf, mem, len);
 109        mem += ret;
 110        len -= ret;
 111
 112        /* Process video data. */
 113        ret = uvc_video_encode_data(video, buf, mem, len);
 114        len -= ret;
 115
 116        req->length = video->req_size - len;
 117
 118        if (buf->buf.bytesused == video->queue.buf_used) {
 119                video->queue.buf_used = 0;
 120                buf->state = UVC_BUF_STATE_DONE;
 121                uvc_queue_next_buffer(&video->queue, buf);
 122                video->fid ^= UVC_STREAM_FID;
 123        }
 124}
 125
 126/* --------------------------------------------------------------------------
 127 * Request handling
 128 */
 129
 130/*
 131 * I somehow feel that synchronisation won't be easy to achieve here. We have
 132 * three events that control USB requests submission:
 133 *
 134 * - USB request completion: the completion handler will resubmit the request
 135 *   if a video buffer is available.
 136 *
 137 * - USB interface setting selection: in response to a SET_INTERFACE request,
 138 *   the handler will start streaming if a video buffer is available and if
 139 *   video is not currently streaming.
 140 *
 141 * - V4L2 buffer queueing: the driver will start streaming if video is not
 142 *   currently streaming.
 143 *
 144 * Race conditions between those 3 events might lead to deadlocks or other
 145 * nasty side effects.
 146 *
 147 * The "video currently streaming" condition can't be detected by the irqqueue
 148 * being empty, as a request can still be in flight. A separate "queue paused"
 149 * flag is thus needed.
 150 *
 151 * The paused flag will be set when we try to retrieve the irqqueue head if the
 152 * queue is empty, and cleared when we queue a buffer.
 153 *
 154 * The USB request completion handler will get the buffer at the irqqueue head
 155 * under protection of the queue spinlock. If the queue is empty, the streaming
 156 * paused flag will be set. Right after releasing the spinlock a userspace
 157 * application can queue a buffer. The flag will then cleared, and the ioctl
 158 * handler will restart the video stream.
 159 */
 160static void
 161uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
 162{
 163        struct uvc_video *video = req->context;
 164        struct uvc_buffer *buf;
 165        unsigned long flags;
 166        int ret;
 167
 168        switch (req->status) {
 169        case 0:
 170                break;
 171
 172        case -ESHUTDOWN:
 173                printk(KERN_INFO "VS request cancelled.\n");
 174                goto requeue;
 175
 176        default:
 177                printk(KERN_INFO "VS request completed with status %d.\n",
 178                        req->status);
 179                goto requeue;
 180        }
 181
 182        spin_lock_irqsave(&video->queue.irqlock, flags);
 183        buf = uvc_queue_head(&video->queue);
 184        if (buf == NULL) {
 185                spin_unlock_irqrestore(&video->queue.irqlock, flags);
 186                goto requeue;
 187        }
 188
 189        video->encode(req, video, buf);
 190
 191        if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) {
 192                printk(KERN_INFO "Failed to queue request (%d).\n", ret);
 193                usb_ep_set_halt(ep);
 194                spin_unlock_irqrestore(&video->queue.irqlock, flags);
 195                goto requeue;
 196        }
 197        spin_unlock_irqrestore(&video->queue.irqlock, flags);
 198
 199        return;
 200
 201requeue:
 202        spin_lock_irqsave(&video->req_lock, flags);
 203        list_add_tail(&req->list, &video->req_free);
 204        spin_unlock_irqrestore(&video->req_lock, flags);
 205}
 206
 207static int
 208uvc_video_free_requests(struct uvc_video *video)
 209{
 210        unsigned int i;
 211
 212        for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
 213                if (video->req[i]) {
 214                        usb_ep_free_request(video->ep, video->req[i]);
 215                        video->req[i] = NULL;
 216                }
 217
 218                if (video->req_buffer[i]) {
 219                        kfree(video->req_buffer[i]);
 220                        video->req_buffer[i] = NULL;
 221                }
 222        }
 223
 224        INIT_LIST_HEAD(&video->req_free);
 225        video->req_size = 0;
 226        return 0;
 227}
 228
 229static int
 230uvc_video_alloc_requests(struct uvc_video *video)
 231{
 232        unsigned int i;
 233        int ret = -ENOMEM;
 234
 235        BUG_ON(video->req_size);
 236
 237        for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
 238                video->req_buffer[i] = kmalloc(video->ep->maxpacket, GFP_KERNEL);
 239                if (video->req_buffer[i] == NULL)
 240                        goto error;
 241
 242                video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
 243                if (video->req[i] == NULL)
 244                        goto error;
 245
 246                video->req[i]->buf = video->req_buffer[i];
 247                video->req[i]->length = 0;
 248                video->req[i]->dma = DMA_ADDR_INVALID;
 249                video->req[i]->complete = uvc_video_complete;
 250                video->req[i]->context = video;
 251
 252                list_add_tail(&video->req[i]->list, &video->req_free);
 253        }
 254
 255        video->req_size = video->ep->maxpacket;
 256        return 0;
 257
 258error:
 259        uvc_video_free_requests(video);
 260        return ret;
 261}
 262
 263/* --------------------------------------------------------------------------
 264 * Video streaming
 265 */
 266
 267/*
 268 * uvc_video_pump - Pump video data into the USB requests
 269 *
 270 * This function fills the available USB requests (listed in req_free) with
 271 * video data from the queued buffers.
 272 */
 273static int
 274uvc_video_pump(struct uvc_video *video)
 275{
 276        struct usb_request *req;
 277        struct uvc_buffer *buf;
 278        unsigned long flags;
 279        int ret;
 280
 281        /* FIXME TODO Race between uvc_video_pump and requests completion
 282         * handler ???
 283         */
 284
 285        while (1) {
 286                /* Retrieve the first available USB request, protected by the
 287                 * request lock.
 288                 */
 289                spin_lock_irqsave(&video->req_lock, flags);
 290                if (list_empty(&video->req_free)) {
 291                        spin_unlock_irqrestore(&video->req_lock, flags);
 292                        return 0;
 293                }
 294                req = list_first_entry(&video->req_free, struct usb_request,
 295                                        list);
 296                list_del(&req->list);
 297                spin_unlock_irqrestore(&video->req_lock, flags);
 298
 299                /* Retrieve the first available video buffer and fill the
 300                 * request, protected by the video queue irqlock.
 301                 */
 302                spin_lock_irqsave(&video->queue.irqlock, flags);
 303                buf = uvc_queue_head(&video->queue);
 304                if (buf == NULL) {
 305                        spin_unlock_irqrestore(&video->queue.irqlock, flags);
 306                        break;
 307                }
 308
 309                video->encode(req, video, buf);
 310
 311                /* Queue the USB request */
 312                if ((ret = usb_ep_queue(video->ep, req, GFP_KERNEL)) < 0) {
 313                        printk(KERN_INFO "Failed to queue request (%d)\n", ret);
 314                        usb_ep_set_halt(video->ep);
 315                        spin_unlock_irqrestore(&video->queue.irqlock, flags);
 316                        break;
 317                }
 318                spin_unlock_irqrestore(&video->queue.irqlock, flags);
 319        }
 320
 321        spin_lock_irqsave(&video->req_lock, flags);
 322        list_add_tail(&req->list, &video->req_free);
 323        spin_unlock_irqrestore(&video->req_lock, flags);
 324        return 0;
 325}
 326
 327/*
 328 * Enable or disable the video stream.
 329 */
 330static int
 331uvc_video_enable(struct uvc_video *video, int enable)
 332{
 333        unsigned int i;
 334        int ret;
 335
 336        if (video->ep == NULL) {
 337                printk(KERN_INFO "Video enable failed, device is "
 338                        "uninitialized.\n");
 339                return -ENODEV;
 340        }
 341
 342        if (!enable) {
 343                for (i = 0; i < UVC_NUM_REQUESTS; ++i)
 344                        usb_ep_dequeue(video->ep, video->req[i]);
 345
 346                uvc_video_free_requests(video);
 347                uvc_queue_enable(&video->queue, 0);
 348                return 0;
 349        }
 350
 351        if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
 352                return ret;
 353
 354        if ((ret = uvc_video_alloc_requests(video)) < 0)
 355                return ret;
 356
 357        if (video->max_payload_size) {
 358                video->encode = uvc_video_encode_bulk;
 359                video->payload_size = 0;
 360        } else
 361                video->encode = uvc_video_encode_isoc;
 362
 363        return uvc_video_pump(video);
 364}
 365
 366/*
 367 * Initialize the UVC video stream.
 368 */
 369static int
 370uvc_video_init(struct uvc_video *video)
 371{
 372        INIT_LIST_HEAD(&video->req_free);
 373        spin_lock_init(&video->req_lock);
 374
 375        video->fcc = V4L2_PIX_FMT_YUYV;
 376        video->bpp = 16;
 377        video->width = 320;
 378        video->height = 240;
 379        video->imagesize = 320 * 240 * 2;
 380
 381        /* Initialize the video buffers queue. */
 382        uvc_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 383        return 0;
 384}
 385
 386