Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[pandora-kernel.git] / drivers / media / video / ivtv / ivtv-fileops.c
index 6fb96f1..7ec5c99 100644 (file)
@@ -219,7 +219,9 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
                        /* Process pending program info updates and pending VBI data */
                        ivtv_update_pgm_info(itv);
 
-                       if (jiffies - itv->dualwatch_jiffies > msecs_to_jiffies(1000)) {
+                       if (time_after(jiffies,
+                                      itv->dualwatch_jiffies +
+                                      msecs_to_jiffies(1000))) {
                                itv->dualwatch_jiffies = jiffies;
                                ivtv_dualwatch(itv);
                        }
@@ -580,12 +582,25 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
        ivtv_queue_init(&q);
        set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
 
+       /* Start decoder (returns 0 if already started) */
+       mutex_lock(&itv->serialize_lock);
+       rc = ivtv_start_decoding(id, itv->speed);
+       mutex_unlock(&itv->serialize_lock);
+       if (rc) {
+               IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
+
+               /* failure, clean up */
+               clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+               return rc;
+       }
+
 retry:
        /* If possible, just DMA the entire frame - Check the data transfer size
        since we may get here before the stream has been fully set-up */
        if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
                while (count >= itv->dma_data_req_size) {
-                       if (!ivtv_yuv_udma_stream_frame (itv, (void *)user_buf)) {
+                       if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) {
                                bytes_written += itv->dma_data_req_size;
                                user_buf += itv->dma_data_req_size;
                                count -= itv->dma_data_req_size;
@@ -662,18 +677,6 @@ retry:
                ivtv_enqueue(s, buf, &s->q_full);
        }
 
-       /* Start decoder (returns 0 if already started) */
-       mutex_lock(&itv->serialize_lock);
-       rc = ivtv_start_decoding(id, itv->speed);
-       mutex_unlock(&itv->serialize_lock);
-       if (rc) {
-               IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
-
-               /* failure, clean up */
-               clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
-               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-               return rc;
-       }
        if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
                if (s->q_full.length >= itv->dma_data_req_size) {
                        int got_sig;
@@ -753,8 +756,10 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
        IVTV_DEBUG_HI_FILE("Encoder poll\n");
        poll_wait(filp, &s->waitq, wait);
 
-       if (eof || s->q_full.length)
+       if (s->q_full.length || s->q_io.length)
                return POLLIN | POLLRDNORM;
+       if (eof)
+               return POLLHUP;
        return 0;
 }
 
@@ -983,6 +988,8 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
        /* Find which card this open was on */
        spin_lock(&ivtv_cards_lock);
        for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+               if (ivtv_cards[x] == NULL)
+                       continue;
                /* find out which stream this open was on */
                for (y = 0; y < IVTV_MAX_STREAMS; y++) {
                        s = &ivtv_cards[x]->streams[y];