diff -urp ivtv.vanilla/driver/Makefile ivtv/driver/Makefile --- ivtv.vanilla/driver/Makefile 2003-11-01 09:35:36.000000000 +0100 +++ ivtv/driver/Makefile 2003-11-08 22:11:56.000000000 +0100 @@ -1,7 +1,9 @@ -KERNELDIR = /usr/src/linux +KERNELDIR = /lib/modules/`uname -r`/build MODDIR = /lib/modules/`uname -r`/kernel/drivers/media/video -CROSS_COMPILE = -LD = $(CROSS_COMPILE)ld +CROSS_COMPILE = +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar IVTVOBJS = ivtv-driver.o ivtv-i2c.o ivtv-api.o OBJS = msp3400.o saa7115.o tveeprom.o ivtv.o saa7127.o ivtv-fb.o @@ -9,10 +11,6 @@ include $(KERNELDIR)/.config CFLAGS = -D__KERNEL__ -D__KERNEL_SYSCALLS__ -DMODULE -DMODVERSIONS -I$(KERNELDIR)/include -O2 -fomit-frame-pointer -march=i586 -mcpu=i586 -fno-strict-aliasing -Wno-unused -include $(KERNELDIR)/include/linux/modversions.h -ifdef CONFIG_SMP - CFLAGS += -D__SMP__ -DSMP -endif - # uncomment if you use i2c 2.8.0+ #CFLAGS += -DNEW_I2C diff -urp ivtv.vanilla/driver/ivtv-api.c ivtv/driver/ivtv-api.c --- ivtv.vanilla/driver/ivtv-api.c 2003-11-01 09:35:36.000000000 +0100 +++ ivtv/driver/ivtv-api.c 2003-11-08 22:02:50.000000000 +0100 @@ -1481,47 +1481,47 @@ int ivtv_v4l2_open(struct inode *inode, int ivtv_v4l2_read(struct file *filp, char *buf, size_t count, loff_t *pos) { struct ivtv_open_id *id = filp->private_data; - + struct ivtv *itv = id->itv; + struct ivtv_v4l2_stream *stream; int ret=0; - + IVTV_DEBUG(IVTV_DEBUG_INFO,"v4l2 read\n"); - if (down_interruptible(&id->itv->sem_lock)) + if (down_interruptible(&itv->sem_lock)) return -ERESTARTSYS; - //FIXME need to handle non-blocking io - //FIXME needs locking - //FIXME this can be collapsed into 1 var i think - if (!test_bit(IVTV_F_S_CAP, &id->itv->v4l2.streams[id->type].s_flags) && - (id->itv->v4l2.streams[id->type].id == -1)) { - - set_bit(IVTV_F_S_CAP, &id->itv->v4l2.streams[id->type].s_flags); - id->itv->v4l2.streams[id->type].id = id->open_id; + stream = &itv->v4l2.streams[id->type]; - ret = ivtv_start_v4l2_stream(id); - if (ret) - IVTV_DEBUG(IVTV_DEBUG_INFO, - "Error in v4l2 stream init\n"); - id->itv->v4l2.streams[id->type].seq = 0; - id->itv->v4l2.streams[id->type].ubytes= 0; + if (!test_and_set_bit(IVTV_F_S_CAP, &stream->s_flags) + && stream->id == -1) { + stream->id = id->open_id; + + ret = ivtv_start_v4l2_stream(id); + if (ret) { + IVTV_DEBUG(IVTV_DEBUG_INFO, + "Error in v4l2 stream init\n"); + /* bit of a hack... but try to reload firmware + * if capture init fails */ + ret = ivtv_firmware_copy(itv); + if (!ret) + ret = ivtv_start_v4l2_stream(id); + } + stream->seq = 0; + stream->ubytes = 0; } else { - if (id->open_id != id->itv->v4l2.streams[id->type].id) + if (id->open_id != stream->id) ret = -EBUSY; } - up(&id->itv->sem_lock); + up(&itv->sem_lock); if (ret) return ret; - if (filp->f_flags & O_NONBLOCK) { - if(!(ivtv_stream_has_data(id)) ) - return -EAGAIN; - } - - ret = ivtv_read(id,buf,count); + ret = ivtv_read(id, buf, count, !(filp->f_flags & O_NONBLOCK)); - if (ret > 0) *pos += ret; + if (ret > 0) + *pos += ret; return ret; } @@ -1529,6 +1529,8 @@ int ivtv_v4l2_read(struct file *filp, ch ssize_t ivtv_v4l2_write(struct file *filp, const char *buf, size_t count, loff_t *pos) { struct ivtv_open_id *id = filp->private_data; + struct ivtv *itv = id->itv; + struct ivtv_v4l2_stream *stream; int ret=0; if ( (id->type != IVTV_DEC_STREAM_TYPE_MPG) && @@ -1537,20 +1539,21 @@ ssize_t ivtv_v4l2_write(struct file *fil return -EINVAL; } - if (down_interruptible(&id->itv->sem_lock)) + if (down_interruptible(&itv->sem_lock)) return -ERESTARTSYS; // Initialize Decoder /* FIXME we'll need to make this its own stream type */ - if (!test_and_set_bit(IVTV_F_S_CAP, &id->itv->v4l2.streams[id->type].s_flags)) { - id->itv->v4l2.streams[id->type].id = id->open_id; + stream = &itv->v4l2.streams[id->type]; + if (!test_and_set_bit(IVTV_F_S_CAP, &stream->s_flags)) { + stream->id = id->open_id; ret = ivtv_start_v4l2_decode(id); } else { - if (id->open_id != id->itv->v4l2.streams[id->type].id) + if (id->open_id != stream->id) ret = -EBUSY; } - up(&id->itv->sem_lock); + up(&itv->sem_lock); if (ret) return ret; diff -urp ivtv.vanilla/driver/ivtv-driver.c ivtv/driver/ivtv-driver.c --- ivtv.vanilla/driver/ivtv-driver.c 2003-11-02 07:27:07.000000000 +0100 +++ ivtv/driver/ivtv-driver.c 2003-11-08 22:03:06.000000000 +0100 @@ -70,8 +70,6 @@ int tuner = -1; int errno; -unsigned long oldest_ts; - #ifdef YUV_FIXUP MODULE_PARM(yuv_fixup, "i"); MODULE_PARM_DESC(yuv_fixup, @@ -209,6 +207,17 @@ int ivtv_enq_buf(struct ivtv *itv, struc return 0; } +/* called to remove the buffer returned by _peek_ functions */ +void ivtv_del_buf(struct ivtv *itv, struct ivtv_buffer_list *queue, + struct ivtv_buffer *buffer) { + unsigned long flags; + + spin_lock_irqsave(&itv->lock, flags); + list_del_init(&buffer->list); + queue->elements--; + spin_unlock_irqrestore(&itv->lock, flags); +} + /* returns first item in queue, doesn't dequeue */ struct ivtv_buffer *ivtv_deq_peek_head(struct ivtv *itv, struct ivtv_buffer_list *queue) { @@ -367,11 +376,14 @@ int ivtv_init_queue(struct ivtv *itv, st int ivtv_move_queue(struct ivtv *itv, struct ivtv_buffer_list *src, struct ivtv_buffer_list *dst) { struct ivtv_buffer *buf; + unsigned long flags; - while ((buf = ivtv_deq_buf(itv, src))) { - ivtv_enq_buf(itv, dst, buf); - } + spin_lock_irqsave(&itv->lock, flags); + while ((buf = __ivtv_deq_buf(src))) + __ivtv_enq_buf(dst, buf); + + spin_unlock_irqrestore(&itv->lock, flags); return 0; } @@ -1441,6 +1453,11 @@ void ivtv_sched_DMA_tasklet(unsigned lon } /* mark overflow condition, next free will restart dma req */ set_bit(IVTV_F_S_OVERFLOW, &itv->v4l2.streams[type].s_flags); + /* FIXME: must wait a little bit, perhaps use timer to fire + * this tasklet */ +#if 1 + tasklet_schedule(&itv->dma_sched_tq); +#endif return; } @@ -1983,7 +2000,7 @@ static int ivtv_YUV_fixup(struct ivtv_v4 #endif -long ivtv_read(struct ivtv_open_id *id, char *ubuf, size_t count) { +long ivtv_read(struct ivtv_open_id *id, char *ubuf, size_t count, int block) { int x, sleepctr, datalen, retval=0; struct ivtv *itv = id->itv; size_t newcount; @@ -2017,6 +2034,11 @@ long ivtv_read(struct ivtv_open_id *id, if (buf) break; + if (!block) { + retval = -EAGAIN; + break; + } + ivtv_sleep_timeout(IVTV_SLEEP_WAIT); if (signal_pending(current)) @@ -2089,20 +2111,12 @@ long ivtv_read(struct ivtv_open_id *id, /* if buffer is empty or we've read the whole frame */ if ((buf->buffer.bytesused == 0)) { - spin_lock_irq(&itv->lock); - - list_del(&buf->list); - __ivtv_enq_buf(&st->free_q, buf); - spin_unlock_irq(&itv->lock); + ivtv_del_buf(itv, &st->full_q, buf); + ivtv_enq_buf(itv, &st->free_q, buf); if (test_and_clear_bit(IVTV_F_S_OVERFLOW, &st->s_flags)) tasklet_schedule(&itv->dma_sched_tq); - if (jiffies - buf->ts > oldest_ts) { - oldest_ts = jiffies - buf->ts; - printk(KERN_DEBUG "ivtv: oldest buffer %lu jiffies\n", jiffies - buf->ts); - } - buf = ivtv_deq_peek_head(itv, &st->full_q); if (buf) { tid = buf->buffer.sequence; @@ -2134,28 +2148,27 @@ long ivtv_read(struct ivtv_open_id *id, void ivtv_swap_copy(const char *buf, const char *ubuf, size_t count) { u32 *src,*dst; - //int y; src=(u32 *)ubuf; dst=(u32 *)buf; - /* FIXME this might break on non X86 */ -// #if __CPU__ > 386 - /* Ultra-efficient swab+copy! */ - while ((u32)src <= (u32)ubuf + count) { /* byteswap while copying */ - __asm__ __volatile__ ("bswap %0" : - "=r" (*dst) : - "0" (*src) ); - src++;dst++; - } -// #else - #if 0 - /* Old slow memcpy then swab */ - memcpy((void *)buf,(void *)ubuf,count); - for (y = 0; y < count; y += 4) { - swab32s( (u32 *)((u32)buf + y)); - } - #endif +#ifdef CONFIG_X86 + while ((u32)src <= (u32)ubuf + count) { /* byteswap while copying */ + __asm__ __volatile__ ("bswap %0" : + "=r" (*dst) : + "0" (*src) ); + src++;dst++; + } +#else + { + int y; + /* Old slow memcpy then swab */ + memcpy((void *)buf,(void *)ubuf,count); + for (y = 0; y < count; y += 4) { + swab32s( (u32 *)((u32)buf + y)); + } + } +#endif } int ivtv_fill_dec_buffers(struct ivtv_open_id *id, const char *ubuf, size_t count) { @@ -2197,8 +2210,7 @@ int ivtv_fill_dec_buffers(struct ivtv_op break; } - if (test_bit(IVTV_F_I_NEEDS_DATA, &itv->i_flags)) - ivtv_dec_sched_DMA(id->itv); + ivtv_dec_sched_DMA(id->itv); } while (!buf); set_current_state(TASK_RUNNING); remove_wait_queue(&stream->waitq, &wait); @@ -2229,10 +2241,8 @@ int ivtv_fill_dec_buffers(struct ivtv_op /* enq buffer when full */ if (buf->buffer.bytesused == IVTV_DMA_DEC_BUF_SIZE) { - spin_lock_irq(&itv->lock); - list_del(&buf->list); - __ivtv_enq_buf(&stream->full_q, buf); - spin_unlock_irq(&itv->lock); + ivtv_del_buf(itv, &stream->free_q, buf); + ivtv_enq_buf(itv, &stream->full_q, buf); } } @@ -2305,12 +2315,12 @@ void ivtv_dec_sched_DMA(struct ivtv *itv stream = &itv->v4l2.streams[type]; - if (test_bit(IVTV_F_I_DMAP, &itv->i_flags)) { + if (test_bit(IVTV_F_I_BUSY, &itv->i_flags)) { IVTV_DEBUG(IVTV_DEBUG_INFO, "DEC: decoder busy, delaying\n"); set_bit(IVTV_F_I_NEEDS_DATA, &itv->i_flags); return; } - + /* If we got this far, we have data to send and it wants it */ clear_bit(IVTV_F_I_NEEDS_DATA, &itv->i_flags); @@ -2319,7 +2329,6 @@ void ivtv_dec_sched_DMA(struct ivtv *itv mem_size = data[2]; buffer_bytes = data[3]; /* # bytes in card's buffer */ - while ((max > x) && (mem_size > bytes_written)) { /* send a maximum of 'max' buffers */ buf = ivtv_deq_peek_head(itv, &stream->full_q); @@ -2362,10 +2371,8 @@ void ivtv_dec_sched_DMA(struct ivtv *itv /* buffer is empty? */ if (buf->buffer.bytesused == 0) { - spin_lock_irqsave(&itv->lock, flags); - list_del(&buf->list); - __ivtv_enq_buf(&stream->dma_q, buf); - spin_unlock_irqrestore(&itv->lock, flags); + ivtv_del_buf(itv, &stream->full_q, buf); + ivtv_enq_buf(itv, &stream->dma_q, buf); } x++; } @@ -2390,7 +2397,7 @@ void ivtv_dec_sched_DMA(struct ivtv *itv /* note that we're DMA'ing */ mod_timer(&itv->dec_timeout, jiffies + DEC_DMA_TIMEOUT); set_bit(IVTV_F_S_DMAP, &stream->s_flags); - set_bit(IVTV_F_I_DMAP, &itv->i_flags); + set_bit(IVTV_F_I_BUSY, &itv->i_flags); ivtv_api_irqsafe(itv->dec_mbox, IVTV_API_DEC_DMA_FROM_HOST, 3,&data[0]); spin_unlock_irqrestore(&itv->lock, flags); @@ -2410,13 +2417,13 @@ void ivtv_dec_DMA_done(struct ivtv *itv) spin_lock_irqsave(&itv->lock, flags); - if (!test_and_clear_bit(IVTV_F_I_DMAP, &itv->i_flags)) { + if (!test_and_clear_bit(IVTV_F_I_BUSY, &itv->i_flags)) { IVTV_DEBUG(IVTV_DEBUG_ERR, "DMAP not set\n"); spin_unlock_irqrestore(&itv->lock, flags); goto debug; } - mod_timer(&itv->dec_timeout, jiffies + DEC_DMA_TIMEOUT); + del_timer(&itv->dec_timeout); for (y=IVTV_DEC_STREAM_TYPE_MPG; y < itv->v4l2.streamcount; y++) { if (test_and_clear_bit(IVTV_F_S_DMAP, &itv->v4l2.streams[y].s_flags)) { @@ -2428,21 +2435,15 @@ void ivtv_dec_DMA_done(struct ivtv *itv) spin_unlock_irqrestore(&itv->lock, flags); /* Handle OSD DMA */ - if ((itv->user_dma_to_device_state != NULL) && - (itv->user_dma_to_device_state->page_count != 0)) { + if (test_and_clear_bit(IVTV_F_I_OSD_DMA, &itv->i_flags)) { IVTV_DEBUG(IVTV_DEBUG_INFO, "OSD: DMA Done\n"); - itv->user_dma_to_device_state->page_count = 0; - - up(&itv->user_dma_to_device_state->lock); - /* wake all the normal streams, in case they fell asleep */ for (y=IVTV_DEC_STREAM_TYPE_MPG; y < itv->v4l2.streamcount; y++) { wake_up(&itv->v4l2.streams[y].waitq); } wake_up(&itv->dec_master_w); - return; } @@ -2511,46 +2512,10 @@ int ivtv_get_timing_info(struct ivtv *it } ssize_t ivtv_write(struct ivtv_open_id *id, const char *ubuf, size_t count) { -#if 0 - u32 result, data[IVTV_MBOX_MAX_DATA]; - u32 dec_cnt; - struct ivtv *itv=id->itv; -#endif int bytes_written=0, ret; IVTV_DEBUG(IVTV_DEBUG_INFO, "ivtv_write\n"); -#if 0 /* Lots of extra debugging stuff */ - /* Last DMA status? */ - if (ivtv_api(itv->dec_mbox, &itv->sem_lock, - IVTV_API_DEC_DMA_STATUS,&result,0,&data[0])) { - IVTV_DEBUG(IVTV_DEBUG_ERR, "DEC: error sending status req\n"); - } - - IVTV_DEBUG(IVTV_DEBUG_INFO, - "DEC: DMA status bitmask 0x%08x, stream type: 0x%08x\n", - data[0], data[1]); - - /* buffer fullness stats */ - if (ivtv_api(itv->dec_mbox, &itv->sem_lock, - IVTV_API_DEC_XFER_INFO,&result,0,&data[0])) { - IVTV_DEBUG(IVTV_DEBUG_ERR, "DEC: error sending DMA info\n"); - } - - IVTV_DEBUG(IVTV_DEBUG_INFO, - "DEC: Stream type: 0x%08x, maxbytes 0x%08x, bufferbytes 0x%08x\n", - data[0], data[2], data[3]); - - - /* Timing info. */ - if (ivtv_api(itv->dec_mbox, &itv->sem_lock, - IVTV_API_DEC_TIMING_INFO,&result,0,&data[0])) { - IVTV_DEBUG(IVTV_DEBUG_ERR, "DEC: err sending timing info\n"); - } - - IVTV_DEBUG(IVTV_DEBUG_INFO, "DEC: Frames decoded 0x%08x\n", data[0]); -#endif - while (bytes_written < count) { /* completely use up user data * before returning */ /* buffer the data - this may block waiting on free buffers */ diff -urp ivtv.vanilla/driver/ivtv-fb.c ivtv/driver/ivtv-fb.c --- ivtv.vanilla/driver/ivtv-fb.c 2003-11-01 09:35:36.000000000 +0100 +++ ivtv/driver/ivtv-fb.c 2003-11-08 22:01:58.000000000 +0100 @@ -137,9 +137,12 @@ console hijacks, and allow you to unload #include #include -#include #include +#ifdef CONFIG_MTRR +#include +#endif + #include