Re: Flyvideo 2k/3k IR remote

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Tim Connors wrote:
> On Sat, 26 Apr 2003, David Atkinson wrote:
>
>
>>Probably a software artifact due to the fact the gpio register is
>>polled. This has been fixed in the latest version, which uses interrupts
>>instead of polling, available here:
>>
>>http://users.tpg.com.au/atko/gpf/ir/
>>
>>Note that it freezes when you try to unload the LIRC module.
>
>
> It does too. I tried applying the patch to 0.2.8 - patched successfully
> with a little fuzz. But now when I close a v4l client, the picture keeps
> distplaying on the screen. When I switch to another X session, the picture
> is still updated on the sceen (albeit, corrupted). I got an kernel panic
> in there somewhere, and I can't register any keystrokes on the
> remote whatsoever.

That's what you get when you use a snapshot :) Seriously though, are you sure this is a problem with my patch? I just tried the 0.9.8 snapshot with the IR patch applied, and I could use xawtv/motv/tvtime all fine. I just updated the patch adding support for Cinergy 400 IR remotes, this is the patch I tried against 0.9.8. Sure, the IR won't work without changing a line or two, but I don't think the patch should cause the problems you mention. Did you try 0.9.8 without the patch?

> Oh yeah, and that module unload freeze is still fun :)

Try the attached patch (against lirc-0.6.6).

eg. lirc-0.6.6$ patch -p1 < patch-lirc-0.6.6-nocrash

> What's the status on this driver these days?

The remote control driver needs to be redesigned. It's on my todo list in the next few months (when I have time).

- David.

diff -u lirc-0.6.6/drivers/lirc_dev/lirc_dev.c lirc-0.6.6-patched/drivers/lirc_dev/lirc_dev.c
--- lirc-0.6.6/drivers/lirc_dev/lirc_dev.c	2001-12-13 09:27:38.000000000 +1100
+++ lirc-0.6.6-patched/drivers/lirc_dev/lirc_dev.c	2003-05-09 15:03:24.000000000 +1000
@@ -1,7 +1,7 @@
 /*
  * LIRC base driver
  * 
- * (L) by Artur Lipowski <alipowski@xxxxxxxxxx>
+ * (L) by Artur Lipowski <alipowski@xxxxxxxxxx>
  *
  *  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
@@ -17,7 +17,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: lirc_dev.c,v 1.18 2001/12/12 20:26:01 ranty Exp $
+ * $Id: lirc_dev.c,v 1.22 2002/11/09 22:13:15 lirc Exp $
  *
  */
 
@@ -30,10 +30,10 @@
 #define LIRC_HAVE_DEVFS
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
-#error "********************************************************"
-#error " Sorry, this driver needs kernel version 2.2.4 or higher"
-#error "********************************************************"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
+#error "**********************************************************"
+#error " Sorry, this driver needs kernel version 2.2.18 or higher "
+#error "**********************************************************"
 #endif
 
 #include <linux/config.h>
@@ -87,6 +87,7 @@
 
 	int tpid;
 	struct semaphore *t_notify;
+	struct semaphore *t_notify2;
 	int shutdown;
 	long jiffies_to_wait;
 
@@ -118,6 +119,7 @@
 
 	ir->tpid = -1;
 	ir->t_notify = NULL;
+	ir->t_notify2 = NULL;
 	ir->shutdown = 0;
 	ir->jiffies_to_wait = 0;
 
@@ -202,7 +204,7 @@
 			} else {
 				interruptible_sleep_on(ir->p.get_queue(ir->p.data));
 			}
-			if (signal_pending(current)) {
+			if (ir->shutdown) {
 				break;
 			}
 			if (!add_to_buf(ir)) {
@@ -213,8 +215,12 @@
 			current->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(HZ/2);
 		}
-	} while (!ir->shutdown && !signal_pending(current));
+	} while (!ir->shutdown);
 	
+	if (ir->t_notify2 != NULL) {
+		down(ir->t_notify2);
+	}
+
 	ir->tpid = -1;
 	if (ir->t_notify != NULL) {
 		up(ir->t_notify);
@@ -258,18 +264,26 @@
 		return -EBADRQC;
 	}
 
+	printk("lirc_dev: lirc_register_plugin:"
+	       "sample_rate: %d\n",p->sample_rate);
 	if (p->sample_rate) {
 		if (2 > p->sample_rate || 50 < p->sample_rate) {
 			printk("lirc_dev: lirc_register_plugin:"
 			       "sample_rate must be beetween 2 and 50!\n");
 			return -EBADRQC;
 		}
-	} else {
+	} else if (!p->fops) {
 		if (!p->get_queue) {
 			printk("lirc_dev: lirc_register_plugin:"
 			       "get_queue cannot be NULL!\n");
 			return -EBADRQC;
 		}
+	} else {
+		if (!p->fops->read || !p->fops->poll || !p->fops->ioctl) {
+			printk("lirc_dev: lirc_register_plugin:"
+			       "neither read, poll nor ioctl can be NULL!\n");
+			return -EBADRQC;
+		}
 	}
 
 	down_interruptible(&plugin_lock);
@@ -325,18 +339,21 @@
 					  &fops, NULL);
 #endif
 
-	/* try to fire up polling thread */
-	ir->t_notify = &tn;
-	ir->tpid = kernel_thread(lirc_thread, (void*)ir, 0);
-	if (ir->tpid < 0) {
-		IRUNLOCK;
-		up(&plugin_lock);
-		printk("lirc_dev: lirc_register_plugin:"
-		       "cannot run poll thread for minor = %d\n", p->minor);
-		return -ECHILD;
+	if(p->sample_rate || p->get_queue) {
+		/* try to fire up polling thread */
+		ir->t_notify = &tn;
+		ir->tpid = kernel_thread(lirc_thread, (void*)ir, 0);
+		if (ir->tpid < 0) {
+			IRUNLOCK;
+			up(&plugin_lock);
+			printk("lirc_dev: lirc_register_plugin:"
+			       "cannot run poll thread for minor = %d\n",
+			       p->minor);
+			return -ECHILD;
+		}
+		down(&tn);
+		ir->t_notify = NULL;
 	}
-	down(&tn);
-	ir->t_notify = NULL;
 	up(&plugin_lock);
 
 	MOD_INC_USE_COUNT;
@@ -354,6 +371,7 @@
 {
 	struct irctl *ir;
 	DECLARE_MUTEX_LOCKED(tn);
+	DECLARE_MUTEX_LOCKED(tn2);
 
 	if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
 		printk("lirc_dev: lirc_unregister_plugin:"
@@ -383,9 +401,23 @@
 	/* end up polling thread */
 	if (ir->tpid >= 0) {
 		ir->t_notify = &tn;
+		ir->t_notify2 = &tn2;
 		ir->shutdown = 1;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		{
+			struct task_struct *p;
+			
+			p = find_task_by_pid(ir->tpid);
+			wake_up_process(p);
+		}
+#else
+		/* 2.2.x does not export wake_up_process() */
+		wake_up_interruptible(ir->p.get_queue(ir->p.data));
+#endif
+		up(&tn2);
 		down(&tn);
 		ir->t_notify = NULL;
+		ir->t_notify2 = NULL;
 	}
 
 	dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n",
@@ -421,6 +453,10 @@
 
 	dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor);
 
+	/* if the plugin has an open function use it instead */
+	if(ir->p.fops && ir->p.fops->open)
+		return ir->p.fops->open(inode, file);
+
 	down_interruptible(&plugin_lock);
 
 	if (ir->p.minor == NOPLUG) {
@@ -462,6 +498,10 @@
 
 	dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor);
  
+	/* if the plugin has a close function use it instead */
+	if(ir->p.fops && ir->p.fops->release)
+		return ir->p.fops->release(inode, file);
+
 	down_interruptible(&plugin_lock);
 
 	--ir->open;
@@ -481,6 +521,10 @@
 
 	dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor);
 
+	/* if the plugin has a poll function use it instead */
+	if(ir->p.fops && ir->p.fops->poll)
+		return ir->p.fops->poll(file, wait);
+
 	if (!ir->in_buf) {
 		poll_wait(file, &ir->wait_poll, wait);
 	}
@@ -505,6 +549,10 @@
 	dprintk(LOGHEAD "poll called (%u)\n",
 		ir->p.name, ir->p.minor, cmd);
 
+	/* if the plugin has a ioctl function use it instead */
+	if(ir->p.fops && ir->p.fops->ioctl)
+		return ir->p.fops->ioctl(inode, file, cmd, arg);
+
 	if (ir->p.minor == NOPLUG) {
 		dprintk(LOGHEAD "ioctl result = -ENODEV\n",
 			ir->p.name, ir->p.minor);
@@ -555,6 +603,10 @@
 
 	dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
 
+	/* if the plugin has a specific read function use it instead */
+	if(ir->p.fops && ir->p.fops->read)
+		return ir->p.fops->read(file, buffer, length, ppos);
+
 	if (ir->bytes_in_key != length) {
 		dprintk(LOGHEAD "read result = -EIO\n",
 			ir->p.name, ir->p.minor);
@@ -611,9 +663,24 @@
 	return ret ? -EFAULT : length;
 }
 
+static ssize_t irctl_write(struct file *file, const char *buffer,
+			   size_t length, loff_t * ppos)
+{
+	struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
+
+	dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
+
+	/* if the plugin has a specific read function use it instead */
+	if(ir->p.fops && ir->p.fops->write)
+		return ir->p.fops->write(file, buffer, length, ppos);
+
+	return -EINVAL;
+}
+
 
 static struct file_operations fops = {
 	read:    irctl_read, 
+	write:   irctl_write,
 	poll:    irctl_poll,
 	ioctl:   irctl_ioctl,
 	open:    irctl_open,
diff -u lirc-0.6.6/drivers/lirc_dev/lirc_dev.h lirc-0.6.6-patched/drivers/lirc_dev/lirc_dev.h
--- lirc-0.6.6/drivers/lirc_dev/lirc_dev.h	2000-12-04 05:02:55.000000000 +1100
+++ lirc-0.6.6-patched/drivers/lirc_dev/lirc_dev.h	2003-05-09 15:06:09.000000000 +1000
@@ -1,21 +1,16 @@
 /*
  * LIRC base driver
  * 
- * (L) by Artur Lipowski <alipowski@xxxxxxxxxx>
+ * (L) by Artur Lipowski <alipowski@xxxxxxxxxx>
  *        This code is licensed under GNU GPL
  *
- * $Id: lirc_dev.h,v 1.3 2000/12/03 18:02:55 columbus Exp $
+ * $Id: lirc_dev.h,v 1.7 2002/11/19 20:22:06 ranty Exp $
  *
  */
 
 #ifndef _LINUX_LIRC_DEV_H
 #define _LINUX_LIRC_DEV_H
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
-/* comes with bttv */
-#include "../drivers/char/kcompat24.h"
-#endif
-
 #define MAX_IRCTL_DEVICES 2
 #define BUFLEN            16
 
@@ -25,11 +20,14 @@
      int minor;
      int code_length;
      int sample_rate;
+     unsigned long features;
      void* data;
      int (*get_key) (void* data, unsigned char* key, int key_no);
      wait_queue_head_t* (*get_queue) (void* data);
-     void (*set_use_inc) (void* data);
+     int (*set_use_inc) (void* data);
      void (*set_use_dec) (void* data);
+     int (*ioctl) (struct inode *,struct file *,unsigned int, unsigned long);
+     struct file_operations *fops;
 };
 /* name:
  * this string will be used for logs
@@ -72,6 +70,9 @@
  *
  * set_use_dec:
  * set_use_dec will be called after device is closed
+ *
+ * fops:
+ * file_operations for drivers which don't fit the current plugin model.
  */
 
 


[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux