V4L/DVB: cx18, cx23885, v4l2 doc, MAINTAINERS: Update Andy Walls' email address
[safe/jmp/linux-2.6] / drivers / media / video / cx18 / cx18-alsa-pcm.c
index 6e56df9..8f55692 100644 (file)
@@ -2,7 +2,7 @@
  *  ALSA PCM device for the
  *  ALSA interface to cx18 PCM capture streams
  *
- *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *  Copyright (C) 2009  Andy Walls <awalls@md.metrocast.net>
  *  Copyright (C) 2009  Devin Heitmueller <dheitmueller@kernellabs.com>
  *
  *  Portions of this work were sponsored by ONELAN Limited.
@@ -25,6 +25,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
 #include <media/v4l2-device.h>
 
@@ -78,7 +79,7 @@ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
        int period_elapsed = 0;
        int length;
 
-       dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%d\n", cxsc,
+       dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
                pcm_data, num_bytes);
 
        substream = cxsc->capture_pcm_substream;
@@ -151,31 +152,28 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
        struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
        struct cx18 *cx = to_cx18(v4l2_dev);
        struct cx18_stream *s;
-       struct cx18_open_id *item;
+       struct cx18_open_id item;
        int ret;
 
        /* Instruct the cx18 to start sending packets */
+       snd_cx18_lock(cxsc);
        s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
 
-       /* Allocate memory */
-       item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
-       if (NULL == item)
-               return -ENOMEM;
-
-       item->cx = cx;
-       item->type = s->type;
-       item->open_id = cx->open_id++;
+       item.cx = cx;
+       item.type = s->type;
+       item.open_id = cx->open_id++;
 
        /* See if the stream is available */
-       if (cx18_claim_stream(item, item->type)) {
+       if (cx18_claim_stream(&item, item.type)) {
                /* No, it's already in use */
-               kfree(item);
+               snd_cx18_unlock(cxsc);
                return -EBUSY;
        }
 
        if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
            test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
                /* We're already streaming.  No additional action required */
+               snd_cx18_unlock(cxsc);
                return 0;
        }
 
@@ -190,6 +188,7 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
        /* Not currently streaming, so start it up */
        set_bit(CX18_F_S_STREAMING, &s->s_flags);
        ret = cx18_start_v4l2_encode_stream(s);
+       snd_cx18_unlock(cxsc);
 
        return 0;
 }
@@ -203,6 +202,7 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
        int ret;
 
        /* Instruct the cx18 to stop sending packets */
+       snd_cx18_lock(cxsc);
        s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
        ret = cx18_stop_v4l2_encode_stream(s, 0);
        clear_bit(CX18_F_S_STREAMING, &s->s_flags);
@@ -210,6 +210,7 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
        cx18_release_stream(s);
 
        cx->pcm_announce_callback = NULL;
+       snd_cx18_unlock(cxsc);
 
        return 0;
 }