static int videobuf_dvb_thread(void *data) { struct videobuf_dvb *dvb = data; struct videobuf_buffer *buf; unsigned long flags; int err; void *outp; dprintk("dvb thread started\n"); set_freezable(); videobuf_read_start(&dvb->dvbq); for (;;) { /* fetch next buffer */ buf = list_entry(dvb->dvbq.stream.next, struct videobuf_buffer, stream); list_del(&buf->stream); err = videobuf_waiton(buf,0,1); /* no more feeds left or stop_feed() asked us to quit */ if (0 == dvb->nfeeds) break; if (kthread_should_stop()) break; try_to_freeze(); /* feed buffer data to demux */ outp = videobuf_queue_to_vmalloc (&dvb->dvbq, buf); if (buf->state == VIDEOBUF_DONE) dvb_dmx_swfilter(&dvb->demux, outp, buf->size); /* requeue buffer */ list_add_tail(&buf->stream,&dvb->dvbq.stream); spin_lock_irqsave(dvb->dvbq.irqlock,flags); dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf); spin_unlock_irqrestore(dvb->dvbq.irqlock,flags); } videobuf_read_stop(&dvb->dvbq); dprintk("dvb thread stopped\n"); /* Hmm, linux becomes *very* unhappy without this ... */ while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } return 0; }
static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { struct solo6010_dev *solo_dev = fh->solo_dev; dma_addr_t vbuf; unsigned int fdma_addr; int error = -1; int i; if (!(vbuf = videobuf_to_dma_contig(vb))) goto finish_buf; if (erase_off(solo_dev)) { void *p = videobuf_queue_to_vmalloc(&fh->vidq, vb); int image_size = solo_image_size(solo_dev); for (i = 0; i < image_size; i += 2) { ((u8 *)p)[i] = 0x80; ((u8 *)p)[i + 1] = 0x00; } error = 0; } else { fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * (SOLO_HW_BPL * solo_vlines(solo_dev))); error = solo_p2m_dma_t(solo_dev, 0, vbuf, fdma_addr, solo_bytesperline(solo_dev), solo_vlines(solo_dev), SOLO_HW_BPL); } finish_buf: if (error) { vb->state = VIDEOBUF_ERROR; } else { vb->state = VIDEOBUF_DONE; vb->field_count++; } wake_up(&vb->done); }