diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-03-14 12:12:39 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-03-14 12:12:39 -0300 |
commit | 1c56b8f4079af9413ea15f420259e97187a3bf7a (patch) | |
tree | 42a3f1eb4a419e49badcc1ce966120f6a88a1fe1 | |
parent | e07574e1290ffc63432bc2b06a7677abc365de2d (diff) | |
parent | 0b831dcdb633365e47049c9aa5f243cce99569e5 (diff) | |
download | mediapointer-dvb-s2-1c56b8f4079af9413ea15f420259e97187a3bf7a.tar.gz mediapointer-dvb-s2-1c56b8f4079af9413ea15f420259e97187a3bf7a.tar.bz2 |
Snd_cx88_create: don't dereference NULL core
From: Duncan Sands <duncan.sands@math.u-psud.fr>
If the call to cx88_core_get returns a NULL value, it is dereferenced
by cx88_reset, and perhaps by cx88_core_put. Spotted by the Coverity
checker.
Signed-off-by: Duncan Sands <baldrick@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
91 files changed, 1583 insertions, 927 deletions
@@ -1,52 +1,53 @@ -Mauro Carvalho Chehab 2006 Jan 30 +Mauro Carvalho Chehab 2006 Mar 8 -This file describes the general procedures used by v4l-dvb maintainers. -Some of these also applies to patch submitters. +This file describes the general procedures used by v4l-dvb developers +who are responsible for maintaining V4L/DVB drivers. Some of these +also applies to patch submitters. -We've moved from cvs to a modern SCM system that fits better into +Current V4L/DVB tree uses a modern SCM system that fits better into kernel development model, called Mercurial (aka hg). -At http://selenic.com/mercurial you'll find quick-start info, a -tutorial and FAQs. +There are some tutorials, FAQs and other valuable informations at +http://selenic.com/mercurial Mercurial is a distributed SCM, which means every developer gets his own full copy of the repository (including the complete revision history), and can work and commit locally without network connection. The resulting changesets can then be exchanged between repositories and -finally published to the master repository in linuxtv.org. +finally published to the master repository in linuxtv.org. A list of +current available repositories is available at: http://linuxtv.org/hg + +The master repository with stable patches is available at: +http://linuxtv/org/hg/v4l-dvb Mercurial is organized with a master tag, called tip. This tag contains the master repository that will be used by normal users and to generate patches to kernel. -The v4l-dvb mercurial repository is meant for development. It means -that it might be broken from time to time, although all efforts should -be done to avoid this. There are more "stable" snapshots at -http://www.linuxtv.org/downloads/snapshot page. - -This file postulates some simple rules for maintaing hg tree, as stated +This file postulates some simple rules for maintaing hg trees, as stated below: 1) It is strongly recommended that each developer be active at IRC channels (irc://irc.freenode.net) #v4l (for analog) and/or #linuxtv (for digital). It helps to have more discussions at major changes; -2) Minor changes, like simple card additions (for example a new card - row at a card struct) can be applied directly by each developer; +2) Each developer may have one or more development trees, for his daily + work. It is recommended to have a tree called 'v4l-dvb' for each + developer with their stable patches. -3) Medium changes that needs modification on card coding or creating a - new card type should be discussed first at the Mailing Lists - video4linux-list@redhat.com (analog/common parts) and/or - linux-dvb@linuxtv.org to allow other contributors to discuss about - the way it will be included. +3) After the patches are ready, developer should send an email to + v4l-dvb-maintainer list asking the maintainer to pull it from developer + repository, pushing it at master. The maintainer will analyse the patch + and publish at master hg if everything looks ok. -4) Major changes that implies changing some core structs should be - widely discussed on IRC, posted to the list, created a snapshot THEN - committed to the tip branch. It is strongly recommended to use a branch - or v4l_experimental area for such changes. +4) Medium or major changes that needs modification on card coding, creating a + new card type or requiring changes at core structs should be discussed first + at the Mailing Lists video4linux-list@redhat.com (analog/common parts) + and/or linux-dvb@linuxtv.org and at IRC to allow other contributors to + discuss about the way it will be included. -5) Every CVS maintainer should follow the "rules of thumb" of kernel - development stated at Linux source code, especially: +5) Every developer should follow the "rules of thumb" of kernel development + stated at Linux source code, especially: Documentation/SubmittingPatches Documentation/SubmittingDrivers @@ -66,7 +67,7 @@ below: hg add <files> hg remove <files> hg rename <source> <dest> - hg addremove + hg addremove [<files>] *Warning* hg addremove will add/removes all files, including object files. Be careful! You can remove wrongly added files with hg remove. @@ -79,14 +80,19 @@ below: This command will preserve the changes at the files. So, a new hg commit will redo the desired commit. -9) To push the change to the *MASTER* repository you need to run: +9) To push the change to the repository you need to run: - make push + hg push <url> 10) To update from the master repository, it is needed to do: make pull + After pulling from master, if there are some changes at local repository, + hg will require to merge it. This is done by + hg update -m + make commit + 11) For hg to work properly, these vars should be defined (replacing the names at the left): @@ -185,7 +191,16 @@ below: since the macro preprocessing script used to prepare kernel upstream patches (v4l/scripts/gentree.pl) is not able to handle it. -Cheers, +18) To import contributed stuff, a script is provided at tree and allows easy + import of a mbox-based patch emails. This is done with: + ./mailimport <mbox file> + For it to work properly, git tools need to be installed at local machine, + since git have a gitimport script that is used by mailimport. + Also, hg have a feature, called mqueue, that allows having several patches + that can be applied/unapplied for testing. mailimport trusts on it to work, + so, this extension should be enabled for mailimport script to work. + +Good Work! Mauro Mauro Carvalho Chehab <mchehab .at. linuxtv .dot. org> diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 17ea5a031..421a2427f 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -86,6 +86,8 @@ 85 -> AverTV DVB-T 777 [1461:2c05] 86 -> LifeView FlyDVB-T [5168:0301] 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] - 88 -> Tevion DVB-T 220RF [17de:7201] + 88 -> Tevion/KWorld DVB-T 220RF [17de:7201] 89 -> ELSA EX-VISION 700TV [1048:226c] 90 -> Kworld ATSC110 [17de:7350] + 91 -> AVerMedia A169 B [1461:7360] + 92 -> AVerMedia A169 B1 [1461:6360] diff --git a/linux/Documentation/video4linux/CARDLIST.tuner b/linux/Documentation/video4linux/CARDLIST.tuner index 603f16537..1bcdac67d 100644 --- a/linux/Documentation/video4linux/CARDLIST.tuner +++ b/linux/Documentation/video4linux/CARDLIST.tuner @@ -64,10 +64,10 @@ tuner=62 - Philips TEA5767HN FM Radio tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner tuner=64 - LG TDVS-H062F/TUA6034 tuner=65 - Ymec TVF66T5-B/DFF -tuner=66 - LG NTSC (TALN mini series) +tuner=66 - LG TALN series tuner=67 - Philips TD1316 Hybrid Tuner tuner=68 - Philips TUV1236D ATSC/NTSC dual in -tuner=69 - Tena TNF 5335 MF +tuner=69 - Tena TNF 5335 and similar models tuner=70 - Samsung TCPN 2121P30A tuner=71 - Xceive xc3028 tuner=72 - Thomson FE6600 diff --git a/linux/Documentation/video4linux/README.cpia2 b/linux/Documentation/video4linux/README.cpia2 index f3bd3439a..ce8213d28 100644 --- a/linux/Documentation/video4linux/README.cpia2 +++ b/linux/Documentation/video4linux/README.cpia2 @@ -70,7 +70,7 @@ line like this: If the driver is compiled into the kernel, at boot time specify them like this: - cpia2=num_buffers:3,buffer_size:65535 + cpia2.num_buffers=3 cpia2.buffer_size=65535 What buffer size should I use? ------------------------------ diff --git a/v4l_experimental/pvrusb2/README b/linux/Documentation/video4linux/README.pvrusb2 index 073491307..c73a32c34 100644 --- a/v4l_experimental/pvrusb2/README +++ b/linux/Documentation/video4linux/README.pvrusb2 @@ -1,5 +1,5 @@ -$Id: README,v 1.2 2006/01/01 08:26:03 mcisely Exp $ +$Id$ Mike Isely <isely@pobox.com> pvrusb2 driver diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 71a5f1329..4233c2c2b 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -116,8 +116,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) pg = vmalloc_to_page(virt); if (NULL == pg) goto err; - if (PageHighMem(pg)) - BUG(); + BUG_ON(PageHighMem(pg)); sglist[i].page = pg; sglist[i].length = PAGE_SIZE; } diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index 480a34a26..fd9163d4b 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -38,8 +38,7 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; - if ((fh->resources & bits) != bits) - BUG(); + BUG_ON((fh->resources & bits) != bits); mutex_lock(&dev->lock); fh->resources &= ~bits; @@ -56,8 +55,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf) { DEB_EE(("dev:%p, buf:%p\n",dev,buf)); - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); videobuf_waiton(&buf->vb,0,0); videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); diff --git a/linux/drivers/media/dvb/dvb-core/demux.h b/linux/drivers/media/dvb/dvb-core/demux.h index 9f025825b..0c1d87c52 100644 --- a/linux/drivers/media/dvb/dvb-core/demux.h +++ b/linux/drivers/media/dvb/dvb-core/demux.h @@ -216,7 +216,7 @@ struct dmx_frontend { /*--------------------------------------------------------------------------*/ /* - * Flags OR'ed in the capabilites field of struct dmx_demux. + * Flags OR'ed in the capabilities field of struct dmx_demux. */ #define DMX_TS_FILTERING 1 diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index 4c52c8521..f6932d6c6 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -1,9 +1,8 @@ /* * dmxdev.c - DVB demultiplexer device * - * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> - * & Marcus Metzler <marcus@convergence.de> - for convergence integrated media GmbH + * Copyright (C) 2000 Ralph Metzler & Marcus Metzler + * for convergence integrated media GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -32,7 +31,6 @@ #include <linux/wait.h> #include <asm/uaccess.h> #include <asm/system.h> - #include "dmxdev.h" static int debug; @@ -44,15 +42,16 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) { - buffer->data=NULL; - buffer->size=8192; - buffer->pread=0; - buffer->pwrite=0; - buffer->error=0; + buffer->data = NULL; + buffer->size = 8192; + buffer->pread = 0; + buffer->pwrite = 0; + buffer->error = 0; init_waitqueue_head(&buffer->queue); } -static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len) +static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, + const u8 *src, int len) { int split; int free; @@ -63,98 +62,99 @@ static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *s if (!buf->data) return 0; - free=buf->pread-buf->pwrite; - split=0; - if (free<=0) { - free+=buf->size; - split=buf->size-buf->pwrite; + free = buf->pread - buf->pwrite; + split = 0; + if (free <= 0) { + free += buf->size; + split = buf->size - buf->pwrite; } - if (len>=free) { + if (len >= free) { dprintk("dmxdev: buffer overflow\n"); return -1; } - if (split>=len) - split=0; - todo=len; + if (split >= len) + split = 0; + todo = len; if (split) { memcpy(buf->data + buf->pwrite, src, split); - todo-=split; - buf->pwrite=0; + todo -= split; + buf->pwrite = 0; } - memcpy(buf->data + buf->pwrite, src+split, todo); - buf->pwrite=(buf->pwrite+todo)%buf->size; + memcpy(buf->data + buf->pwrite, src + split, todo); + buf->pwrite = (buf->pwrite + todo) % buf->size; return len; } static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src, - int non_blocking, char __user *buf, size_t count, loff_t *ppos) + int non_blocking, char __user *buf, + size_t count, loff_t *ppos) { - unsigned long todo=count; + unsigned long todo = count; int split, avail, error; if (!src->data) return 0; - if ((error=src->error)) { - src->pwrite=src->pread; - src->error=0; + if ((error = src->error)) { + src->pwrite = src->pread; + src->error = 0; return error; } - if (non_blocking && (src->pwrite==src->pread)) + if (non_blocking && (src->pwrite == src->pread)) return -EWOULDBLOCK; - while (todo>0) { - if (non_blocking && (src->pwrite==src->pread)) - return (count-todo) ? (count-todo) : -EWOULDBLOCK; + while (todo > 0) { + if (non_blocking && (src->pwrite == src->pread)) + return (count - todo) ? (count - todo) : -EWOULDBLOCK; if (wait_event_interruptible(src->queue, - (src->pread!=src->pwrite) || - (src->error))<0) - return count-todo; + (src->pread != src->pwrite) || + (src->error)) < 0) + return count - todo; - if ((error=src->error)) { - src->pwrite=src->pread; - src->error=0; + if ((error = src->error)) { + src->pwrite = src->pread; + src->error = 0; return error; } - split=src->size; - avail=src->pwrite - src->pread; - if (avail<0) { - avail+=src->size; - split=src->size - src->pread; + split = src->size; + avail = src->pwrite - src->pread; + if (avail < 0) { + avail += src->size; + split = src->size - src->pread; } - if (avail>todo) - avail=todo; - if (split<avail) { - if (copy_to_user(buf, src->data+src->pread, split)) - return -EFAULT; - buf+=split; - src->pread=0; - todo-=split; - avail-=split; + if (avail > todo) + avail = todo; + if (split < avail) { + if (copy_to_user(buf, src->data + src->pread, split)) + return -EFAULT; + buf += split; + src->pread = 0; + todo -= split; + avail -= split; } if (avail) { - if (copy_to_user(buf, src->data+src->pread, avail)) + if (copy_to_user(buf, src->data + src->pread, avail)) return -EFAULT; src->pread = (src->pread + avail) % src->size; - todo-=avail; - buf+=avail; + todo -= avail; + buf += avail; } } return count; } -static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type) +static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type) { struct list_head *head, *pos; - head=demux->get_frontends(demux); + head = demux->get_frontends(demux); if (!head) return NULL; list_for_each(pos, head) - if (DMX_FE_ENTRY(pos)->source==type) + if (DMX_FE_ENTRY(pos)->source == type) return DMX_FE_ENTRY(pos); return NULL; @@ -166,37 +166,37 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; - dprintk ("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __FUNCTION__); if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - if ((file->f_flags&O_ACCMODE)==O_RDWR) { - if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) { + if ((file->f_flags & O_ACCMODE) == O_RDWR) { + if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { mutex_unlock(&dmxdev->mutex); return -EOPNOTSUPP; } } - if ((file->f_flags&O_ACCMODE)==O_RDONLY) { - dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); - dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE; - dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE); - if (!dmxdev->dvr_buffer.data) { - mutex_unlock(&dmxdev->mutex); - return -ENOMEM; - } + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); + dmxdev->dvr_buffer.size = DVR_BUFFER_SIZE; + dmxdev->dvr_buffer.data = vmalloc(DVR_BUFFER_SIZE); + if (!dmxdev->dvr_buffer.data) { + mutex_unlock(&dmxdev->mutex); + return -ENOMEM; + } } - if ((file->f_flags&O_ACCMODE)==O_WRONLY) { - dmxdev->dvr_orig_fe=dmxdev->demux->frontend; + if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + dmxdev->dvr_orig_fe = dmxdev->demux->frontend; if (!dmxdev->demux->write) { mutex_unlock(&dmxdev->mutex); return -EOPNOTSUPP; } - front=get_fe(dmxdev->demux, DMX_MEMORY_FE); + front = get_fe(dmxdev->demux, DMX_MEMORY_FE); if (!front) { mutex_unlock(&dmxdev->mutex); @@ -217,17 +217,17 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - if ((file->f_flags&O_ACCMODE)==O_WRONLY) { + if ((file->f_flags & O_ACCMODE) == O_WRONLY) { dmxdev->demux->disconnect_frontend(dmxdev->demux); dmxdev->demux->connect_frontend(dmxdev->demux, dmxdev->dvr_orig_fe); } - if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (dmxdev->dvr_buffer.data) { - void *mem=dmxdev->dvr_buffer.data; + void *mem = dmxdev->dvr_buffer.data; mb(); spin_lock_irq(&dmxdev->lock); - dmxdev->dvr_buffer.data=NULL; + dmxdev->dvr_buffer.data = NULL; spin_unlock_irq(&dmxdev->lock); vfree(mem); } @@ -237,7 +237,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) } static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; @@ -245,60 +245,62 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, if (!dmxdev->demux->write) return -EOPNOTSUPP; - if ((file->f_flags&O_ACCMODE)!=O_WRONLY) + if ((file->f_flags & O_ACCMODE) != O_WRONLY) return -EINVAL; if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - ret=dmxdev->demux->write(dmxdev->demux, buf, count); + ret = dmxdev->demux->write(dmxdev->demux, buf, count); mutex_unlock(&dmxdev->mutex); return ret; } static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) + loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; int ret; //mutex_lock(&dmxdev->mutex); - ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, - file->f_flags&O_NONBLOCK, - buf, count, ppos); + ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, + file->f_flags & O_NONBLOCK, + buf, count, ppos); //mutex_unlock(&dmxdev->mutex); return ret; } -static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state) +static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter + *dmxdevfilter, int state) { spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state=state; + dmxdevfilter->state = state; spin_unlock_irq(&dmxdevfilter->dev->lock); } -static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size) +static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, + unsigned long size) { - struct dmxdev_buffer *buf=&dmxdevfilter->buffer; + struct dmxdev_buffer *buf = &dmxdevfilter->buffer; void *mem; - if (buf->size==size) + if (buf->size == size) return 0; - if (dmxdevfilter->state>=DMXDEV_STATE_GO) + if (dmxdevfilter->state >= DMXDEV_STATE_GO) return -EBUSY; spin_lock_irq(&dmxdevfilter->dev->lock); - mem=buf->data; - buf->data=NULL; - buf->size=size; - buf->pwrite=buf->pread=0; + mem = buf->data; + buf->data = NULL; + buf->size = size; + buf->pwrite = buf->pread = 0; spin_unlock_irq(&dmxdevfilter->dev->lock); vfree(mem); if (buf->size) { - mem=vmalloc(dmxdevfilter->buffer.size); + mem = vmalloc(dmxdevfilter->buffer.size); if (!mem) return -ENOMEM; spin_lock_irq(&dmxdevfilter->dev->lock); - buf->data=mem; + buf->data = mem; spin_unlock_irq(&dmxdevfilter->dev->lock); } return 0; @@ -306,31 +308,33 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsign static void dvb_dmxdev_filter_timeout(unsigned long data) { - struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data; + struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data; - dmxdevfilter->buffer.error=-ETIMEDOUT; + dmxdevfilter->buffer.error = -ETIMEDOUT; spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT; + dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT; spin_unlock_irq(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); } static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) { - struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec; + struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec; del_timer(&dmxdevfilter->timer); if (para->timeout) { - dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout; - dmxdevfilter->timer.data=(unsigned long) dmxdevfilter; - dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000; + dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout; + dmxdevfilter->timer.data = (unsigned long)dmxdevfilter; + dmxdevfilter->timer.expires = + jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000; add_timer(&dmxdevfilter->timer); } } static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter, enum dmx_success success) + const u8 *buffer2, size_t buffer2_len, + struct dmx_section_filter *filter, + enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; int ret; @@ -340,68 +344,68 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, return 0; } spin_lock(&dmxdevfilter->dev->lock); - if (dmxdevfilter->state!=DMXDEV_STATE_GO) { + if (dmxdevfilter->state != DMXDEV_STATE_GO) { spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", buffer1[0], buffer1[1], - buffer1[2], buffer1[3], - buffer1[4], buffer1[5]); - ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len); - if (ret==buffer1_len) { - ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len); + buffer1[2], buffer1[3], buffer1[4], buffer1[5]); + ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, + buffer1_len); + if (ret == buffer1_len) { + ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, + buffer2_len); } - if (ret<0) { - dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread; - dmxdevfilter->buffer.error=-EOVERFLOW; + if (ret < 0) { + dmxdevfilter->buffer.pwrite = dmxdevfilter->buffer.pread; + dmxdevfilter->buffer.error = -EOVERFLOW; } - if (dmxdevfilter->params.sec.flags&DMX_ONESHOT) - dmxdevfilter->state=DMXDEV_STATE_DONE; + if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) + dmxdevfilter->state = DMXDEV_STATE_DONE; spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed, enum dmx_success success) + const u8 *buffer2, size_t buffer2_len, + struct dmx_ts_feed *feed, + enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dmxdev_buffer *buffer; int ret; spin_lock(&dmxdevfilter->dev->lock); - if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) { + if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { spin_unlock(&dmxdevfilter->dev->lock); return 0; } - if (dmxdevfilter->params.pes.output==DMX_OUT_TAP) - buffer=&dmxdevfilter->buffer; + if (dmxdevfilter->params.pes.output == DMX_OUT_TAP) + buffer = &dmxdevfilter->buffer; else - buffer=&dmxdevfilter->dev->dvr_buffer; + buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } - ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); - if (ret==buffer1_len) - ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); - if (ret<0) { - buffer->pwrite=buffer->pread; - buffer->error=-EOVERFLOW; + ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); + if (ret == buffer1_len) + ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); + if (ret < 0) { + buffer->pwrite = buffer->pread; + buffer->error = -EOVERFLOW; } spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } - /* stop feed but only mark the specified filter as stopped (state set) */ - static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) { dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); @@ -420,20 +424,16 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) return 0; } - /* start feed associated with the specified filter */ - static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) { - dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO); + dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); switch (filter->type) { case DMXDEV_TYPE_SEC: return filter->feed.sec->start_filtering(filter->feed.sec); - break; case DMXDEV_TYPE_PES: return filter->feed.ts->start_filtering(filter->feed.ts); - break; default: return -EINVAL; } @@ -441,32 +441,31 @@ static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) return 0; } - /* restart section feed if it has filters left associated with it, otherwise release the feed */ - static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) { int i; struct dmxdev *dmxdev = filter->dev; u16 pid = filter->params.sec.pid; - for (i=0; i<dmxdev->filternum; i++) - if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && - dmxdev->filter[i].type==DMXDEV_TYPE_SEC && - dmxdev->filter[i].pid==pid) { + for (i = 0; i < dmxdev->filternum; i++) + if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && + dmxdev->filter[i].type == DMXDEV_TYPE_SEC && + dmxdev->filter[i].params.sec.pid == pid) { dvb_dmxdev_feed_start(&dmxdev->filter[i]); return 0; } - filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec); + filter->dev->demux->release_section_feed(dmxdev->demux, + filter->feed.sec); return 0; } static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) { - if (dmxdevfilter->state<DMXDEV_STATE_GO) + if (dmxdevfilter->state < DMXDEV_STATE_GO) return 0; switch (dmxdevfilter->type) { @@ -476,36 +475,35 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) dvb_dmxdev_feed_stop(dmxdevfilter); if (dmxdevfilter->filter.sec) dmxdevfilter->feed.sec-> - release_filter(dmxdevfilter->feed.sec, - dmxdevfilter->filter.sec); + release_filter(dmxdevfilter->feed.sec, + dmxdevfilter->filter.sec); dvb_dmxdev_feed_restart(dmxdevfilter); - dmxdevfilter->feed.sec=NULL; + dmxdevfilter->feed.sec = NULL; break; case DMXDEV_TYPE_PES: if (!dmxdevfilter->feed.ts) break; dvb_dmxdev_feed_stop(dmxdevfilter); dmxdevfilter->dev->demux-> - release_ts_feed(dmxdevfilter->dev->demux, - dmxdevfilter->feed.ts); - dmxdevfilter->feed.ts=NULL; + release_ts_feed(dmxdevfilter->dev->demux, + dmxdevfilter->feed.ts); + dmxdevfilter->feed.ts = NULL; break; default: - if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED) + if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED) return 0; return -EINVAL; } - dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0; + dmxdevfilter->buffer.pwrite = dmxdevfilter->buffer.pread = 0; return 0; } static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) { - if (dmxdevfilter->state<DMXDEV_STATE_SET) + if (dmxdevfilter->state < DMXDEV_STATE_SET) return 0; - dmxdevfilter->type=DMXDEV_TYPE_NONE; - dmxdevfilter->pid=0xffff; + dmxdevfilter->type = DMXDEV_TYPE_NONE; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); return 0; } @@ -525,7 +523,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) if (!(mem = filter->buffer.data)) { mem = vmalloc(filter->buffer.size); spin_lock_irq(&filter->dev->lock); - filter->buffer.data=mem; + filter->buffer.data = mem; spin_unlock_irq(&filter->dev->lock); if (!filter->buffer.data) return -ENOMEM; @@ -536,18 +534,19 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) switch (filter->type) { case DMXDEV_TYPE_SEC: { - struct dmx_sct_filter_params *para=&filter->params.sec; - struct dmx_section_filter **secfilter=&filter->filter.sec; - struct dmx_section_feed **secfeed=&filter->feed.sec; + struct dmx_sct_filter_params *para = &filter->params.sec; + struct dmx_section_filter **secfilter = &filter->filter.sec; + struct dmx_section_feed **secfeed = &filter->feed.sec; + + *secfilter = NULL; + *secfeed = NULL; - *secfilter=NULL; - *secfeed=NULL; /* find active filter/feed with same PID */ - for (i=0; i<dmxdev->filternum; i++) { + for (i = 0; i < dmxdev->filternum; i++) { if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].pid == para->pid && - dmxdev->filter[i].type == DMXDEV_TYPE_SEC) { + dmxdev->filter[i].type == DMXDEV_TYPE_SEC && + dmxdev->filter[i].params.sec.pid == para->pid) { *secfeed = dmxdev->filter[i].feed.sec; break; } @@ -555,21 +554,20 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) /* if no feed found, try to allocate new one */ if (!*secfeed) { - ret=dmxdev->demux->allocate_section_feed(dmxdev->demux, - secfeed, - dvb_dmxdev_section_callback); - if (ret<0) { - printk ("DVB (%s): could not alloc feed\n", - __FUNCTION__); + ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, + secfeed, + dvb_dmxdev_section_callback); + if (ret < 0) { + printk("DVB (%s): could not alloc feed\n", + __FUNCTION__); return ret; } - ret=(*secfeed)->set(*secfeed, para->pid, 32768, - (para->flags & DMX_CHECK_CRC) ? 1 : 0); - - if (ret<0) { - printk ("DVB (%s): could not set feed\n", - __FUNCTION__); + ret = (*secfeed)->set(*secfeed, para->pid, 32768, + (para->flags & DMX_CHECK_CRC) ? 1 : 0); + if (ret < 0) { + printk("DVB (%s): could not set feed\n", + __FUNCTION__); dvb_dmxdev_feed_restart(filter); return ret; } @@ -577,41 +575,38 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) dvb_dmxdev_feed_stop(filter); } - ret=(*secfeed)->allocate_filter(*secfeed, secfilter); - + ret = (*secfeed)->allocate_filter(*secfeed, secfilter); if (ret < 0) { dvb_dmxdev_feed_restart(filter); filter->feed.sec->start_filtering(*secfeed); - dprintk ("could not get filter\n"); + dprintk("could not get filter\n"); return ret; } (*secfilter)->priv = filter; memcpy(&((*secfilter)->filter_value[3]), - &(para->filter.filter[1]), DMX_FILTER_SIZE-1); + &(para->filter.filter[1]), DMX_FILTER_SIZE - 1); memcpy(&(*secfilter)->filter_mask[3], - ¶->filter.mask[1], DMX_FILTER_SIZE-1); + ¶->filter.mask[1], DMX_FILTER_SIZE - 1); memcpy(&(*secfilter)->filter_mode[3], - ¶->filter.mode[1], DMX_FILTER_SIZE-1); + ¶->filter.mode[1], DMX_FILTER_SIZE - 1); - (*secfilter)->filter_value[0]=para->filter.filter[0]; - (*secfilter)->filter_mask[0]=para->filter.mask[0]; - (*secfilter)->filter_mode[0]=para->filter.mode[0]; - (*secfilter)->filter_mask[1]=0; - (*secfilter)->filter_mask[2]=0; + (*secfilter)->filter_value[0] = para->filter.filter[0]; + (*secfilter)->filter_mask[0] = para->filter.mask[0]; + (*secfilter)->filter_mode[0] = para->filter.mode[0]; + (*secfilter)->filter_mask[1] = 0; + (*secfilter)->filter_mask[2] = 0; filter->todo = 0; - ret = filter->feed.sec->start_filtering (filter->feed.sec); - + ret = filter->feed.sec->start_filtering(filter->feed.sec); if (ret < 0) return ret; dvb_dmxdev_filter_timer(filter); break; } - case DMXDEV_TYPE_PES: { struct timespec timeout = { 0 }; @@ -623,41 +618,41 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) struct dmx_ts_feed **tsfeed = &filter->feed.ts; filter->feed.ts = NULL; - otype=para->output; + otype = para->output; - ts_pes=(enum dmx_ts_pes) para->pes_type; + ts_pes = (enum dmx_ts_pes)para->pes_type; - if (ts_pes<DMX_PES_OTHER) - ts_type=TS_DECODER; + if (ts_pes < DMX_PES_OTHER) + ts_type = TS_DECODER; else - ts_type=0; + ts_type = 0; if (otype == DMX_OUT_TS_TAP) ts_type |= TS_PACKET; if (otype == DMX_OUT_TAP) - ts_type |= TS_PAYLOAD_ONLY|TS_PACKET; + ts_type |= TS_PAYLOAD_ONLY | TS_PACKET; - ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux, - tsfeed, - dvb_dmxdev_ts_callback); - if (ret<0) + ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, + tsfeed, + dvb_dmxdev_ts_callback); + if (ret < 0) return ret; - (*tsfeed)->priv = (void *) filter; + (*tsfeed)->priv = filter; ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, 32768, timeout); - if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); + dmxdev->demux->release_ts_feed(dmxdev->demux, + *tsfeed); return ret; } ret = filter->feed.ts->start_filtering(filter->feed.ts); - if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); + dmxdev->demux->release_ts_feed(dmxdev->demux, + *tsfeed); return ret; } @@ -684,32 +679,31 @@ static int dvb_demux_open(struct inode *inode, struct file *file) if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; - for (i=0; i<dmxdev->filternum; i++) - if (dmxdev->filter[i].state==DMXDEV_STATE_FREE) + for (i = 0; i < dmxdev->filternum; i++) + if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) break; - if (i==dmxdev->filternum) { + if (i == dmxdev->filternum) { mutex_unlock(&dmxdev->mutex); return -EMFILE; } - dmxdevfilter=&dmxdev->filter[i]; + dmxdevfilter = &dmxdev->filter[i]; mutex_init(&dmxdevfilter->mutex); - dmxdevfilter->dvbdev=dmxdev->dvbdev; - file->private_data=dmxdevfilter; + file->private_data = dmxdevfilter; dvb_dmxdev_buffer_init(&dmxdevfilter->buffer); - dmxdevfilter->type=DMXDEV_TYPE_NONE; + dmxdevfilter->type = DMXDEV_TYPE_NONE; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); - dmxdevfilter->feed.ts=NULL; + dmxdevfilter->feed.ts = NULL; init_timer(&dmxdevfilter->timer); mutex_unlock(&dmxdev->mutex); return 0; } - -static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) +static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, + struct dmxdev_filter *dmxdevfilter) { if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -723,10 +717,10 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *d dvb_dmxdev_filter_reset(dmxdevfilter); if (dmxdevfilter->buffer.data) { - void *mem=dmxdevfilter->buffer.data; + void *mem = dmxdevfilter->buffer.data; spin_lock_irq(&dmxdev->lock); - dmxdevfilter->buffer.data=NULL; + dmxdevfilter->buffer.data = NULL; spin_unlock_irq(&dmxdev->lock); vfree(mem); } @@ -742,120 +736,120 @@ static inline void invert_mode(dmx_filter_t *filter) { int i; - for (i=0; i<DMX_FILTER_SIZE; i++) - filter->mode[i]^=0xff; + for (i = 0; i < DMX_FILTER_SIZE; i++) + filter->mode[i] ^= 0xff; } - static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_sct_filter_params *params) + struct dmxdev_filter *dmxdevfilter, + struct dmx_sct_filter_params *params) { - dprintk ("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __FUNCTION__); dvb_dmxdev_filter_stop(dmxdevfilter); - dmxdevfilter->type=DMXDEV_TYPE_SEC; - dmxdevfilter->pid=params->pid; + dmxdevfilter->type = DMXDEV_TYPE_SEC; memcpy(&dmxdevfilter->params.sec, params, sizeof(struct dmx_sct_filter_params)); invert_mode(&dmxdevfilter->params.sec.filter); dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - if (params->flags&DMX_IMMEDIATE_START) + if (params->flags & DMX_IMMEDIATE_START) return dvb_dmxdev_filter_start(dmxdevfilter); return 0; } static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_pes_filter_params *params) + struct dmxdev_filter *dmxdevfilter, + struct dmx_pes_filter_params *params) { dvb_dmxdev_filter_stop(dmxdevfilter); - if (params->pes_type>DMX_PES_OTHER || params->pes_type<0) + if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0) return -EINVAL; - dmxdevfilter->type=DMXDEV_TYPE_PES; - dmxdevfilter->pid=params->pid; - memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params)); + dmxdevfilter->type = DMXDEV_TYPE_PES; + memcpy(&dmxdevfilter->params, params, + sizeof(struct dmx_pes_filter_params)); dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - if (params->flags&DMX_IMMEDIATE_START) + if (params->flags & DMX_IMMEDIATE_START) return dvb_dmxdev_filter_start(dmxdevfilter); return 0; } static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, - struct file *file, char __user *buf, size_t count, loff_t *ppos) + struct file *file, char __user *buf, + size_t count, loff_t *ppos) { int result, hcount; - int done=0; - - if (dfil->todo<=0) { - hcount=3+dfil->todo; - if (hcount>count) - hcount=count; - result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, - buf, hcount, ppos); - if (result<0) { - dfil->todo=0; + int done = 0; + + if (dfil->todo <= 0) { + hcount = 3 + dfil->todo; + if (hcount > count) + hcount = count; + result = dvb_dmxdev_buffer_read(&dfil->buffer, + file->f_flags & O_NONBLOCK, + buf, hcount, ppos); + if (result < 0) { + dfil->todo = 0; return result; } - if (copy_from_user(dfil->secheader-dfil->todo, buf, result)) + if (copy_from_user(dfil->secheader - dfil->todo, buf, result)) return -EFAULT; - buf+=result; - done=result; - count-=result; - dfil->todo-=result; - if (dfil->todo>-3) + buf += result; + done = result; + count -= result; + dfil->todo -= result; + if (dfil->todo > -3) return done; - dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff; + dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff; if (!count) return done; } - if (count>dfil->todo) - count=dfil->todo; - result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK, - buf, count, ppos); - if (result<0) + if (count > dfil->todo) + count = dfil->todo; + result = dvb_dmxdev_buffer_read(&dfil->buffer, + file->f_flags & O_NONBLOCK, + buf, count, ppos); + if (result < 0) return result; - dfil->todo-=result; - return (result+done); + dfil->todo -= result; + return (result + done); } - static ssize_t -dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +dvb_demux_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) { - struct dmxdev_filter *dmxdevfilter= file->private_data; - int ret=0; + struct dmxdev_filter *dmxdevfilter = file->private_data; + int ret; if (mutex_lock_interruptible(&dmxdevfilter->mutex)) return -ERESTARTSYS; - if (dmxdevfilter->type==DMXDEV_TYPE_SEC) - ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); + if (dmxdevfilter->type == DMXDEV_TYPE_SEC) + ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); else - ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, - file->f_flags&O_NONBLOCK, - buf, count, ppos); + ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, + file->f_flags & O_NONBLOCK, + buf, count, ppos); mutex_unlock(&dmxdevfilter->mutex); return ret; } - static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dmxdev_filter *dmxdevfilter = file->private_data; - struct dmxdev *dmxdev=dmxdevfilter->dev; - unsigned long arg=(unsigned long) parg; - int ret=0; + struct dmxdev *dmxdev = dmxdevfilter->dev; + unsigned long arg = (unsigned long)parg; + int ret = 0; if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -866,7 +860,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdev->mutex); return -ERESTARTSYS; } - if (dmxdevfilter->state<DMXDEV_STATE_SET) + if (dmxdevfilter->state < DMXDEV_STATE_SET) ret = -EINVAL; else ret = dvb_dmxdev_filter_start(dmxdevfilter); @@ -878,7 +872,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdev->mutex); return -ERESTARTSYS; } - ret=dvb_dmxdev_filter_stop(dmxdevfilter); + ret = dvb_dmxdev_filter_stop(dmxdevfilter); mutex_unlock(&dmxdevfilter->mutex); break; @@ -887,8 +881,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdev->mutex); return -ERESTARTSYS; } - ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, - (struct dmx_sct_filter_params *)parg); + ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg); mutex_unlock(&dmxdevfilter->mutex); break; @@ -897,8 +890,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdev->mutex); return -ERESTARTSYS; } - ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, - (struct dmx_pes_filter_params *)parg); + ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg); mutex_unlock(&dmxdevfilter->mutex); break; @@ -907,7 +899,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdev->mutex); return -ERESTARTSYS; } - ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); + ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); mutex_unlock(&dmxdevfilter->mutex); break; @@ -916,10 +908,10 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, case DMX_GET_PES_PIDS: if (!dmxdev->demux->get_pes_pids) { - ret=-EINVAL; + ret = -EINVAL; break; } - dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg); + dmxdev->demux->get_pes_pids(dmxdev->demux, parg); break; case DMX_GET_CAPS: @@ -940,17 +932,18 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, case DMX_GET_STC: if (!dmxdev->demux->get_stc) { - ret=-EINVAL; + ret = -EINVAL; break; } ret = dmxdev->demux->get_stc(dmxdev->demux, - ((struct dmx_stc *)parg)->num, - &((struct dmx_stc *)parg)->stc, - &((struct dmx_stc *)parg)->base); + ((struct dmx_stc *)parg)->num, + &((struct dmx_stc *)parg)->stc, + &((struct dmx_stc *)parg)->base); break; default: - ret=-EINVAL; + ret = -EINVAL; + break; } mutex_unlock(&dmxdev->mutex); return ret; @@ -962,8 +955,7 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file, return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); } - -static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) +static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) { struct dmxdev_filter *dmxdevfilter = file->private_data; unsigned int mask = 0; @@ -987,7 +979,6 @@ static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) return mask; } - static int dvb_demux_release(struct inode *inode, struct file *file) { struct dmxdev_filter *dmxdevfilter = file->private_data; @@ -996,32 +987,28 @@ static int dvb_demux_release(struct inode *inode, struct file *file) return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); } - static struct file_operations dvb_demux_fops = { - .owner = THIS_MODULE, - .read = dvb_demux_read, - .ioctl = dvb_demux_ioctl, - .open = dvb_demux_open, - .release = dvb_demux_release, - .poll = dvb_demux_poll, + .owner = THIS_MODULE, + .read = dvb_demux_read, + .ioctl = dvb_demux_ioctl, + .open = dvb_demux_open, + .release = dvb_demux_release, + .poll = dvb_demux_poll, }; - static struct dvb_device dvbdev_demux = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_demux_fops + .priv = NULL, + .users = 1, + .writers = 1, + .fops = &dvb_demux_fops }; - static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) + unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - - int ret=0; + int ret; if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -1029,39 +1016,38 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, switch (cmd) { case DMX_SET_BUFFER_SIZE: // FIXME: implement - ret=0; + ret = 0; break; default: - ret=-EINVAL; + ret = -EINVAL; + break; } mutex_unlock(&dmxdev->mutex); return ret; } - static int dvb_dvr_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); } - -static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) +static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; unsigned int mask = 0; - dprintk ("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __FUNCTION__); poll_wait(file, &dmxdev->dvr_buffer.queue, wait); - if ((file->f_flags&O_ACCMODE) == O_RDONLY) { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (dmxdev->dvr_buffer.error) mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); - if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite) + if (dmxdev->dvr_buffer.pread != dmxdev->dvr_buffer.pwrite) mask |= (POLLIN | POLLRDNORM | POLLPRI); } else mask |= (POLLOUT | POLLWRNORM | POLLPRI); @@ -1069,61 +1055,63 @@ static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) return mask; } - static struct file_operations dvb_dvr_fops = { - .owner = THIS_MODULE, - .read = dvb_dvr_read, - .write = dvb_dvr_write, - .ioctl = dvb_dvr_ioctl, - .open = dvb_dvr_open, - .release = dvb_dvr_release, - .poll = dvb_dvr_poll, + .owner = THIS_MODULE, + .read = dvb_dvr_read, + .write = dvb_dvr_write, + .ioctl = dvb_dvr_ioctl, + .open = dvb_dvr_open, + .release = dvb_dvr_release, + .poll = dvb_dvr_poll, }; static struct dvb_device dvbdev_dvr = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_dvr_fops + .priv = NULL, + .users = 1, + .writers = 1, + .fops = &dvb_dvr_fops }; -int -dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) +int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) { int i; if (dmxdev->demux->open(dmxdev->demux) < 0) return -EUSERS; - dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter)); + dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter)); if (!dmxdev->filter) return -ENOMEM; mutex_init(&dmxdev->mutex); spin_lock_init(&dmxdev->lock); - for (i=0; i<dmxdev->filternum; i++) { - dmxdev->filter[i].dev=dmxdev; - dmxdev->filter[i].buffer.data=NULL; - dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE); + for (i = 0; i < dmxdev->filternum; i++) { + dmxdev->filter[i].dev = dmxdev; + dmxdev->filter[i].buffer.data = NULL; + dvb_dmxdev_filter_state_set(&dmxdev->filter[i], + DMXDEV_STATE_FREE); } - dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX); - dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR); + dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, + DVB_DEVICE_DEMUX); + dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, + dmxdev, DVB_DEVICE_DVR); dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); return 0; } + EXPORT_SYMBOL(dvb_dmxdev_init); -void -dvb_dmxdev_release(struct dmxdev *dmxdev) +void dvb_dmxdev_release(struct dmxdev *dmxdev) { dvb_unregister_device(dmxdev->dvbdev); dvb_unregister_device(dmxdev->dvr_dvbdev); vfree(dmxdev->filter); - dmxdev->filter=NULL; + dmxdev->filter = NULL; dmxdev->demux->close(dmxdev->demux); } + EXPORT_SYMBOL(dvb_dmxdev_release); diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.h b/linux/drivers/media/dvb/dvb-core/dmxdev.h index d1d34a71b..73da838f8 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.h +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.h @@ -40,7 +40,7 @@ #include "dvbdev.h" #include "demux.h" -enum dmxdevype { +enum dmxdev_type { DMXDEV_TYPE_NONE, DMXDEV_TYPE_SEC, DMXDEV_TYPE_PES, @@ -65,8 +65,6 @@ struct dmxdev_buffer { }; struct dmxdev_filter { - struct dvb_device *dvbdev; - union { struct dmx_section_filter *sec; } filter; @@ -81,7 +79,7 @@ struct dmxdev_filter { struct dmx_pes_filter_params pes; } params; - int type; + enum dmxdev_type type; enum dmxdev_state state; struct dmxdev *dev; struct dmxdev_buffer buffer; @@ -96,8 +94,6 @@ struct dmxdev_filter { struct timer_list timer; int todo; u8 secheader[3]; - - u16 pid; }; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 77ad2410f..f23324835 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -45,6 +45,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) rbuf->pread=rbuf->pwrite=0; rbuf->data=data; rbuf->size=len; + rbuf->error=0; init_waitqueue_head(&rbuf->queue); @@ -86,7 +87,8 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) { - rbuf->pread = rbuf->pwrite; + rbuf->pread = rbuf->pwrite = 0; + rbuf->error = 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 6d2560972..d97714e75 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -35,6 +35,7 @@ struct dvb_ringbuffer { ssize_t size; ssize_t pread; ssize_t pwrite; + int error; wait_queue_head_t queue; spinlock_t lock; diff --git a/linux/drivers/media/dvb/dvb-usb/dtt200u.c b/linux/drivers/media/dvb/dvb-usb/dtt200u.c index d2ce5d52a..b25f65238 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/linux/drivers/media/dvb/dvb-usb/dtt200u.c @@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { .cold_ids = { &dtt200u_usb_table[0], NULL }, .warm_ids = { &dtt200u_usb_table[1], NULL }, }, - { 0 }, + { NULL }, } }; @@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { .cold_ids = { &dtt200u_usb_table[2], NULL }, .warm_ids = { &dtt200u_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 4258a995d..a1705ecb9 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -47,7 +47,7 @@ static int dvb_usb_init(struct dvb_usb_device *d) d->state = DVB_USB_STATE_INIT; -/* check the capabilites and set appropriate variables */ +/* check the capabilities and set appropriate variables */ /* speed - when running at FULL speed we need a HW PID filter */ if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h index bdf596c42..b14e842d0 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -91,7 +91,7 @@ struct dvb_usb_device; /** * struct dvb_usb_properties - properties of a dvb-usb-device - * @caps: capabilites of the DVB USB device. + * @caps: capabilities of the DVB USB device. * @pid_filter_count: number of PID filter position in the optional hardware * PID-filter. * diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045.c b/linux/drivers/media/dvb/dvb-usb/vp7045.c index 16aa00ec4..20beb2539 100644 --- a/linux/drivers/media/dvb/dvb-usb/vp7045.c +++ b/linux/drivers/media/dvb/dvb-usb/vp7045.c @@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { .cold_ids = { &vp7045_usb_table[2], NULL }, .warm_ids = { &vp7045_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 56492926a..106022c39 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -1090,11 +1090,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, struct av7110 *av7110; /* pointer casting paranoia... */ - if (!demux) - BUG(); + BUG_ON(!demux); dvbdemux = (struct dvb_demux *) demux->priv; - if (!dvbdemux) - BUG(); + BUG_ON(!dvbdemux); av7110 = (struct av7110 *) dvbdemux->priv; dprintk(4, "%p\n", av7110); @@ -1441,7 +1439,7 @@ static int check_firmware(struct av7110* av7110) len = ntohl(*(u32*) ptr); ptr += 4; if (len >= 512) { - printk("dvb-ttpci: dpram file is way to big.\n"); + printk("dvb-ttpci: dpram file is way too big.\n"); return -EINVAL; } if (crc != crc32_le(0, ptr, len)) { diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 245db934f..69a550871 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -696,8 +696,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) memcpy(ttusb->muxpack + ttusb->muxpack_ptr, data, avail); ttusb->muxpack_ptr += avail; - if (ttusb->muxpack_ptr > 264) - BUG(); + BUG_ON(ttusb->muxpack_ptr > 264); data += avail; len -= avail; /* determine length */ diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index f6889f771..7fb2e7ca5 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -324,6 +324,8 @@ source "drivers/media/video/cx88/Kconfig" source "drivers/media/video/em28xx/Kconfig" +source "drivers/media/video/pvrusb2/Kconfig" + config VIDEO_OVCAMCHIP tristate "OmniVision Camera Chip support" depends on VIDEO_DEV && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 87b1ce6e2..02bd94f0f 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -45,6 +45,8 @@ obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ obj-$(CONFIG_VIDEO_CX88) += cx88/ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o +obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ +obj-$(CONFIG_VIDEO_PVRUSB2) += msp3400.o obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ diff --git a/linux/drivers/media/video/bttv-cards.c b/linux/drivers/media/video/bttv-cards.c index b46f1118b..47131de0d 100644 --- a/linux/drivers/media/video/bttv-cards.c +++ b/linux/drivers/media/video/bttv-cards.c @@ -161,6 +161,8 @@ MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a li MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); MODULE_PARM_DESC(tuner,"specify installed tuner type"); MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); +MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" + " [some VIA/SIS chipsets are known to have problem with overlay]"); /* ----------------------------------------------------------------------- */ /* list of card IDs for bt878+ cards */ @@ -5044,12 +5046,14 @@ void __devinit bttv_check_chipset(void) if (vsfx) printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); if (pcipci_fail) { - printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); + printk(KERN_INFO "bttv: bttv and your chipset may not work " + "together.\n"); if (!no_overlay) { - printk(KERN_WARNING "bttv: overlay will be disabled.\n"); + printk(KERN_INFO "bttv: overlay will be disabled.\n"); no_overlay = 1; } else { - printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n"); + printk(KERN_INFO "bttv: overlay forced. Use this " + "option at your own risk.\n"); } } if (UNSET != latency) diff --git a/linux/drivers/media/video/bttv-risc.c b/linux/drivers/media/video/bttv-risc.c index 4efe74dd8..148e86a79 100644 --- a/linux/drivers/media/video/bttv-risc.c +++ b/linux/drivers/media/video/bttv-risc.c @@ -277,6 +277,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, if (line > maxy) btcx_calc_skips(line, ov->w.width, &maxy, skips, &nskips, ov->clips, ov->nclips); + else + nskips = 0; /* write out risc code */ for (start = 0, skip = 0; start < ov->w.width; start = end) { @@ -514,8 +516,7 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf) { - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); videobuf_waiton(&buf->vb,0,0); videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); diff --git a/linux/drivers/media/video/compat_ioctl32.c b/linux/drivers/media/video/compat_ioctl32.c index 9e9e9304b..8323dcf30 100644 --- a/linux/drivers/media/video/compat_ioctl32.c +++ b/linux/drivers/media/video/compat_ioctl32.c @@ -169,29 +169,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user if (kp->clipcount > 2048) return -EINVAL; if (kp->clipcount) { - struct v4l2_clip32 *uclips = compat_ptr(up->clips); - struct v4l2_clip *kclips; + struct v4l2_clip32 __user *uclips; + struct v4l2_clip __user *kclips; int n = kp->clipcount; + compat_caddr_t p; + if (get_user(p, &up->clips)) + return -EFAULT; + uclips = compat_ptr(p); kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); kp->clips = kclips; while (--n >= 0) { - if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) || - copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c))) + if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) + return -EFAULT; + if (put_user(n ? kclips + 1 : NULL, &kclips->next)) return -EFAULT; - kclips->next = n ? kclips + 1 : 0; uclips += 1; kclips += 1; } } else - kp->clips = 0; + kp->clips = NULL; return 0; } static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) || - copy_to_user(&up->w, &kp->w, sizeof(up->w)) || + if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || put_user(kp->field, &up->field) || put_user(kp->chromakey, &up->chromakey) || put_user(kp->clipcount, &up->clipcount)) @@ -201,33 +204,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) || - copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) + return -EFAULT; return 0; } static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) || - copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) + return -EFAULT; return 0; } static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) || - copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) + return -EFAULT; return 0; } static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) || - copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) + return -EFAULT; return 0; } @@ -281,18 +280,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) || - copy_from_user(kp, up, sizeof(struct v4l2_standard))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) + return -EFAULT; return 0; } static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) || - copy_to_user(up, kp, sizeof(struct v4l2_standard))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) + return -EFAULT; return 0; } @@ -330,18 +327,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) || - copy_from_user(kp, up, sizeof(struct v4l2_tuner))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) + return -EFAULT; return 0; } static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) || - copy_to_user(up, kp, sizeof(struct v4l2_tuner))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) + return -EFAULT; return 0; } @@ -382,11 +377,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user break; case V4L2_MEMORY_USERPTR: { - unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); + compat_long_t tmp; - if(get_user(kp->length, &up->length) || - get_user(kp->m.userptr, &tmp)) - return -EFAULT; + if (get_user(kp->length, &up->length) || + get_user(tmp, &up->m.userptr)) + return -EFAULT; + + kp->m.userptr = (unsigned long)compat_ptr(tmp); } break; case V4L2_MEMORY_OVERLAY: @@ -470,33 +467,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) || - copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) + return -EFAULT; return 0; } static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) || - copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) + return -EFAULT; return 0; } static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) || - copy_from_user(kp, up, sizeof(struct v4l2_input))) - return -EFAULT; + if (copy_from_user(kp, up, sizeof(struct v4l2_input))) + return -EFAULT; return 0; } static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) || - copy_to_user(up, kp, sizeof(struct v4l2_input))) - return -EFAULT; + if (copy_to_user(up, kp, sizeof(struct v4l2_input))) + return -EFAULT; return 0; } diff --git a/linux/drivers/media/video/cpia2/cpia2_v4l.c b/linux/drivers/media/video/cpia2/cpia2_v4l.c index c38681283..2ab1582fd 100644 --- a/linux/drivers/media/video/cpia2/cpia2_v4l.c +++ b/linux/drivers/media/video/cpia2/cpia2_v4l.c @@ -1629,7 +1629,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file, } switch (ioctl_nr) { - case VIDIOCGCAP: /* query capabilites */ + case VIDIOCGCAP: /* query capabilities */ retval = ioctl_cap_query(arg, cam); break; @@ -2054,7 +2054,7 @@ static void __init check_parameters(void) * cpia2_init/module_init * *****************************************************************************/ -int __init cpia2_init(void) +static int __init cpia2_init(void) { LOG("%s v%d.%d.%d\n", ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER); @@ -2069,37 +2069,12 @@ int __init cpia2_init(void) * cpia2_exit/module_exit * *****************************************************************************/ -void __exit cpia2_exit(void) +static void __exit cpia2_exit(void) { cpia2_usb_cleanup(); schedule_timeout(2 * HZ); } - -int __init cpia2_setup(char *str) -{ - while(str) { - if(!strncmp(str, "buffer_size:", 12)) { - buffer_size = simple_strtoul(str + 13, &str, 10); - } else if(!strncmp(str, "num_buffers:", 12)) { - num_buffers = simple_strtoul(str + 13, &str, 10); - } else if(!strncmp(str, "alternate:", 10)) { - alternate = simple_strtoul(str + 11, &str, 10); - } else if(!strncmp(str, "video_nr:", 9)) { - video_nr = simple_strtoul(str + 10, &str, 10); - } else if(!strncmp(str, "flicker_freq:",13)) { - flicker_freq = simple_strtoul(str + 14, &str, 10); - } else if(!strncmp(str, "flicker_mode:",13)) { - flicker_mode = simple_strtoul(str + 14, &str, 10); - } else { - ++str; - } - } - return 1; -} - -__setup("cpia2=", cpia2_setup); - module_init(cpia2_init); module_exit(cpia2_exit); diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index e5b9007c2..e6cc40e04 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -686,6 +686,11 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, chip = (snd_cx88_card_t *) card->private_data; core = cx88_core_get(pci); + if (NULL == core) { + err = -EINVAL; + kfree (chip); + return err; + } if (!pci_dma_supported(pci,0xffffffff)) { dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); @@ -702,11 +707,6 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, spin_lock_init(&chip->reg_lock); cx88_reset(core); - if (NULL == core) { - err = -EINVAL; - kfree (chip); - return err; - } chip->core = core; /* get irq */ diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index c9c76003e..73b7ed14f 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -186,17 +186,18 @@ struct cx88_board cx88_boards[] = { .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio1 = 0x309f, + .gpio1 = 0xe09f, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio1 = 0x305f, + .gpio1 = 0xe05f, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio1 = 0x305f, + .gpio1 = 0xe05f, }}, .radio = { + .gpio1 = 0xe0df, .type = CX88_RADIO, }, }, @@ -324,19 +325,19 @@ struct cx88_board cx88_boards[] = { .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0xff00, + .gpio0 = 0xbff0, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0xff03, + .gpio0 = 0xbff3, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0xff03, + .gpio0 = 0xbff3, }}, .radio = { .type = CX88_RADIO, - .gpio0 = 0xff00, + .gpio0 = 0xbff0, }, }, [CX88_BOARD_ASUS_PVR_416] = { diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index 24acfa2bd..e8bf7cf7c 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -232,8 +232,7 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, void cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) { - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); videobuf_waiton(&buf->vb,0,0); videobuf_dma_pci_unmap(pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index 94b9ab35f..11d2e625a 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -188,6 +188,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 5; /* ms */ break; + case CX88_BOARD_PROLINK_PLAYTVPVR: case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: ir_codes = ir_codes_pixelview; ir->gpio_addr = MO_GP1_IO; diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index a40d1bcd0..7d811004d 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -162,10 +162,43 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, struct cx88_buffer *buf; struct list_head *item; - dprintk( 0, "cx8802_restart_queue\n" ); + dprintk( 1, "cx8802_restart_queue\n" ); if (list_empty(&q->active)) { - dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); + struct cx88_buffer *prev; + prev = NULL; + + dprintk(1, "cx8802_restart_queue: queue is empty\n" ); + + for (;;) { + if (list_empty(&q->queued)) + return 0; + buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); + if (NULL == prev) { + list_del(&buf->vb.queue); + list_add_tail(&buf->vb.queue,&q->active); + cx8802_start_dma(dev, q, buf); + buf->vb.state = STATE_ACTIVE; + buf->count = q->count++; + mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); + dprintk(1,"[%p/%d] restart_queue - first active\n", + buf,buf->vb.i); + + } else if (prev->vb.width == buf->vb.width && + prev->vb.height == buf->vb.height && + prev->fmt == buf->fmt) { + list_del(&buf->vb.queue); + list_add_tail(&buf->vb.queue,&q->active); + buf->vb.state = STATE_ACTIVE; + buf->count = q->count++; + prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); + dprintk(1,"[%p/%d] restart_queue - move to active\n", + buf,buf->vb.i); + } else { + return 0; + } + prev = buf; + } return 0; } diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index edd32f7c1..4484744bc 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -253,7 +253,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0x00, .maximum = 0xff, .step = 1, - .default_value = 0, + .default_value = 0x7f, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 128, @@ -281,7 +281,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0xff, .step = 1, - .default_value = 0, + .default_value = 0x7f, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 128, @@ -326,7 +326,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0x3f, .step = 1, - .default_value = 0x1f, + .default_value = 0x3f, .type = V4L2_CTRL_TYPE_INTEGER, }, .reg = AUD_VOL_CTL, @@ -392,8 +392,7 @@ static void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) { struct cx88_core *core = dev->core; - if ((fh->resources & bits) != bits) - BUG(); + BUG_ON((fh->resources & bits) != bits); mutex_lock(&core->lock); fh->resources &= ~bits; @@ -1160,7 +1159,8 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: - ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f)); + ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40) + : (0x7f - (value & 0x7f)); break; case V4L2_CID_AUDIO_VOLUME: ctl->value = 0x3f - (value & 0x3f); @@ -1205,7 +1205,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) mask=c->mask; switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: - value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; + value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40); break; case V4L2_CID_AUDIO_VOLUME: value = 0x3f - (ctl->value & 0x3f); @@ -1246,8 +1246,7 @@ static void init_controls(struct cx88_core *core) for (i = 0; i < CX8800_CTLS; i++) { ctrl.id=cx8800_ctls[i].v.id; - ctrl.value=cx8800_ctls[i].v.default_value - +cx8800_ctls[i].off; + ctrl.value=cx8800_ctls[i].v.default_value; set_control(core, &ctrl); } } diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 27a8bfdd6..a03be58aa 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -69,7 +69,7 @@ /* need "shadow" registers for some write-only ones ... */ #define SHADOW_AUD_VOL_CTL 1 #define SHADOW_AUD_BAL_CTL 2 -#define SHADOW_MAX 2 +#define SHADOW_MAX 3 /* FM Radio deemphasis type */ enum cx88_deemph_type { diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index 387f76c9f..dd8dc256d 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -160,7 +160,7 @@ const char *msp_standard_std_name(int std) return "unknown"; } -void msp_set_source(struct i2c_client *client, u16 src) +static void msp_set_source(struct i2c_client *client, u16 src) { struct msp_state *state = i2c_get_clientdata(client); @@ -223,7 +223,7 @@ void msp3400c_set_mode(struct i2c_client *client, int mode) /* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP, nor do they support stereo BTSC. */ -void msp3400c_set_audmode(struct i2c_client *client) +static void msp3400c_set_audmode(struct i2c_client *client) { static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; struct msp_state *state = i2c_get_clientdata(client); @@ -989,7 +989,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) status, is_stereo, is_bilingual, state->rxsubchans); } -void msp34xxg_set_audmode(struct i2c_client *client) +static void msp34xxg_set_audmode(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); int source; diff --git a/linux/drivers/media/video/msp3400.h b/linux/drivers/media/video/msp3400.h index 80e26e68f..5bb277609 100644 --- a/linux/drivers/media/video/msp3400.h +++ b/linux/drivers/media/video/msp3400.h @@ -109,7 +109,6 @@ int msp_sleep(struct msp_state *state, int timeout); /* msp3400-kthreads.c */ const char *msp_standard_std_name(int std); -void msp_set_source(struct i2c_client *client, u16 src); void msp_set_audmode(struct i2c_client *client); void msp_detect_stereo(struct i2c_client *client); int msp3400c_thread(void *data); diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig new file mode 100644 index 000000000..93b182c54 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/Kconfig @@ -0,0 +1,13 @@ +config VIDEO_PVRUSB2 + tristate "Hauppauge WinTV-PVR USB2 support" + depends on VIDEO_DEV && USB && I2C && EXPERIMENTAL + select FW_LOADER + select VIDEO_TUNER + select VIDEO_TVEEPROM + select VIDEO_DECODER + ---help--- + This is a video4linux driver for Conexant 23416 based + usb2 personal video recorder devices. + + To compile this driver as a module, choose M here: the + module will be called pvrusb2 diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile new file mode 100644 index 000000000..c83742fb1 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/Makefile @@ -0,0 +1,11 @@ +pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ + pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ + pvrusb2-encoder.o pvrusb2-video-v4l.o \ + pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \ + pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ + pvrusb2-sysfs.o pvrusb2-context.o pvrusb2-io.o \ + pvrusb2-ioread.o pvrusb2-debugifc.o + +obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o + +EXTRA_CFLAGS += -I$(src)/.. diff --git a/v4l_experimental/pvrusb2/pvrusb2-audio.c b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c index 067a686e0..7e2fab330 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-audio.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-audio.c,v 1.9 2006/01/23 07:00:31 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -155,7 +155,7 @@ static int msp3400_check(struct pvr2_msp3400_handler *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); + for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); idx++) { msk = 1 << idx; if (ctxt->stale_mask & msk) continue; @@ -172,7 +172,7 @@ static void msp3400_update(struct pvr2_msp3400_handler *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); + for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); idx++) { msk = 1 << idx; if (!(ctxt->stale_mask & msk)) continue; diff --git a/v4l_experimental/pvrusb2/pvrusb2-audio.h b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.h index 0a278927e..536339b68 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-audio.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-audio.h,v 1.2 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2-context.c b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c index 1f8b400a0..0f0e14d01 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-context.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c @@ -1,5 +1,5 @@ /* - * $Id: pvrusb2-context.c,v 1.3 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -74,7 +74,9 @@ static void pvr2_context_setup(struct pvr2_context *mp) struct pvr2_context *pvr2_context_create( - struct usb_interface *intf,void (*setup_func)(struct pvr2_context *)) + struct usb_interface *intf, + const struct usb_device_id *devid, + void (*setup_func)(struct pvr2_context *)) { struct pvr2_context *mp = 0; mp = kmalloc(sizeof(*mp),GFP_KERNEL); @@ -83,7 +85,7 @@ struct pvr2_context *pvr2_context_create( pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); mp->setup_func = setup_func; mutex_init(&mp->mutex); - mp->hdw = pvr2_hdw_create(intf); + mp->hdw = pvr2_hdw_create(intf,devid); if (!mp->hdw) { pvr2_context_destroy(mp); mp = 0; @@ -183,7 +185,7 @@ void pvr2_channel_done(struct pvr2_channel *cp) int pvr2_channel_claim_stream(struct pvr2_channel *cp, - struct pvr2_context_stream *sp) + struct pvr2_context_stream *sp) { int code = 0; pvr2_context_enter(cp->mc_head); do { diff --git a/v4l_experimental/pvrusb2/pvrusb2-context.h b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h index 229a8ef0e..873622a0f 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-context.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h @@ -1,5 +1,5 @@ /* - * $Id: pvrusb2-context.h,v 1.3 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -77,6 +77,7 @@ void pvr2_context_enter(struct pvr2_context *); void pvr2_context_exit(struct pvr2_context *); struct pvr2_context *pvr2_context_create(struct usb_interface *intf, + const struct usb_device_id *devid, void (*setup_func)(struct pvr2_context *)); void pvr2_context_disconnect(struct pvr2_context *); diff --git a/v4l_experimental/pvrusb2/pvrusb2-debug.h b/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h index 70a143736..d95a8588e 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-debug.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h @@ -1,5 +1,5 @@ /* - * $Id: pvrusb2-debug.h,v 1.5 2006/01/14 22:09:52 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -22,7 +22,7 @@ extern int pvrusb2_debug; -#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2 " fmt "\n", ##arg); } while (0) +#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0) /* These are listed in *rough* order of decreasing usefulness and increasing noise level. */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-debugifc.c b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index f56b96f56..bcfe468eb 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-debugifc.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-debugifc.c,v 1.2 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -41,7 +41,7 @@ static struct debugifc_mask_item mask_items[] = { static unsigned int debugifc_count_whitespace(const char *buf, - unsigned int count) + unsigned int count) { unsigned int scnt; char ch; @@ -58,7 +58,7 @@ static unsigned int debugifc_count_whitespace(const char *buf, static unsigned int debugifc_count_nonwhitespace(const char *buf, - unsigned int count) + unsigned int count) { unsigned int scnt; char ch; @@ -74,8 +74,8 @@ static unsigned int debugifc_count_nonwhitespace(const char *buf, static unsigned int debugifc_isolate_word(const char *buf,unsigned int count, - const char **wstrPtr, - unsigned int *wlenPtr) + const char **wstrPtr, + unsigned int *wlenPtr) { const char *wptr; unsigned int consume_cnt = 0; @@ -102,7 +102,7 @@ static unsigned int debugifc_isolate_word(const char *buf,unsigned int count, static int debugifc_parse_unsigned_number(const char *buf,unsigned int count, - u32 *num_ptr) + u32 *num_ptr) { u32 result = 0; u32 val; @@ -138,7 +138,7 @@ static int debugifc_parse_unsigned_number(const char *buf,unsigned int count, static int debugifc_match_keyword(const char *buf,unsigned int count, - const char *keyword) + const char *keyword) { unsigned int kl; if (!keyword) return 0; @@ -163,7 +163,7 @@ static unsigned long debugifc_find_mask(const char *buf,unsigned int count) static int debugifc_print_mask(char *buf,unsigned int sz, - unsigned long msk,unsigned long val) + unsigned long msk,unsigned long val) { struct debugifc_mask_item *mip; unsigned int idx; @@ -184,9 +184,9 @@ static int debugifc_print_mask(char *buf,unsigned int sz, } static unsigned int debugifc_parse_subsys_mask(const char *buf, - unsigned int count, - unsigned long *mskPtr, - unsigned long *valPtr) + unsigned int count, + unsigned long *mskPtr, + unsigned long *valPtr) { const char *wptr; unsigned int consume_cnt = 0; @@ -286,7 +286,7 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, - char *buf,unsigned int acnt) + char *buf,unsigned int acnt) { int bcnt = 0; int ccnt; @@ -338,7 +338,7 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) + unsigned int count) { const char *wptr; unsigned int wlen; @@ -444,7 +444,7 @@ int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) + unsigned int count) { unsigned int bcnt = 0; int ret; diff --git a/v4l_experimental/pvrusb2/pvrusb2-debugifc.h b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.h index 59f4373d6..990b02d35 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-debugifc.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-debugifc.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-demod.c b/linux/drivers/media/video/pvrusb2/pvrusb2-demod.c index f7545b773..dca787dfa 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-demod.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-demod.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-demod.c,v 1.5 2006/01/22 03:48:34 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2-demod.h b/linux/drivers/media/video/pvrusb2/pvrusb2-demod.h index 0067872ea..4c4e40ffb 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-demod.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-demod.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-demod.h,v 1.1 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-eeprom.c b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c index 9df9fd3eb..60ee45ca2 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-eeprom.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-eeprom.c,v 1.5 2006/01/14 19:09:50 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -86,21 +86,22 @@ */ -#define PVR_EEPROM_I2C_ADDR 0x50 - #include <media/tveeprom.h> -/* We seem to only be interested in the back half of the EEPROM */ +/* We seem to only be interested in the last 128 bytes of the EEPROM */ #define EEPROM_SIZE 128 -#define EEPROM_OFFS 128 /* Grab EEPROM contents, needed for direct method. */ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) { struct i2c_msg msg[2]; u8 *eeprom; - u8 offs; + u8 iadd[2]; + u8 addr; + u16 eepromSize; + unsigned int offs; int ret; + int mode16 = 0; unsigned pcnt,tcnt; eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); if (!eeprom) { @@ -110,11 +111,28 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) return 0; } - msg[0].addr = PVR_EEPROM_I2C_ADDR; + trace_eeprom("Value for eeprom addr from controller was 0x%x", + hdw->eeprom_addr); + addr = hdw->eeprom_addr; + /* Seems that if the high bit is set, then the *real* eeprom + address is shifted right now bit position (noticed this in + newer PVR USB2 hardware) */ + if (addr & 0x80) addr >>= 1; + + /* FX2 documentation states that a 16bit-addressed eeprom is + expected if the I2C address is an odd number (yeah, this is + strange bit it's what they do) */ + mode16 = (addr & 1); + eepromSize = (mode16 ? 4096 : 256); + trace_eeprom("Examining %d byte eeprom at location 0x%x" + " using %d bit addressing",eepromSize,addr, + mode16 ? 16 : 8); + + msg[0].addr = addr; msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &offs; - msg[1].addr = PVR_EEPROM_I2C_ADDR; + msg[0].len = mode16 ? 2 : 1; + msg[0].buf = iadd; + msg[1].addr = hdw->eeprom_addr; msg[1].flags = I2C_M_RD; /* We have to do the actual eeprom data fetch ourselves, because @@ -125,7 +143,13 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { pcnt = 16; if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + EEPROM_OFFS; + offs = tcnt + (eepromSize - EEPROM_SIZE); + if (mode16) { + iadd[0] = offs >> 8; + iadd[1] = offs; + } else { + iadd[0] = offs; + } msg[1].len = pcnt; msg[1].buf = eeprom+tcnt; if ((ret = i2c_transfer( @@ -163,7 +187,7 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) { struct i2c_client fake_client; /* Newer version expects a useless client interface */ - fake_client.addr = PVR_EEPROM_I2C_ADDR; + fake_client.addr = hdw->eeprom_addr; fake_client.adapter = &hdw->i2c_adap; tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); } diff --git a/v4l_experimental/pvrusb2/pvrusb2-eeprom.h b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h index edc80b62e..061cecd91 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-eeprom.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-eeprom.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 046cd9f1f..97931d3c4 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-encoder.c,v 1.5 2006/01/14 20:11:08 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -147,7 +147,7 @@ static int pvr2_read_encoder_words(struct pvr2_hdw *hdw,int statusFl, static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd, - int args, ...) + int args, ...) { unsigned int poll_count; int ret = 0; @@ -308,14 +308,14 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) the ivtv driver). But, if I leave them in, then mplayer goes nuts with xrun errors. So for now we don't do this. It sure would be nice to know what these are for. */ -#ifdef notdef +#if 0 ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 5); ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 2, 3, 1); ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 8); #endif /* Strange compared to ivtv data. */ -#ifdef notdef +#if 0 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0x0120, 0x0120); ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, diff --git a/v4l_experimental/pvrusb2/pvrusb2-encoder.h b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.h index 4a35e8ac0..01b5a0b89 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-encoder.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-encoder.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index c4b1cbdcd..1b161773b 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw-internal.h,v 1.6 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -93,6 +93,10 @@ struct pvr2_decoder_ctrl { #define FW1_STATE_RELOAD 3 #define FW1_STATE_OK 4 +/* Known major hardware variants, keyed from device ID */ +#define PVR2_HDW_TYPE_29XXX 0 +#define PVR2_HDW_TYPE_24XXX 1 + /* This structure contains all state data directly needed to manipulate the hardware (as opposed to complying with a kernel interface) */ @@ -101,6 +105,9 @@ struct pvr2_hdw { struct usb_device *usb_dev; struct usb_interface *usb_intf; + /* Device type, one of PVR2_HDW_TYPE_xxxxx */ + unsigned int hdw_type; + /* Video spigot */ struct pvr2_stream *vid_stream; @@ -176,6 +183,10 @@ struct pvr2_hdw { // Which subsystems are manipulated to enable streaming unsigned long subsys_stream_mask; + // True if there is a request to trigger logging of state in each + // module. + int log_requested; + /* Tuner / frequency control stuff */ unsigned int tuner_type; int tuner_updated; @@ -188,6 +199,9 @@ struct pvr2_hdw { be no v4l junk here). Probably a better way to do this. */ int v4l_minor_number; + /* Location of eeprom or a negative number if none */ + int eeprom_addr; + enum pvr2_config config; /* Information about what audio signal we're hearing */ @@ -200,7 +214,7 @@ struct pvr2_hdw { }; int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw, - unsigned int ctl_id,int value); + unsigned int ctl_id,int value); int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 20206cff9..b87651e5a 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw.c,v 1.13 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -35,6 +35,19 @@ #include "pvrusb2-encoder.h" #include "pvrusb2-debug.h" +struct usb_device_id pvr2_device_table[] = { + [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, + [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, + { } +}; + +MODULE_DEVICE_TABLE(usb, pvr2_device_table); + +static const char *pvr2_device_names[] = { + [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx", + [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx", +}; + static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; DECLARE_MUTEX(pvr2_unit_sem); @@ -43,14 +56,17 @@ static int initusbreset = 1; static int procreload = 0; static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; +static int init_pause_msec = 0; module_param(ctlchg, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); +module_param(init_pause_msec, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay"); module_param(initusbreset, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe"); module_param(procreload, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(procreload, - "Attempt init failure recovery with firmware reload"); + "Attempt init failure recovery with firmware reload"); module_param_array(tuner, int, NULL, 0444); MODULE_PARM_DESC(tuner,"specify installed tuner type"); module_param_array(tolerance, int, NULL, 0444); @@ -70,10 +86,6 @@ MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); /* size of a firmware chunk */ #define FIRMWARE_CHUNK_SIZE 0x2000 -/* Various files we will load with firmware_entry */ -#define FIRMWARE1_FILE "pvrusb2.f1" -#define FIRMWARE2_FILE "pvrusb2.f2" - typedef int (*pvr2_ctl_set_func)(struct pvr2_hdw *,int ctl_id,int val); typedef int (*pvr2_ctl_get_func)(struct pvr2_hdw *,int ctl_id); @@ -169,7 +181,7 @@ static int pvr2_ctl_get_subsys_mask(struct pvr2_hdw *hdw,int ctl_id); static int pvr2_ctl_set_subsys_mask(struct pvr2_hdw *hdw,int ctl_id,int val); static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id); static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id, - int val); + int val); static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = { @@ -296,7 +308,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = [PVR2_CID_FREQUENCY] = { .name = "Tuner Frequency (Hz)", .min_value = 55250000L, - .max_value = 801250000L, + .max_value = 850000000L, .default_value = 175250000L, }, [PVR2_CID_HRES] = { @@ -338,7 +350,7 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] = [PVR2_CID_CHANPROG_FREQ] = { .name = "Channel Program Frequency", .min_value = 55250000L, - .max_value = 801250000L, + .max_value = 850000000L, .skip_init = !0, .set_func = pvr2_ctl_set_chanprog_id, .get_func = pvr2_ctl_get_chanprog_id, @@ -421,6 +433,63 @@ int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) } +/* Attempt to locate one of the given set of files. Messages are logged + appropriate to what has been found. The return value will be 0 or + greater on success (it will be the index of the file name found) and + fw_entry will be filled in. Otherwise a negative error is returned on + failure. If the return value is -ENOENT then no viable firmware file + could be located. */ +static int pvr2_locate_firmware(struct pvr2_hdw *hdw, + const struct firmware **fw_entry, + const char *fwtypename, + unsigned int fwcount, + const char *fwnames[]) +{ + unsigned int idx; + int ret = -EINVAL; + for (idx = 0; idx < fwcount; idx++) { + ret = request_firmware(fw_entry, + fwnames[idx], + &hdw->usb_dev->dev); + if (!ret) { + trace_firmware("Located %s firmware: %s;" + " uploading...", + fwtypename, + fwnames[idx]); + return idx; + } + if (ret == -ENOENT) continue; + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "request_firmware fatal error with code=%d",ret); + return ret; + } + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "***WARNING***" + " Device %s firmware" + " seems to be missing.", + fwtypename); + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Did you install the pvrusb2 firmware files" + " in their proper location?"); + if (fwcount == 1) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "request_firmware unable to locate %s file %s", + fwtypename,fwnames[0]); + } else { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "request_firmware unable to locate" + " one of the following %s files:", + fwtypename); + for (idx = 0; idx < fwcount; idx++) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "request_firmware: Failed to find %s", + fwnames[idx]); + } + } + return ret; +} + + /* * pvr2_upload_firmware1(). * @@ -438,27 +507,41 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw) unsigned int pipe; int ret; u16 address; - const char *firmware_file = FIRMWARE1_FILE; - + static const char *fw_files_29xxx[] = { + "v4l-pvrusb2-29xxx-01.fw", + }; + static const char *fw_files_24xxx[] = { + "v4l-pvrusb2-24xxx-01.fw", + }; + static const struct { + const char **lst; + unsigned int cnt; + } fw_file_defs[] = { + [PVR2_HDW_TYPE_29XXX] = { + fw_files_29xxx, + sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), + }, + [PVR2_HDW_TYPE_24XXX] = { + fw_files_24xxx, + sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), + }, + }; hdw->fw1_state = FW1_STATE_FAILED; // default result trace_firmware("pvr2_upload_firmware1"); + ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", + fw_file_defs[hdw->hdw_type].cnt, + fw_file_defs[hdw->hdw_type].lst); + if (ret < 0) { + if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; + return ret; + } + usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - ret = request_firmware(&fw_entry, firmware_file, &hdw->usb_dev->dev); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware failed for '%s' code=%d", - firmware_file,ret); - if (ret == -ENOENT) { - hdw->fw1_state = FW1_STATE_MISSING; - } - return ret; - } if (fw_entry->size != 0x2000){ pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); @@ -519,9 +602,20 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) unsigned int pipe, fw_len, fw_done; int actual_length; int ret = 0; + int fwidx; + static const char *fw_files[] = { + "v4l-cx2341x-enc.fw", + }; trace_firmware("pvr2_upload_firmware2"); + ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", + sizeof(fw_files)/sizeof(fw_files[0]), + fw_files); + if (ret < 0) return ret; + fwidx = ret; + ret = 0; + /* First prepare firmware loading */ ret |= pvr2_hdw_cmd_soft_reset(hdw); ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ @@ -546,34 +640,19 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) if (ret) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "firmware2 upload prep failed, ret=%d",ret); + release_firmware(fw_entry); return ret; } /* Now send firmware */ - ret = request_firmware(&fw_entry, FIRMWARE2_FILE, &hdw->usb_dev->dev); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware failed for '%s'", FIRMWARE2_FILE); - if (ret == -ENOENT) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device encoder firmware" - " seems to be missing."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware files" - " in their proper location?"); - } - return ret; - } - fw_len = fw_entry->size; if (fw_len % FIRMWARE_CHUNK_SIZE) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "size of %s must be a multiple of 8192B", - FIRMWARE2_FILE); + "size of %s firmware" + " must be a multiple of 8192B", + fw_files[fwidx]); release_firmware(fw_entry); return -1; } @@ -603,7 +682,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) } trace_firmware("upload of %s : %i / %i ", - FIRMWARE2_FILE,fw_done,fw_len); + fw_files[fwidx],fw_done,fw_len); kfree(fw_ptr); release_firmware(fw_entry); @@ -842,8 +921,8 @@ unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw) void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) + unsigned long msk, + unsigned long val) { unsigned long val2; msk &= PVR2_SUBSYS_ALL; @@ -856,8 +935,8 @@ void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) + unsigned long msk, + unsigned long val) { LOCK_TAKE(hdw->big_lock); do { pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val); @@ -906,7 +985,7 @@ int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw, - enum pvr2_config config) + enum pvr2_config config) { unsigned long sm = hdw->subsys_enabled_mask; if (!hdw->flag_ok) return -EIO; @@ -952,10 +1031,55 @@ static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) } +static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) +{ + /* Try a harmless request to fetch the eeprom's address over + endpoint 1. See what happens. Only the full FX2 image can + respond to this. If this probe fails then likely the FX2 + firmware needs be loaded. */ + int result; + LOCK_TAKE(hdw->ctl_lock); do { + hdw->cmd_buffer[0] = 0xeb; + result = pvr2_send_request_ex(hdw,HZ*1,!0, + hdw->cmd_buffer,1, + hdw->cmd_buffer,1); + if (result < 0) break; + } while(0); LOCK_GIVE(hdw->ctl_lock); + if (result) { + pvr2_trace(PVR2_TRACE_INIT, + "Probe of device endpoint 1 result status %d", + result); + } else { + pvr2_trace(PVR2_TRACE_INIT, + "Probe of device endpoint 1 succeeded"); + } + return result == 0; +} + + static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) { + int ret; unsigned int idx; - if (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints == 0) { + int reloadFl = 0; + if (!reloadFl) { + reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints + == 0); + if (reloadFl) { + pvr2_trace(PVR2_TRACE_INIT, + "USB endpoint config looks strange" + "; possibly firmware needs to be loaded"); + } + } + if (!reloadFl) { + reloadFl = !pvr2_hdw_check_firmware(hdw); + if (reloadFl) { + pvr2_trace(PVR2_TRACE_INIT, + "Check for FX2 firmware failed" + "; possibly firmware needs to be loaded"); + } + } + if (reloadFl) { if (pvr2_upload_firmware1(hdw) != 0) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failure uploading firmware1"); @@ -987,8 +1111,16 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) pvr2_reset_ctl_endpoints(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_eeprom_analyze(hdw); + ret = pvr2_hdw_get_eeprom_addr(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; + if (ret < 0) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Unable to determine location of eeprom, skipping"); + } else { + hdw->eeprom_addr = ret; + pvr2_eeprom_analyze(hdw); + if (!pvr2_hdw_dev_ok(hdw)) return; + } if (!get_default_tuner_type(hdw)) { pvr2_trace(PVR2_TRACE_INIT, @@ -1059,21 +1191,17 @@ int pvr2_hdw_setup(struct pvr2_hdw *hdw) " and reconnect."); break; } + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "Device initialization was not successful."); if (hdw->fw1_state == FW1_STATE_MISSING) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device microcontroller firmware" - " seems to be missing."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware" - " files in their proper location?"); + "Giving up since device" + " microcontroller firmware" + " appears to be missing."); break; } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Device initialization was not successful."); } if (procreload) { pvr2_trace( @@ -1099,22 +1227,37 @@ int pvr2_hdw_setup(struct pvr2_hdw *hdw) " in order to recover."); } } while (0); LOCK_GIVE(hdw->big_lock); + pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); return hdw->flag_init_ok; } /* Create and return a structure for interacting with the underlying hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf) +struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, + const struct usb_device_id *devid) { unsigned int idx,cnt1,cnt2; struct pvr2_hdw *hdw; + unsigned int hdw_type; __u8 ifnum; + hdw_type = devid - pvr2_device_table; + if (hdw_type >= + sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Bogus device type of %u reported",hdw_type); + return 0; + } + hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p",hdw); + pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", + hdw,pvr2_device_names[hdw_type]); if (!hdw) goto fail; memset(hdw,0,sizeof(*hdw)); + hdw->hdw_type = hdw_type; + + hdw->eeprom_addr = -1; hdw->unit_number = -1; hdw->v4l_minor_number = -1; hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); @@ -1342,7 +1485,7 @@ int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id) /* Set current value for given control - normally this is just stored and the hardware isn't updated until the commit function is called. */ int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw, - unsigned int ctl_id,int value) + unsigned int ctl_id,int value) { if (ctl_id >= PVR2_CID_COUNT) return -EINVAL; if (value < control_defs[ctl_id].min_value) return -EINVAL; @@ -1377,8 +1520,8 @@ int pvr2_hdw_set_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id,int value) /* Retrieve string name for a given control value (returns a null pointer for any invalid combinations). */ const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *hdw, - unsigned int ctl_id, - int value) + unsigned int ctl_id, + int value) { struct pvr2_ctl_def *cdef; if (ctl_id >= PVR2_CID_COUNT) return 0; @@ -1641,7 +1784,7 @@ static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id) static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id, - int val) + int val) { pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,~0,val); return 0; @@ -1697,6 +1840,16 @@ struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) } +void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) +{ + LOCK_TAKE(hdw->big_lock); do { + hdw->log_requested = !0; + pvr2_i2c_core_check_stale(hdw); + hdw->log_requested = 0; + pvr2_i2c_core_sync(hdw); + } while (0); LOCK_GIVE(hdw->big_lock); +} + void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) { int ret; @@ -1757,7 +1910,7 @@ int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, - char *buf,unsigned int cnt) + char *buf,unsigned int cnt) { int ret = -EINVAL; LOCK_TAKE(hdw->big_lock); do { @@ -1853,31 +2006,33 @@ static void pvr2_ctl_timeout(unsigned long data) } -int pvr2_send_request(struct pvr2_hdw *hdw, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) +int pvr2_send_request_ex(struct pvr2_hdw *hdw, + unsigned int timeout,int probe_fl, + void *write_data,unsigned int write_len, + void *read_data,unsigned int read_len) { unsigned int idx; - int status; + int status = 0; struct timer_list timer; if (!hdw->ctl_lock_held) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Attempted to execute control transfer" " without lock!!"); - status = -EINVAL; - goto done; + return -EDEADLK; } - if (!hdw->flag_ok) { + if ((!hdw->flag_ok) && !probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Attempted to execute control transfer" " when device not ok"); return -EIO; } if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when USB is disconnected"); - return -EIO; + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Attempted to execute control transfer" + " when USB is disconnected"); + } + return -ENOTTY; } /* Ensure that we have sane parameters */ @@ -1921,7 +2076,7 @@ int pvr2_send_request(struct pvr2_hdw *hdw, hdw->ctl_write_pend_flag = 0; hdw->ctl_read_pend_flag = 0; init_timer(&timer); - timer.expires = jiffies + HZ*4; + timer.expires = jiffies + timeout; timer.data = (unsigned long)hdw; timer.function = pvr2_ctl_timeout; @@ -1952,6 +2107,7 @@ int pvr2_send_request(struct pvr2_hdw *hdw, "Failed to submit write-control" " URB status=%d",status); hdw->ctl_write_pend_flag = 0; + goto done; } } @@ -1978,6 +2134,7 @@ int pvr2_send_request(struct pvr2_hdw *hdw, "Failed to submit read-control" " URB status=%d",status); hdw->ctl_read_pend_flag = 0; + goto done; } } @@ -1999,6 +2156,10 @@ int pvr2_send_request(struct pvr2_hdw *hdw, if (hdw->ctl_timeout_flag) { status = -ETIMEDOUT; + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Timed out control-write"); + } goto done; } @@ -2011,19 +2172,24 @@ int pvr2_send_request(struct pvr2_hdw *hdw, /* USB subsystem is reporting some kind of failure on the write */ status = hdw->ctl_write_urb->status; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB failure, status=%d", - status); + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "control-write URB failure," + " status=%d", + status); + } goto done; } if (hdw->ctl_write_urb->actual_length < write_len) { /* Failed to write enough data */ status = -EIO; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB short," - " expected=%d got=%d", - write_len, - hdw->ctl_write_urb->actual_length); + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "control-write URB short," + " expected=%d got=%d", + write_len, + hdw->ctl_write_urb->actual_length); + } goto done; } } @@ -2036,18 +2202,24 @@ int pvr2_send_request(struct pvr2_hdw *hdw, /* USB subsystem is reporting some kind of failure on the read */ status = hdw->ctl_read_urb->status; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB failure, status=%d", - status); + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "control-read URB failure," + " status=%d", + status); + } goto done; } if (hdw->ctl_read_urb->actual_length < read_len) { /* Failed to read enough data */ status = -EIO; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB short," - " expected=%d got=%d", - read_len,hdw->ctl_read_urb->actual_length); + if (!probe_fl) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "control-read URB short," + " expected=%d got=%d", + read_len, + hdw->ctl_read_urb->actual_length); + } goto done; } /* Transfer retrieved data out from internal buffer */ @@ -2059,13 +2231,22 @@ int pvr2_send_request(struct pvr2_hdw *hdw, done: hdw->cmd_debug_state = 0; - if (status < 0) { + if ((status < 0) && (!probe_fl)) { pvr2_hdw_render_useless_unlocked(hdw); } return status; } +int pvr2_send_request(struct pvr2_hdw *hdw, + void *write_data,unsigned int write_len, + void *read_data,unsigned int read_len) +{ + return pvr2_send_request_ex(hdw,HZ*4,0, + write_data,write_len, + read_data,read_len); +} + int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) { int ret; @@ -2177,6 +2358,13 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to lock USB device ret=%d",ret); } + if (init_pause_msec) { + pvr2_trace(PVR2_TRACE_INFO, + "Waiting %u msec for hardware to settle", + init_pause_msec); + msleep(init_pause_msec); + } + } @@ -2247,7 +2435,7 @@ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *ptr) + struct pvr2_hdw_debug_info *ptr) { ptr->big_lock_held = hdw->big_lock_held; ptr->ctl_lock_held = hdw->ctl_lock_held; @@ -2327,6 +2515,21 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) } +int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) +{ + int result; + LOCK_TAKE(hdw->ctl_lock); do { + hdw->cmd_buffer[0] = 0xeb; + result = pvr2_send_request(hdw, + hdw->cmd_buffer,1, + hdw->cmd_buffer,1); + if (result < 0) break; + result = hdw->cmd_buffer[0]; + } while(0); LOCK_GIVE(hdw->ctl_lock); + return result; +} + + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index d813d07d4..667c95a27 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw.h,v 1.6 2006/01/14 21:11:17 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -145,7 +145,7 @@ #define PVR2_SUBSYS_ENC_RUN (1 << 4) #define PVR2_SUBSYS_CFG_ALL ( \ - PVR2_SUBSYS_ENC_FIRMWARE | \ + PVR2_SUBSYS_ENC_FIRMWARE | \ PVR2_SUBSYS_ENC_CFG ) #define PVR2_SUBSYS_RUN_ALL ( \ PVR2_SUBSYS_DIGITIZER_RUN | \ @@ -168,7 +168,8 @@ struct pvr2_hdw; /* Create and return a structure for interacting with the underlying hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf); +struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, + const struct usb_device_id *devid); /* Poll for background activity (if any) */ void pvr2_hdw_poll(struct pvr2_hdw *); @@ -235,7 +236,7 @@ const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *,unsigned int ctl_id); /* Retrieve string name for a given control value (returns a null pointer for any invalid combinations). */ const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *, - unsigned int ctl_id,int value); + unsigned int ctl_id,int value); /* Commit all control changes made up to this point */ int pvr2_hdw_commit_ctl(struct pvr2_hdw *); @@ -269,7 +270,7 @@ struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); identified by bit positions within msk, and new state for each item is identified by corresponding bit positions within val. */ void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); + unsigned long msk,unsigned long val); /* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */ void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk); @@ -284,7 +285,7 @@ unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *); /* Adjust mask of what get shut down when streaming is stopped. This is a debugging aid. */ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); + unsigned long msk,unsigned long val); /* Retrieve mask indicating which pieces of hardware are disabled when streaming is turned off. */ @@ -304,7 +305,7 @@ int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); value is the number of bytes retrieved or zero if we're past the end or an error otherwise (e.g. if firmware retrieval is not enabled). */ int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs, - char *buf,unsigned int cnt); + char *buf,unsigned int cnt); /* Retrieve previously stored v4l minor device number */ int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *); @@ -322,8 +323,17 @@ void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw); /* Issue a command and get a response from the device. LOTS of higher level stuff is built on this. */ -int pvr2_send_request(struct pvr2_hdw *, void *, unsigned int, - void *, unsigned int); +int pvr2_send_request(struct pvr2_hdw *, + void *write_ptr,unsigned int write_len, + void *read_ptr,unsigned int read_len); + +/* Issue a command and get a response from the device. This extended + version includes a probe flag (which if set means that device errors + should not be logged or treated as fatal) and a timeout in jiffies. + This can be used to non-lethally probe the health of endpoint 1. */ +int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl, + void *write_ptr,unsigned int write_len, + void *read_ptr,unsigned int read_len); /* Slightly higher level device communication functions. */ int pvr2_write_register(struct pvr2_hdw *, u16, u32); @@ -353,6 +363,9 @@ int pvr2_hdw_cmd_soft_reset(struct pvr2_hdw *); /* Stop / start video stream transport */ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); +/* Find I2C address of eeprom */ +int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *); + /* Direct manipulation of GPIO bits */ int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *); int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *); @@ -385,13 +398,18 @@ struct pvr2_hdw_debug_info { kind of locking and so it is not atomic and may yield inconsistent results. This is *purely* a debugging aid. */ void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *); + struct pvr2_hdw_debug_info *); + +/* Cause modules to log their state once */ +void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); /* Cause encoder firmware to be uploaded into the device. This is normally done autonomously, but the interface is exported here because it is also a debugging aid. */ int pvr2_upload_firmware2(struct pvr2_hdw *hdw); +/* List of device types that we can match */ +extern struct usb_device_id pvr2_device_table[]; #endif /* __PVRUSB2_HDW_H */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index ff8d38063..2d97653d5 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c-chips-v4l2.c,v 1.3 2006/01/22 03:55:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -37,6 +37,7 @@ #define OP_FREQ 3 #define OP_AUDIORATE 4 #define OP_SIZE 5 +#define OP_LOG 6 static const struct pvr2_i2c_op * const ops[] = { [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, @@ -44,6 +45,7 @@ static const struct pvr2_i2c_op * const ops[] = { [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, [OP_SIZE] = &pvr2_i2c_op_v4l2_size, + [OP_LOG] = &pvr2_i2c_op_v4l2_log, }; void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) @@ -54,7 +56,8 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) (1 << OP_BCSH) | (1 << OP_VOLUME) | (1 << OP_FREQ) | - (1 << OP_SIZE)); + (1 << OP_SIZE) | + (1 << OP_LOG)); if (id == I2C_DRIVERID_MSP3400) { if (pvr2_i2c_msp3400_setup(hdw,cp)) { diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c index 92f2dfa6a..69864782b 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c-cmd-v4l2.c,v 1.1 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -218,6 +218,27 @@ const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { }; +static void do_log(struct pvr2_hdw *hdw) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); + pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,0); + +} + + +static int check_log(struct pvr2_hdw *hdw) +{ + return hdw->log_requested != 0; +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { + .check = check_log, + .update = do_log, + .name = "v4l2_log", +}; + + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h index 8c3945e93..fa0a3af7e 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c-cmd-v4l2.h,v 1.1 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -31,6 +31,7 @@ extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; #endif /* __PVRUSB2_CMD_V4L2_H */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index b45463a2d..8ec637e5e 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c-core.c,v 1.5 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -39,19 +39,26 @@ module_param(i2c_scan, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 length) /* Size of data to write */ + u8 i2c_addr, /* I2C address we're talking to */ + u8 *data, /* Data to write */ + u16 length) /* Size of data to write */ { /* Return value - default 0 means success */ int ret; -#ifdef notdef +#if 0 trace_i2c("pvr2_i2c_write"); #endif if (!data) length = 0; - if (length > (sizeof(hdw->cmd_buffer) - 3)) return -ENOTSUPP; + if (length > (sizeof(hdw->cmd_buffer) - 3)) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Killing an I2C write to %u that is too large" + " (desired=%u limit=%u)", + i2c_addr, + length,(sizeof(hdw->cmd_buffer) - 3)); + return -ENOTSUPP; + } LOCK_TAKE(hdw->ctl_lock); @@ -80,7 +87,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ } } } -#ifdef notdef +#if 0 trace_i2c("i2c_write(%d) len=%d ret=%d stat=%d",i2c_addr,length,ret, hdw->cmd_buffer[0]); #endif @@ -91,16 +98,16 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ } static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 dlen, /* Size of data to write */ - u8 *res, /* Where to put data we read */ - u16 rlen) /* Amount of data to read */ + u8 i2c_addr, /* I2C address we're talking to */ + u8 *data, /* Data to write */ + u16 dlen, /* Size of data to write */ + u8 *res, /* Where to put data we read */ + u16 rlen) /* Amount of data to read */ { /* Return value - default 0 means success */ int ret; -#ifdef notdef +#if 0 trace_i2c("pvr2_i2c_read"); #endif @@ -138,7 +145,7 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ } } -#ifdef notdef +#if 0 trace_i2c("i2c_read(%d) wlen=%d rlen=%d ret=%d stat=%d", i2c_addr,dlen,rlen,ret,hdw->cmd_buffer[0]); #endif @@ -160,8 +167,8 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ /* This is a very, very limited I2C adapter implementation. We can only support what we actually know will work on the device... */ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], - int num) + struct i2c_msg msgs[], + int num) { int ret = -ENOTSUPP; struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data); @@ -282,14 +289,14 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, } static int pvr2_i2c_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return 0; } static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } static int pvr2_i2c_core_singleton(struct i2c_client *cp, @@ -692,7 +699,7 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client) static struct i2c_algorithm pvr2_i2c_algo_template = { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - .id = I2C_ALGO_BIT | I2C_HW_B_BT848, + .id = I2C_HW_B_BT848, #endif .master_xfer = pvr2_i2c_xfer, .algo_control = pvr2_i2c_control, @@ -702,11 +709,7 @@ static struct i2c_algorithm pvr2_i2c_algo_template = { static struct i2c_adapter pvr2_i2c_adap_template = { .owner = THIS_MODULE, .class = I2C_CLASS_TV_ANALOG, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) - .id = I2C_ALGO_BIT | I2C_HW_B_BT848, -#else .id = I2C_HW_B_BT848, -#endif .client_register = pvr2_i2c_attach_inform, .client_unregister = pvr2_i2c_detach_inform, }; diff --git a/v4l_experimental/pvrusb2/pvrusb2-i2c-core.h b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h index 3e8f71962..e8af5b0ed 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-i2c-core.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-i2c-core.h,v 1.1 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-io.c b/linux/drivers/media/video/pvrusb2/pvrusb2-io.c index d53c63785..a6bc3befe 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-io.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-io.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-io.c,v 1.3 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -36,7 +36,7 @@ // #define SANITY_CHECK_BUFFERS -#ifdef notdef +#if 0 #define BUFFER_CHECK(bp) do { \ if ((bp)->signature != BUFFER_SIG) { \ pvr2_trace(PVR2_TRACE_ERROR_LEGS, \ @@ -44,7 +44,7 @@ (bp),__FILE__,__LINE__); \ pvr2_buffer_describe(bp,"BadSig"); \ BUG(); \ - } \ + } \ } while (0) #endif @@ -56,7 +56,7 @@ (bp),__FILE__,__LINE__); \ pvr2_buffer_describe(bp,"BadSig"); \ BUG(); \ - } \ + } \ } while (0) #else #define BUFFER_CHECK(bp) do {} while(0) @@ -278,8 +278,8 @@ static void pvr2_buffer_wipe(struct pvr2_buffer *bp) } static int pvr2_buffer_init(struct pvr2_buffer *bp, - struct pvr2_stream *sp, - unsigned int id) + struct pvr2_stream *sp, + unsigned int id) { memset(bp,0,sizeof(*bp)); bp->signature = BUFFER_SIG; @@ -508,8 +508,8 @@ void pvr2_stream_destroy(struct pvr2_stream *sp) } void pvr2_stream_setup(struct pvr2_stream *sp, - struct usb_device *dev, - int endpoint, + struct usb_device *dev, + int endpoint, unsigned int tolerance) { mutex_lock(&sp->mutex); do { @@ -521,8 +521,8 @@ void pvr2_stream_setup(struct pvr2_stream *sp, } void pvr2_stream_set_callback(struct pvr2_stream *sp, - pvr2_stream_callback func, - void *data) + pvr2_stream_callback func, + void *data) { unsigned long irq_flags; mutex_lock(&sp->mutex); do { diff --git a/v4l_experimental/pvrusb2/pvrusb2-io.h b/linux/drivers/media/video/pvrusb2/pvrusb2-io.h index 5dc72b1ef..65e11385b 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-io.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-io.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-io.h,v 1.2 2006/01/09 06:54:46 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -42,11 +42,11 @@ const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); struct pvr2_stream *pvr2_stream_create(void); void pvr2_stream_destroy(struct pvr2_stream *); void pvr2_stream_setup(struct pvr2_stream *, - struct usb_device *dev,int endpoint, + struct usb_device *dev,int endpoint, unsigned int tolerance); void pvr2_stream_set_callback(struct pvr2_stream *, - pvr2_stream_callback func, - void *data); + pvr2_stream_callback func, + void *data); /* Query / set the nominal buffer count */ int pvr2_stream_get_buffer_count(struct pvr2_stream *); diff --git a/v4l_experimental/pvrusb2/pvrusb2-ioread.c b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c index 375dd8acb..4182d75b7 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-ioread.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-ioread.c,v 1.2 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-ioread.h b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.h index ec2a23325..e6205f123 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-ioread.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-ioread.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c index 72b5132e6..c554671af 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-main.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-main.c,v 1.7 2006/01/22 03:51:19 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -62,11 +62,6 @@ MODULE_PARM_DESC(debug, "Debug trace mask"); static struct pvr2_sysfs_class *class_ptr = 0; -static struct usb_device_id pvr_table[] = { - { USB_DEVICE(0x2040, 0x2900) }, - { } -}; - static void pvr_setup_attach(struct pvr2_context *pvr) { /* Create association with v4l layer */ @@ -80,7 +75,7 @@ static int pvr_probe(struct usb_interface *intf, struct pvr2_context *pvr; /* Create underlying hardware interface */ - pvr = pvr2_context_create(intf,pvr_setup_attach); + pvr = pvr2_context_create(intf,devid,pvr_setup_attach); if (!pvr) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to create hdw handler"); @@ -116,7 +111,7 @@ static struct usb_driver pvr_driver = { owner: THIS_MODULE, #endif name: "pvrusb2", - id_table: pvr_table, + id_table: pvr2_device_table, probe: pvr_probe, disconnect: pvr_disconnect }; @@ -166,7 +161,11 @@ static void __exit pvr_exit(void) module_init(pvr_init); module_exit(pvr_exit); -MODULE_DEVICE_TABLE (usb, pvr_table); +/* Mike Isely <mcisely@pobox.com> 11-Mar-2006: See pvrusb2-hdw.c for + MODULE_DEVICE_TABLE(). We have to declare that attribute there + because that's where the device table actually is now and it seems + that certain gcc configurations get angry if MODULE_DEVICE_TABLE() + is used on what ends up being an external symbol. */ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/v4l_experimental/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 7d17ee749..a9710b52c 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-sysfs.c,v 1.2 2006/01/22 03:51:19 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -196,7 +196,7 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf) } static int store_val_any(int id,struct pvr2_sysfs *sfp, - const char *buf,unsigned int count) + const char *buf,unsigned int count) { int val,minval,maxval; int ch,ret; @@ -293,7 +293,7 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp, } static int store_val_multi(int id,struct pvr2_sysfs *sfp, - const char *buf,unsigned int count) + const char *buf,unsigned int count) { unsigned int count2; int ret; @@ -311,7 +311,7 @@ static int store_val_multi(int id,struct pvr2_sysfs *sfp, } static ssize_t store_val_int(int id,struct class_device *class_dev, - const char *buf,size_t count) + const char *buf,size_t count) { struct pvr2_sysfs *sfp; int ret; @@ -322,7 +322,7 @@ static ssize_t store_val_int(int id,struct class_device *class_dev, } static ssize_t store_val_enum(int id,struct class_device *class_dev, - const char *buf,size_t count) + const char *buf,size_t count) { struct pvr2_sysfs *sfp; int ret; @@ -646,7 +646,7 @@ static ssize_t unit_number_show(struct class_device *class_dev,char *buf) static void class_dev_create(struct pvr2_sysfs *sfp, - struct pvr2_sysfs_class *class_ptr) + struct pvr2_sysfs_class *class_ptr) { struct usb_device *usb_dev; struct class_device *class_dev; @@ -707,7 +707,7 @@ static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, - struct pvr2_sysfs_class *class_ptr) + struct pvr2_sysfs_class *class_ptr) { struct pvr2_sysfs *sfp; sfp = kmalloc(sizeof(*sfp),GFP_KERNEL); @@ -723,7 +723,7 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp, - int numenvp,char *buf,int size) + int numenvp,char *buf,int size) { /* Even though we don't do anything here, we still need this function because sysfs will still try to call it. */ @@ -766,6 +766,7 @@ static ssize_t debuginfo_show(struct class_device *class_dev,char *buf) struct pvr2_sysfs *sfp; sfp = (struct pvr2_sysfs *)class_dev->class_data; if (!sfp) return -EINVAL; + pvr2_hdw_trigger_module_log(sfp->channel.hdw); return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); } @@ -780,7 +781,7 @@ static ssize_t debugcmd_show(struct class_device *class_dev,char *buf) static ssize_t debugcmd_store(struct class_device *class_dev, - const char *buf,size_t count) + const char *buf,size_t count) { struct pvr2_sysfs *sfp; int ret; diff --git a/v4l_experimental/pvrusb2/pvrusb2-sysfs.h b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.h index 20dcc3256..ff9373b47 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-sysfs.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-sysfs.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -32,7 +32,7 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, - struct pvr2_sysfs_class *); + struct pvr2_sysfs_class *); #endif /* __PVRUSB2_SYSFS_H */ diff --git a/v4l_experimental/pvrusb2/pvrusb2-tuner.c b/linux/drivers/media/video/pvrusb2/pvrusb2-tuner.c index 4a6f99177..f829c0acc 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-tuner.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-tuner.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-tuner.c,v 1.12 2006/01/22 03:48:34 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2-tuner.h b/linux/drivers/media/video/pvrusb2/pvrusb2-tuner.h index 83d92d06d..556f12aa9 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-tuner.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-tuner.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-tuner.h,v 1.2 2006/01/01 08:26:03 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-util.h b/linux/drivers/media/video/pvrusb2/pvrusb2-util.h index e8c2cc940..e53aee416 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-util.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-util.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-util.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -23,18 +23,18 @@ #define PVR2_DECOMPOSE_LE(t,i,d) \ do { \ - (t)[i] = (d) & 0xff;\ - (t)[i+1] = ((d) >> 8) & 0xff;\ - (t)[i+2] = ((d) >> 16) & 0xff;\ - (t)[i+3] = ((d) >> 24) & 0xff;\ + (t)[i] = (d) & 0xff;\ + (t)[i+1] = ((d) >> 8) & 0xff;\ + (t)[i+2] = ((d) >> 16) & 0xff;\ + (t)[i+3] = ((d) >> 24) & 0xff;\ } while(0) #define PVR2_DECOMPOSE_BE(t,i,d) \ do { \ - (t)[i+3] = (d) & 0xff;\ - (t)[i+2] = ((d) >> 8) & 0xff;\ - (t)[i+1] = ((d) >> 16) & 0xff;\ - (t)[i] = ((d) >> 24) & 0xff;\ + (t)[i+3] = (d) & 0xff;\ + (t)[i+2] = ((d) >> 8) & 0xff;\ + (t)[i+1] = ((d) >> 16) & 0xff;\ + (t)[i] = ((d) >> 24) & 0xff;\ } while(0) #define PVR2_COMPOSE_LE(t,i) \ diff --git a/v4l_experimental/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 0a78a6646..017d30ad0 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-v4l2.c,v 1.9 2006/01/23 06:58:06 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -124,7 +124,7 @@ static struct v4l2_tuner pvr_v4l2_tuners[]= { .afc = 0, .reserved = {0,0,0,0} } -#ifdef notdef +#if 0 { .index = 1, .name = "Radio Tuner", @@ -306,7 +306,7 @@ static int cnv_cid_v4l2_pvr2(int id) return -1; } -#ifdef notdef +#if 0 static int cnv_cid_pvr2_v4l2(int id) { switch (id) { @@ -342,7 +342,7 @@ static int cnv_cid_pvr2_v4l2(int id) * */ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) + unsigned int cmd, void *arg) { struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_v4l2 *vp = fh->vhead; @@ -839,6 +839,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, break; } + case VIDIOC_LOG_STATUS: + { + pvr2_hdw_trigger_module_log(hdw); + break; + } + default : ret = v4l_compat_translate_ioctl(inode,file,cmd, arg,pvr2_v4l2_do_ioctl); @@ -871,8 +877,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) { pvr2_trace(PVR2_TRACE_INIT, - "Unregistering v4l video device (%s, minor=%d)", - pvr2_config_get_name(dip->config),dip->vdev->minor); + "unregistering device video%d [%s]", + dip->vdev->minor,pvr2_config_get_name(dip->config)); video_unregister_device(dip->vdev); } @@ -899,7 +905,7 @@ void pvr2_v4l2_internal_check(struct pvr2_channel *chp) int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { /* Temporary hack : use ivtv api until a v4l2 one is available. */ @@ -1047,7 +1053,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) static ssize_t pvr2_v4l2_read(struct file *file, - char __user *buff, size_t count, loff_t *ppos) + char __user *buff, size_t count, loff_t *ppos) { struct pvr2_v4l2_fh *fh = file->private_data; int ret; @@ -1159,10 +1165,10 @@ static struct video_device vdev_template = { static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, - struct pvr2_v4l2 *vp, - enum pvr2_config cfg) + struct pvr2_v4l2 *vp, + enum pvr2_config cfg) { -#ifdef notdef +#if 0 struct usb_device *usbdev; #endif int mindevnum; @@ -1171,7 +1177,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, dip->v4lp = vp; dip->config = cfg; -#ifdef notdef +#if 0 usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw); #endif @@ -1206,7 +1212,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, } memcpy(dip->vdev,&vdev_template,sizeof(vdev_template)); -#ifdef notdef +#if 0 /* ????? This relation may be problematic on a disconnect. Is this really needed? I can't seem to find a reason for it. This can't be a required thing - what if the video device being set @@ -1226,8 +1232,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, err("Failed to register pvrusb2 v4l video device"); } else { pvr2_trace(PVR2_TRACE_INIT, - "Registered pvrusb2 v4l device, minor=%d", - dip->vdev->minor); + "registered device video%d [%s]", + dip->vdev->minor,pvr2_config_get_name(dip->config)); } pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, dip->vdev->minor); diff --git a/v4l_experimental/pvrusb2/pvrusb2-v4l2.h b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.h index 9dd446469..9a995e2d2 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-v4l2.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-v4l2.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * diff --git a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.c b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index f4948a7a7..d0bc3682b 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-video-v4l.c,v 1.10 2006/01/22 03:48:34 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -131,7 +131,7 @@ static int decoder_check(struct pvr2_v4l_decoder *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); + for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); idx++) { msk = 1 << idx; if (ctxt->stale_mask & msk) continue; @@ -148,7 +148,7 @@ static void decoder_update(struct pvr2_v4l_decoder *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); + for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); idx++) { msk = 1 << idx; if (!(ctxt->stale_mask & msk)) continue; diff --git a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.h b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h index b47e64791..1c0c98efb 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-video-v4l.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-video-v4l.h,v 1.3 2006/01/14 19:09:50 mcisely Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/v4l_experimental/pvrusb2/pvrusb2.h b/linux/drivers/media/video/pvrusb2/pvrusb2.h index f4e99ad3b..074533e9c 100644 --- a/v4l_experimental/pvrusb2/pvrusb2.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index 5f1f32ecb..8a174f185 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -320,8 +320,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) static int dsp_buffer_free(struct saa7134_dev *dev) { - if (!dev->dmasound.blksize) - BUG(); + BUG_ON(!dev->dmasound.blksize); videobuf_dma_free(&dev->dmasound.dma); diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index fb804441d..b2249665b 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -2030,7 +2030,7 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_FLYTV_DIGIMATRIX] = { .name = "FlyTV mini Asus Digimatrix", .audio_clock = 0x00200000, - .tuner_type = TUNER_LG_NTSC_TALN_MINI, + .tuner_type = TUNER_LG_TALN, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2708,7 +2708,7 @@ struct saa7134_board saa7134_boards[] = { }}, }, [SAA7134_BOARD_TEVION_DVBT_220RF] = { - .name = "Tevion DVB-T 220RF", + .name = "Tevion/KWorld DVB-T 220RF", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_TDA8290, .radio_type = UNSET, @@ -2758,6 +2758,86 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE2, }}, }, + [SAA7134_BOARD_AVERMEDIA_A169_B] = { + /* AVerMedia A169 */ + /* Rickard Osser <ricky@osser.se> */ + /* This card has two saa7134 chips on it, + but only one of them is currently working. */ + .name = "AVerMedia A169 B", + .audio_clock = 0x02187de7, + .tuner_type = TUNER_LG_TALN, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0x0a60000, +#if 0 + .inputs = {{ + .name = name_tv, + .vmux = 4, + .amux = TV, + .tv = 1, + .gpio = 0x00a68300, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_comp2, /* Composite SVIDEO (B/W if signal is carried with SVIDEO) */ + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 9, /* 9 is correct as S-VIDEO according to a169.inf! */ + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0x00a68300, + }, +#endif + }, + [SAA7134_BOARD_AVERMEDIA_A169_B1] = { + /* AVerMedia A169 */ + /* Rickard Osser <ricky@osser.se> */ + .name = "AVerMedia A169 B1", + .audio_clock = 0x02187de7, + .tuner_type = TUNER_LG_TALN, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0xca60000, + .inputs = {{ + .name = name_tv, + .vmux = 4, + .amux = TV, + .tv = 1, + .gpio = 0x04a61000, +#if 0 + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, +#endif + },{ + .name = name_comp2, /* Composite SVIDEO (B/W if signal is carried with SVIDEO) */ + .vmux = 1, + .amux = LINE2, + },{ + .name = name_svideo, + .vmux = 9, /* 9 is correct as S-VIDEO1 according to a169.inf! */ + .amux = LINE1, + }}, +#if 0 + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0x0ca61000, + }, +#endif + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -3265,6 +3345,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x7350, .driver_data = SAA7134_BOARD_KWORLD_ATSC110, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1461, + .subdevice = 0x7360, + .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1461, + .subdevice = 0x6360, + .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B1, + },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -3407,9 +3499,9 @@ int saa7134_board_init1(struct saa7134_dev *dev) break; case SAA7134_BOARD_MD5044: printk("%s: seems there are two different versions of the MD5044\n" - "%s: (with the same ID) out there. If sound doesn't work for\n" - "%s: you try the audio_clock_override=0x200000 insmod option.\n", - dev->name,dev->name,dev->name); + "%s: (with the same ID) out there. If sound doesn't work for\n" + "%s: you try the audio_clock_override=0x200000 insmod option.\n", + dev->name,dev->name,dev->name); break; case SAA7134_BOARD_CINERGY400_CARDBUS: /* power-up tuner chip */ @@ -3456,6 +3548,12 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_UPMOST_PURPLE_TV: dev->has_remote = SAA7134_REMOTE_I2C; break; + case SAA7134_BOARD_AVERMEDIA_A169_B: + printk("%s: AVerMedia A169: dual saa7134 broadcast decoders\n" + "%s: Sorry, none of the inputs to this chip are supported yet.\n" + "%s: Dual decoder functionality is disabled for now, use the other chip.\n", + dev->name,dev->name,dev->name); + break; } return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index e23c6a42d..53717ff9c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -70,6 +70,11 @@ static unsigned int latency = UNSET; module_param(latency, int, 0444); MODULE_PARM_DESC(latency,"pci latency timer"); +static int no_overlay=-1; +module_param(no_overlay, int, 0444); +MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" + " [some VIA/SIS chipsets are known to have problem with overlay]"); + static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; @@ -316,8 +321,7 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt) void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf) { - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); videobuf_waiton(&buf->vb,0,0); videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma); @@ -906,6 +910,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, latency = 0x0A; } #endif + if (pci_pci_problems & PCIPCI_FAIL) { + printk(KERN_INFO "%s: quirk: this driver and your " + "chipset may not work together" + " in overlay mode.\n",dev->name); + if (!no_overlay) { + printk(KERN_INFO "%s: quirk: overlay " + "mode will be disabled.\n", + dev->name); + no_overlay = 1; + } else { + printk(KERN_INFO "%s: quirk: overlay " + "mode will be forced. Use this" + " option at your own risk.\n", + dev->name); + } + } } if (UNSET != latency) { printk(KERN_INFO "%s: setting pci latency timer to %d\n", diff --git a/linux/drivers/media/video/saa7134/saa7134-oss.c b/linux/drivers/media/video/saa7134/saa7134-oss.c index 742692ab2..b57fa81cd 100644 --- a/linux/drivers/media/video/saa7134/saa7134-oss.c +++ b/linux/drivers/media/video/saa7134/saa7134-oss.c @@ -103,8 +103,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) { int err; - if (!dev->dmasound.bufsize) - BUG(); + BUG_ON(!dev->dmasound.bufsize); videobuf_dma_init(&dev->dmasound.dma); err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); @@ -115,8 +114,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev) static int dsp_buffer_free(struct saa7134_dev *dev) { - if (!dev->dmasound.blksize) - BUG(); + BUG_ON(!dev->dmasound.blksize); videobuf_dma_free(&dev->dmasound.dma); dev->dmasound.blocks = 0; dev->dmasound.blksize = 0; diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index daab08493..a034776ae 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -493,8 +493,7 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit) static void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) { - if ((fh->resources & bits) != bits) - BUG(); + BUG_ON((fh->resources & bits) != bits); mutex_lock(&dev->lock); fh->resources &= ~bits; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index b72306e59..511516adb 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -228,6 +228,8 @@ struct saa7134_format { #define SAA7134_BOARD_TEVION_DVBT_220RF 88 #define SAA7134_BOARD_ELSA_700TV 89 #define SAA7134_BOARD_KWORLD_ATSC110 90 +#define SAA7134_BOARD_AVERMEDIA_A169_B 91 +#define SAA7134_BOARD_AVERMEDIA_A169_B1 92 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index e6e808259..57db5b1aa 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -390,6 +390,9 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) case TUNER_PHILIPS_FMD1216ME_MK3: buffer[3] = 0x19; break; + case TUNER_TNF_5335MF: + buffer[3] = 0x11; + break; case TUNER_PHILIPS_FM1256_IH3: div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ buffer[3] = 0x19; diff --git a/linux/drivers/media/video/tuner-types.c b/linux/drivers/media/video/tuner-types.c index c56ded3ec..560879ce9 100644 --- a/linux/drivers/media/video/tuner-types.c +++ b/linux/drivers/media/video/tuner-types.c @@ -941,17 +941,27 @@ static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = { /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */ -static struct tuner_range tuner_lg_taln_mini_ntsc_ranges[] = { +static struct tuner_range tuner_lg_taln_ntsc_ranges[] = { { 16 * 137.25 /*MHz*/, 0x8e, 0x01, }, { 16 * 373.25 /*MHz*/, 0x8e, 0x02, }, { 16 * 999.99 , 0x8e, 0x08, }, }; -static struct tuner_params tuner_lg_taln_mini_params[] = { +static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = { + { 16 * 150.00 /*MHz*/, 0x8e, 0x01, }, + { 16 * 425.00 /*MHz*/, 0x8e, 0x02, }, + { 16 * 999.99 , 0x8e, 0x08, }, +}; + +static struct tuner_params tuner_lg_taln_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_lg_taln_mini_ntsc_ranges, - .count = ARRAY_SIZE(tuner_lg_taln_mini_ntsc_ranges), + .ranges = tuner_lg_taln_ntsc_ranges, + .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges), + },{ + .type = TUNER_PARAM_TYPE_PAL, + .ranges = tuner_lg_taln_pal_secam_ranges, + .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges), }, }; @@ -999,12 +1009,22 @@ static struct tuner_params tuner_tuv1236d_params[] = { #endif }; -/* ------------ TUNER_TNF_5335MF - Philips NTSC ------------ */ +/* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */ +/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF + * but it is expected to work also with other Tenna/Ymec + * models based on TI SN 761677 chip on both PAL and NTSC + */ + +static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = { + { 16 * 168.25 /*MHz*/, 0x8e, 0x01, }, + { 16 * 471.25 /*MHz*/, 0x8e, 0x02, }, + { 16 * 999.99 , 0x8e, 0x08, }, +}; static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = { - { 16 * 157.25 /*MHz*/, 0x8e, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, + { 16 * 169.25 /*MHz*/, 0x8e, 0x01, }, + { 16 * 469.25 /*MHz*/, 0x8e, 0x02, }, + { 16 * 999.99 , 0x8e, 0x08, }, }; static struct tuner_params tuner_tnf_5335mf_params[] = { @@ -1013,6 +1033,11 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { .ranges = tuner_tnf_5335mf_ntsc_ranges, .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges), }, + { + .type = TUNER_PARAM_TYPE_PAL, + .ranges = tuner_tnf_5335_d_if_pal_ranges, + .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges), + }, }; /* 70-79 */ @@ -1388,10 +1413,10 @@ struct tunertype tuners[] = { .params = tuner_ymec_tvf66t5_b_dff_params, .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params), }, - [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */ - .name = "LG NTSC (TALN mini series)", - .params = tuner_lg_taln_mini_params, - .count = ARRAY_SIZE(tuner_lg_taln_mini_params), + [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */ + .name = "LG TALN series", + .params = tuner_lg_taln_params, + .count = ARRAY_SIZE(tuner_lg_taln_params), }, [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ .name = "Philips TD1316 Hybrid Tuner", @@ -1403,8 +1428,8 @@ struct tunertype tuners[] = { .params = tuner_tuv1236d_params, .count = ARRAY_SIZE(tuner_tuv1236d_params), }, - [TUNER_TNF_5335MF] = { /* Philips NTSC */ - .name = "Tena TNF 5335 MF", + [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */ + .name = "Tena TNF 5335 and similar models", .params = tuner_tnf_5335mf_params, .count = ARRAY_SIZE(tuner_tnf_5335mf_params), }, @@ -1422,6 +1447,7 @@ struct tunertype tuners[] = { [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */ .name = "Thomson FE6600", .params = tuner_thomson_fe6600_params, + .count = ARRAY_SIZE(tuner_thomson_fe6600_params), }, }; diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c index c4e2c58a2..4a83c6943 100644 --- a/linux/drivers/media/video/video-buf.c +++ b/linux/drivers/media/video/video-buf.c @@ -61,8 +61,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) pg = vmalloc_to_page(virt); if (NULL == pg) goto err; - if (PageHighMem(pg)) - BUG(); + BUG_ON(PageHighMem(pg)); sglist[i].page = pg; sglist[i].length = PAGE_SIZE; } diff --git a/linux/include/linux/dvb/video.h b/linux/include/linux/dvb/video.h index 1f7fa0351..faebfda39 100644 --- a/linux/include/linux/dvb/video.h +++ b/linux/include/linux/dvb/video.h @@ -135,7 +135,7 @@ typedef struct video_spu { typedef struct video_spu_palette { /* SPU Palette information */ int length; - uint8_t *palette; + uint8_t __user *palette; } video_spu_palette_t; diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 1b76d3e9a..2995bf836 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -592,7 +592,7 @@ struct v4l2_framebuffer struct v4l2_clip { struct v4l2_rect c; - struct v4l2_clip *next; + struct v4l2_clip __user *next; }; struct v4l2_window diff --git a/linux/include/media/tuner.h b/linux/include/media/tuner.h index c18cac6c8..a5471fa67 100644 --- a/linux/include/media/tuner.h +++ b/linux/include/media/tuner.h @@ -111,7 +111,7 @@ #define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ #define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ -#define TUNER_LG_NTSC_TALN_MINI 66 +#define TUNER_LG_TALN 66 #define TUNER_PHILIPS_TD1316 67 #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ diff --git a/mailimport b/mailimport new file mode 100755 index 000000000..b563eecd9 --- /dev/null +++ b/mailimport @@ -0,0 +1,154 @@ +#!/bin/bash +# Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) +# This code is placed under the terms of the GNU General Public License +# +#This script is capable to mass import patches on a mbox file, test for it, allow +#comment editing and applying it. +# +#This script requires: +#1) git, since it uses gitimport to break a mbox into patches; +#2) hg mailqueue. It is easier to manage patches using mq, allowing to work with +# the patches before applying to the tree. + +#uncomment to use mq +#usemq=1 + +#uncomment to stop at the first error while testing a patch with --dry-run +#exitonerror=1 + +head=v4l/scripts/hghead.pl + +if [ "$1" == "" ]; then + echo "Usage: $0 <mbox>" + exit +fi +MBOX=$1 + +if [ "$TMPDIR" == "" ]; then + TMPDIR=/tmp +fi + +DIR=$TMPDIR/mailimport$$ +mkdir $DIR +if [ "$?" != "0" ]; then + echo "*** Error at mkdir $DIR" + exit; +fi +trap "rm -rf $DIR" EXIT +TMP2=$DIR/patchheader + +apply_patch () { + next=$1 + pdir=linux + + echo patch -s -t -p1 --dry-run -l -N -d $pdir -i $next + patch -s -t -p1 --dry-run -l -N -d $pdir -i $next + if [ "$?" != "0" ]; then + pdir=. + echo patch -s -t -p1 --dry-run -l -N -d $pdir -i $next + patch -s -t -p1 --dry-run -l -N -d $pdir -i $next + if [ "$?" != "0" ]; then + $head $next + echo "*** ERROR: Patch didn't applied well" + if [ "$exitonerror" != "" ]; then + exit + else + return + fi + fi + fi + + nano $next + + unset cont + until [ "$cont" == "0" ]; do + cont=0 + $head $next >$TMP2 + + if [ "`grep '^Bad:' $TMP2`" != "" ]; then + echo "*** ERROR: Patch bad formed. Please fix." + sleep 1 + nano $next + cont=1 + fi + done + + make whitespace + + committer=`grep "Committer:" $TMP2|sed s/"#Committer: "//` + + if [ "$usemq" != "" ]; then + name=`cat $next | perl -ne ' + if (s/Subject:\s+(.*)/$1/) { + m/\s*(.*)\s*\n/; + $_="$1"; + + tr/[A-Z]/[a-z]/; + s/[^a-z0-9]/_/g; + s/_+$//; + s/_+/_/g; + s/^v4l_dvb_\d+[a-z]*_//g; + + printf "%s.patch",$_; + exit; + }'` + + cat $next| grep -v "^#" >$TMPDIR/$name + + echo hg -m "`cat $TMP2|grep -v "^#"`" qnew $name + hg qnew -m "`cat $TMP2|grep -v "^#"`" $name + hg qrefresh + else + patch -s -t -p1 -l -N -d $pdir -i $next + if [ "$?" != "0" ]; then + echo "*** ERROR at: patch -s -t -p1 -l -N -d $pdir -i $next" + exit + fi + cur=`pwd` + cd $pdir + hg addremove `diffstat -p1 -l $next` + if [ "$?" != "0" ]; then + echo "*** ERROR at hg addremove" + exit + fi + # Commit the changed files + hg commit -u "$committer" -m "`cat $TMP2|grep -v "^#"`" `diffstat -p1 -l $next` + if [ "$?" != "0" ]; then + echo "*** ERROR at hg commit" + cd $cur + exit + fi + cd $cur + fi +} + +echo git-mailsplit $MBOX $DIR +echo -n "Number of patches at file: " +git-mailsplit $MBOX $DIR +echo + +for i in $DIR/*; do + cat $i| git-mailinfo $DIR/msg $DIR/patch>$DIR/author + cat $DIR/msg|grep -vi ^CC: >$DIR/msg2 + + cat $DIR/author|perl -ne "if (m/Author[:]\\s*(.*)\\n/) { \$auth=\$1; } else \ + { if (m/Email[:]\\s*(.*)\\n/) { print \"From: \$auth \<\$1\>\n\"; } else \ + { if (m/Subject[:]\\s*(.*)\\n/) { \ + \$sub=\$1; \ + \$sub=~ s;^(media|dvb|v4l|video|drivers|[-_/: \\t])*(.*);\$2;; \ + print \"Subject: \$sub\\n\"; \ + } else \ + { print; } } \ + }" >$DIR/author2 + + out=$DIR/patch.diff + + cat $DIR/author2 + + echo "Signed-off-by: $CHANGE_LOG_NAME <$CHANGE_LOG_EMAIL_ADDRESS>" >>$DIR/msg2 + + echo "cat $DIR/author2 $DIR/msg2 $DIR/patch >$out" + cat $DIR/author2 $DIR/msg2 $DIR/patch >$out + + apply_patch $out +done diff --git a/v4l/Make.config b/v4l/Make.config index 0dd4365ce..39c6a118c 100644 --- a/v4l/Make.config +++ b/v4l/Make.config @@ -20,13 +20,15 @@ CONFIG_VIDEO_ALSA := y CONFIG_VIDEO_ADV_DEBUG := y -CONFIG_VIDEO_PVRUSB2 := n +CONFIG_VIDEO_PVRUSB2 := m CONFIG_VIDEO_IVTV := n CONFIG_DVB_FIRESAT := n -CONFIG_VIDEO_CPIA2 := m +CONFIG_VIDEO_CPIA2 := m + +CONFIG_VIDEO_CX88_IVTV := n # doesn't build on older kernels @@ -112,4 +114,4 @@ ifeq ($(CONFIG_DVB_CORE),m) endif CONFIG_VIDEO_IVTV := $(if $(wildcard $(src)/ivtv-svnversion.h),m) -CONFIG_VIDEO_PVRUSB2 := $(if $(wildcard $(src)/.pvrusb2-merge),m) +CONFIG_VIDEO_CX88_IVTV := $(if $(wildcard $(src)/cx88-ivtv.c),m) diff --git a/v4l/Makefile b/v4l/Makefile index 1af345804..d9250f64a 100644 --- a/v4l/Makefile +++ b/v4l/Makefile @@ -91,6 +91,7 @@ endif obj-$(CONFIG_VIDEO_BTTV) += btcx-risc.o ir-common.o bttv.o tveeprom.o obj-$(CONFIG_VIDEO_CX88) += btcx-risc.o cx88xx.o cx8800.o cx8802.o \ cx88-blackbird.o tveeprom.o +obj-$(CONFIG_VIDEO_CX88_IVTV) += cx88-ivtv.o obj-$(CONFIG_TVP5150) += tvp5150.o obj-$(CONFIG_SAA711X) += saa711x.o obj-$(CONFIG_EM28XX) += em28xx.o tveeprom.o @@ -311,8 +312,8 @@ endif inst_video += ir-kbd-i2c.ko msp3400.ko inst_video += tvp5150.ko saa711x.ko saa7134-alsa.ko saa7134-oss.ko inst_video += saa7115.ko cx25840.ko saa7127.ko compat_ioctl32.ko -inst_cx88 := cx8800.ko cx8802.ko cx88-alsa.ko -inst_cx88 += cx88-blackbird.ko cx88xx.ko cx88-dvb.ko cx88-vp3054-i2c.ko +inst_cx88 := cx88xx.ko cx8800.ko cx8802.ko cx88-alsa.ko cx88-dvb.ko +inst_cx88 += cx88-blackbird.ko cx88-vp3054-i2c.ko cx88-ivtv.ko inst_saa7134 := saa6752hs.ko saa7134.ko saa7134-empress.ko saa7134-dvb.ko inst_em28xx := em28xx.ko inst_bt8xx := bt878.ko dvb-bt8xx.ko dst.ko dst_ca.ko @@ -355,11 +356,6 @@ qconfig:: links .version ./scripts/make_kconfig.pl /usr/src/linux-2.6.14 $(ARCH) $(KDIR)/scripts/kconfig/qconf Kconfig -pvrusb2:: - @echo creating pvrusb2 symbolic links... - @find ../v4l_experimental/pvrusb2 -name '*.[ch]' -type f -exec ln -sf '{}' . \; - @echo 'm' > .pvrusb2-merge - ivtv-checkout:: @if [ ! -d ivtv ]; then \ echo retrieving the latest ivtv sources from ivtvdriver.org; \ @@ -379,6 +375,10 @@ ivtv:: ivtv-links @echo '#define IVTV_DRIVER_VERSION_COMMENT "(v4l-dvb + ivtv virtual merge)"' > ivtv-svnversion.h @echo ivtv trunk merged. Run make to build the entire tree. +cx88-ivtv:: + @echo creating cx88-ivtv symbolic links... + @ln -sf ../v4l_experimental/cx88-ivtv.c . + links:: @echo creating symbolic links... @find ../linux/drivers/media -name '*.[ch]' -type f -exec ln -sf '{}' . \; @@ -534,7 +534,7 @@ clean:: @find . -name '*.c' -type l -exec rm '{}' \; @find . -name '*.h' -type l -exec rm '{}' \; -rm -f *~ *.o *.ko .*.o.cmd .*.ko.cmd *.mod.c av7110_firm.h fdump \ - ivtv-svnversion.h .pvrusb2-merge \ + ivtv-svnversion.h \ Kconfig Kconfig.kern .config .config.cmd distclean:: clean diff --git a/v4l/scripts/hghead.pl b/v4l/scripts/hghead.pl new file mode 100755 index 000000000..ddaef0767 --- /dev/null +++ b/v4l/scripts/hghead.pl @@ -0,0 +1,152 @@ +#!/usr/bin/perl +use strict; +use Date::Parse; + +################################################################# +# analyse diffs + +my $in = shift; +my $line; +my $subject; +my $from=0; +my $sub_ok=0; +my $init=0; +my $num=0; +my $maint_ok=0; +my $noblank=1; +my $maintainer_name=$ENV{CHANGE_LOG_NAME}; +my $maintainer_email=$ENV{CHANGE_LOG_EMAIL_ADDRESS}; +my $from=""; +my $body=""; +my $signed=""; +my $fromname=""; + +open IN, "<$in"; + +while ($line = <IN>) { + if ($line =~ m/Index.*/) { + last; + } + if ($line =~ m/^diff .*/) { + last; + } + if ($line =~ m/^\-\-\- .*/) { + last; + } + if ($line =~ m/^\-\-\-.*/) { + last; + } + if ($line =~ m/^\+\+\+ .*/) { + last; + } + + if ($line =~ m/^Date:\s*(.*)/) { + my $time = str2time($1); +# my $timestr = gmtime($time); + + if ($time) { + print "# Date: $time\n"; + } + next; + } + if ($line =~ m/^From:/) { + if ($line =~ m/^From:[\s\"]*([^\"]*)[\s\"]*<(.*)>/) { + if ($1 eq "") { + next; + } + my $name=$1; + my $email=$2; + $name =~ s/\s+$//; + $email =~ s/\s+$//; + $fromname="$name <$email>"; + $from= "From: $fromname\n"; + next; + } + print "Bad: author line have a wrong syntax\n"; + die; + } + + if ($line =~ m/^Subject:\s*(.*\n)/) { + $subject=$1; + next; + } + + if ($line =~ m;^ .*\/.*\| *[0-9]*;) { + next; + } + if ($line =~m/\d+\s*file.* changed, /) { + next; + } + + if ($line =~ m/^Signed-off-by:.*/) { + $noblank=1; + if ($line =~ m/$maintainer_name/) { + $maint_ok=1; + } + + $signed="$signed$line"; + next; + } + if ($line =~ m/^Acked-by:.*/) { + $signed="$signed$line"; + next; + } + + if ($line =~ m/^[a-zA-Z\-]*:/) { + if ($line =~ m/Changeset:\s*(.*)\n/) { + $num=$1; + } + print "# $line"; + next; + } + + if ($line =~ m|^(V4L\/DVB\s*\(.+\)\s*:.*\n)|) { + $subject=$1; + $line="\n"; + } + + if ($sub_ok == 0) { + $sub_ok=1; + substr( $subject, 0, 1 ) = uc (substr ($subject, 0, 1)); + if ($subject =~ m|V4L\/DVB\s*(.+)|) { + $subject=$1; + } + if ($line =~ m/^\n/) { + next; + } + } + + if ($noblank) { + if ($line =~ m/^\n/) { + next; + } + } + if (!$init) { + $init=1; + $noblank=0; + } + $body="$body$line"; +} +close IN; + +if ($from eq "") { + print "Bad: author doesn't exist!\n"; + die; +} + +if (!$maint_ok) { + $signed=$signed."Signed-off-by: $maintainer_name <$maintainer_email>\n"; +} + +if (!$signed =~ m/$from/) { + print "Bad: Author didn't signed his patch!\n"; + die; +} + +$body=~s/\n+$//; +$body=~s/^\n+$//; + +# First from is used by hg to recognize commiter name +print "#Committer: $maintainer_name <$maintainer_email>\n"; +print "$subject\n$from\n$body\n\n$signed"; + diff --git a/v4l/scripts/usbaudio_setup.sh b/v4l/scripts/usbaudio_setup.sh deleted file mode 100755 index 66fdd23df..000000000 --- a/v4l/scripts/usbaudio_setup.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -which /usr/bin/dialog >/dev/null -if [ "0" != "$?" ]; then -echo "this tool requires \"dialog\" (http://hightek.org/dialog/)" -exit 1 -fi -uid=`id -u` -if [ "0" != "$uid" ]; then -echo "this tool must be run as root, you can disable this message by editing the script but only do that unless you know what you're doing!" -exit 1 -fi -which gcc > /dev/null -if [ "0" != "$?" ]; then -echo "this tool won't work unless you install gcc" -exit 1 -fi -test -f ossid -if [ "0" != "$?" ]; then -cat > ossid.c <<_EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <linux/soundcard.h> -#include <fcntl.h> -#include <unistd.h> - -int main(int argc, char **argv){ - int fd; - struct mixer_info *info; - fd=open(argv[1],O_RDONLY); - if(fd>=0){ - info=malloc(sizeof(struct mixer_info)); - ioctl(fd,SOUND_MIXER_INFO,info); - printf("%c \"%s %s\"\n",(argv[1][strlen(argv[1])-1]=='p')?'0':(argv[1][strlen(argv[1])-1]+1),info->name,info->id); - free(info); - close(fd); - } else { - return 1; - } - return 0; -} -_EOF -gcc ossid.c -o ossid -rm ossid.c -fi - -test -f /proc/asound/cards -if [ "0" != "$?" ]; then -dialog --title "Welcome" --backtitle "Empia Sound Configuration" \ ---msgbox "Your system doesn't support ALSA, please have a look at \ -www.alsa-project.org and set it up properly \ - - -Press any key to continue... " 11 50 -exit 1; -fi - -dialog --title "Welcome" --backtitle "Empia Sound Configuration" \ ---msgbox "This tool was written to ease up sound configuration for -* Terratec Hybrid XS -* Terratec Cinergy 250 USB 2.0 -* Hauppauge HVR 900 -* and possible others :) - -first select an usb audio source, as target choose your soundcard -Press any key to continue... " 13 60 - -ls /dev/dsp* | while read a; do ./ossid $a; done | xargs dialog --menu "Choose your TV Audio source:" 12 60 5 2>/tmp/em2880_source.$$ -ls /dev/dsp* | while read a; do ./ossid $a; done | xargs dialog --menu "Choose your output soundcard device:" 12 60 5 2>/tmp/em2880_dst.$$ - -source=`egrep '^[0-9p]' /tmp/em2880_source.$$` -dst=`egrep '^[0-9p]' /tmp/em2880_dst.$$` - -echo "playing $source to $dst"; -if [ "$source" = "0" ]; then - device="/dev/dsp" -else - device="/dev/dsp`expr $source - 1`" -fi - -if [ "$dst" = "0" ]; then - device2="/dev/dsp" -else - device2="/dev/dsp`expr $source - 1`" -fi -clear -echo "Using command: sox -r 48000 -w -c 2 -t ossdsp $device -t ossdsp $device2" -sox -r 48000 -w -c 2 -t ossdsp $device -t ossdsp $device2 diff --git a/v4l_experimental/cx88-ivtv.c b/v4l_experimental/cx88-ivtv.c index c28c1d413..a747e2372 100644 --- a/v4l_experimental/cx88-ivtv.c +++ b/v4l_experimental/cx88-ivtv.c @@ -25,8 +25,8 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> - #include "compat.h" +#include <media/v4l2-common.h> #include "cx88.h" MODULE_DESCRIPTION("ivtv ioctl emulation module for blackbird TV cards"); @@ -111,10 +111,10 @@ static int ivtv_do_ioctl(struct inode *inode, struct file *file, /* int err; */ if (debug > 1) - cx88_print_ioctl(dev->core->name,cmd); + v4l_print_ioctl(dev->core->name,cmd); #if 1 printk( KERN_INFO "IVTV IOCTL: 0x%x\n", cmd ); - cx88_print_ioctl(dev->core->name,cmd); + v4l_print_ioctl(dev->core->name,cmd); #endif dprintk( 1, "IVTV IOCTL: 0x%x\n", cmd ); diff --git a/v4l_experimental/pvrusb2/.cvsignore b/v4l_experimental/pvrusb2/.cvsignore deleted file mode 100644 index 88be5bcbc..000000000 --- a/v4l_experimental/pvrusb2/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -*.ko -*.o.flags -*.mod.c -.*.cmd -.version -.snapshot -.tmp_versions diff --git a/v4l_experimental/pvrusb2/Makefile b/v4l_experimental/pvrusb2/Makefile deleted file mode 100644 index 0c43d6977..000000000 --- a/v4l_experimental/pvrusb2/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -BUILD_DIR := $(shell pwd)/../.. - -all: - $(MAKE) -C $(BUILD_DIR) pvrusb2 - -install: - $(MAKE) -C $(BUILD_DIR) install - -%:: - $(MAKE) -C $(BUILD_DIR) $(MAKECMDGOALS) |