[arch-commits] CVS update of extra/system/lirc (3 files)

Tobias Powalowski tpowa at archlinux.org
Fri Jan 25 17:43:12 UTC 2008


    Date: Friday, January 25, 2008 @ 12:43:12
  Author: tpowa
    Path: /home/cvs-extra/extra/system/lirc

   Added: kernel-2.6.24.patch (1.1)
Modified: PKGBUILD (1.51 -> 1.52) lirc.install (1.17 -> 1.18)

upgpkg: update to new .24 kernel series


---------------------+
 PKGBUILD            |   17 
 kernel-2.6.24.patch | 1143 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lirc.install        |    6 
 3 files changed, 1153 insertions(+), 13 deletions(-)


Index: extra/system/lirc/PKGBUILD
diff -u extra/system/lirc/PKGBUILD:1.51 extra/system/lirc/PKGBUILD:1.52
--- extra/system/lirc/PKGBUILD:1.51	Fri Jan 11 23:40:52 2008
+++ extra/system/lirc/PKGBUILD	Fri Jan 25 12:43:12 2008
@@ -1,18 +1,17 @@
-# $Id: PKGBUILD,v 1.51 2008/01/12 04:40:52 paul Exp $
+# $Id: PKGBUILD,v 1.52 2008/01/25 17:43:12 tpowa Exp $
 # Maintainer: Paul Mattal <paul at archlinux.org>
 
 pkgname=lirc
 pkgver=0.8.2
-pkgrel=9
-_kernver=2.6.23-ARCH
+pkgrel=7
+_kernver=2.6.24-ARCH
 pkgdesc="Linux Infrared Remote Control kernel modules for stock arch kernel"
 arch=(i686 x86_64)
 license=('GPL')
-depends=('lirc-utils' 'kernel26>=2.6.23.8-2')
+depends=('lirc-utils' 'kernel26>=2.6.24-1' 'kernel26<=2.6.25-0')
 makedepends=(help2man)
 source=(http://puzzle.dl.sf.net/sourceforge/$pkgname/$pkgname-$pkgver.tar.bz2 \
-	kernel-2.6.23.patch \
-	lirc-0.8.2-kernel-2.6.22.patch)
+	kernel-2.6.23.patch kernel-2.6.24.patch)
 url="http://www.lirc.org/"
 install=$pkgname.install
 replaces=('lirc+pctv')
@@ -21,9 +20,7 @@
 	# configure
 	cd $startdir/src/lirc-$pkgver || return 1
 	patch -Np1 -i ../kernel-2.6.23.patch || return 1
-	# patch for buffer overflow #8095
-	patch -Np1 -i ../lirc-0.8.2-kernel-2.6.22.patch || return 1
-	
+	patch -Np1 -i ../kernel-2.6.24.patch || return 1
 	./configure --enable-sandboxed --prefix=/usr \
 		--with-driver=all --with-kerneldir=/usr/src/linux-${_kernver}/ \
 		--with-moduledir=/lib/modules/${_kernver}/kernel/drivers/misc \
@@ -50,4 +47,4 @@
 }
 md5sums=('83e7060a6693b81075c178d7e3b215af'
          '645d016b60bd4e67cc880aba034b1f68'
-         '43ef322a202e002088ba82881923b395')
+         '90108e94acc0413f70d83a4d5558757d')
Index: extra/system/lirc/kernel-2.6.24.patch
diff -u /dev/null extra/system/lirc/kernel-2.6.24.patch:1.1
--- /dev/null	Fri Jan 25 12:43:12 2008
+++ extra/system/lirc/kernel-2.6.24.patch	Fri Jan 25 12:43:12 2008
@@ -0,0 +1,1143 @@
+--- lirc-0.8.2/drivers/lirc_dev/lirc_dev.c	2007/11/08 21:27:29	1.53
++++ lirc-0.8.2/drivers/lirc_dev/lirc_dev.c	2008/01/13 10:45:02	1.56
+@@ -41,14 +41,23 @@
+ #include <linux/fs.h>
+ #include <linux/poll.h>
+ #include <linux/smp_lock.h>
++#include <linux/completion.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
+ #include <asm/uaccess.h>
+-#include <asm/semaphore.h>
+ #include <asm/errno.h>
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
++#else
++#include <linux/uaccess.h>
++#include <linux/errno.h>
++#endif
++#include <asm/semaphore.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+ #include <linux/wrapper.h>
+ #endif
+ #define __KERNEL_SYSCALLS__
+ #include <linux/unistd.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
++#include <linux/kthread.h>
++#endif
+ 
+ #include "drivers/kcompat.h"
+ 
+@@ -60,19 +69,19 @@
+ #include "drivers/lirc.h"
+ #include "lirc_dev.h"
+ 
+-static int debug = 0;
+-#define dprintk(fmt, args...)                                 \
+-	do{                                                   \
+-		if(debug) printk(KERN_DEBUG fmt, ## args);    \
+-	}while(0)
++static int debug;
++#define dprintk(fmt, args...)					\
++	do {							\
++		if (debug)					\
++			printk(KERN_DEBUG fmt, ## args);	\
++	} while (0)
+ 
+ #define IRCTL_DEV_NAME    "BaseRemoteCtl"
+ #define SUCCESS           0
+ #define NOPLUG            -1
+ #define LOGHEAD           "lirc_dev (%s[%d]): "
+ 
+-struct irctl
+-{
++struct irctl {
+ 	struct lirc_plugin p;
+ 	int attached;
+ 	int open;
+@@ -80,10 +89,14 @@
+ 	struct semaphore buffer_sem;
+ 	struct lirc_buffer *buf;
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	int tpid;
+-	struct semaphore *t_notify;
+-	struct semaphore *t_notify2;
++	struct completion *t_notify;
++	struct completion *t_notify2;
+ 	int shutdown;
++#else
++	struct task_struct *task;
++#endif
+ 	long jiffies_to_wait;
+ 
+ #ifdef LIRC_HAVE_DEVFS_24
+@@ -108,10 +121,14 @@
+ 	sema_init(&ir->buffer_sem, 1);
+ 	ir->p.minor = NOPLUG;
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	ir->tpid = -1;
+ 	ir->t_notify = NULL;
+ 	ir->t_notify2 = NULL;
+ 	ir->shutdown = 0;
++#else
++	ir->task = NULL;
++#endif
+ 	ir->jiffies_to_wait = 0;
+ 
+ 	ir->open = 0;
+@@ -128,14 +145,14 @@
+ #ifdef LIRC_HAVE_DEVFS_26
+ 	devfs_remove(DEV_LIRC "/%u", ir->p.minor);
+ #endif
+-	class_device_destroy(lirc_class,MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
++	class_device_destroy(lirc_class, MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ 
+-	if (ir->buf != ir->p.rbuf){
++	if (ir->buf != ir->p.rbuf) {
+ 		lirc_buffer_free(ir->buf);
+ 		kfree(ir->buf);
+ 	}
+ 	ir->buf = NULL;
+-	
++
+ 	init_irctl(ir);
+ }
+ 
+@@ -152,29 +169,31 @@
+ 		return -EOVERFLOW;
+ 	}
+ 
+-	if(ir->p.add_to_buf) {
++	if (ir->p.add_to_buf) {
+ 		int res = -ENODATA;
+ 		int got_data = 0;
+-		
++
+ 		/* service the device as long as it is returning
+ 		 * data and we have space
+ 		 */
+-		while( !lirc_buffer_full(ir->buf) )
+-		{
+-			res = ir->p.add_to_buf( ir->p.data, ir->buf );
+-			if( res == SUCCESS )
++		while (!lirc_buffer_full(ir->buf)) {
++			res = ir->p.add_to_buf(ir->p.data, ir->buf);
++			if (res == SUCCESS)
+ 				got_data++;
+ 			else
+ 				break;
+ 		}
+-		
+-		if( res == -ENODEV )
+-		{
++
++		if (res == -ENODEV)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 			ir->shutdown = 1;
+-		}
++#else
++			kthread_stop(ir->task);
++#endif
++
+ 		return (got_data ? SUCCESS : res);
+ 	}
+-	
++
+ 	return SUCCESS;
+ }
+ 
+@@ -183,56 +202,59 @@
+ static int lirc_thread(void *irctl)
+ {
+ 	struct irctl *ir = irctl;
+-	
++
+ 	/* This thread doesn't need any user-level access,
+ 	 * so get rid of all our resources
+ 	 */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	daemonize("lirc_dev");
+-	
+-	if (ir->t_notify != NULL) {
+-		up(ir->t_notify);
+-	}
+-	
++
++	if (ir->t_notify != NULL)
++		complete(ir->t_notify);
++#endif
++
+ 	dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor);
+-	
++
+ 	do {
+ 		if (ir->open) {
+ 			if (ir->jiffies_to_wait) {
+ 				set_current_state(TASK_INTERRUPTIBLE);
+ 				schedule_timeout(ir->jiffies_to_wait);
+ 			} else {
+-				interruptible_sleep_on(ir->p.get_queue(ir->p.data));
++				interruptible_sleep_on(
++					ir->p.get_queue(ir->p.data));
+ 			}
+-			if (ir->shutdown) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
++			if (ir->shutdown)
++#else
++			if (kthread_should_stop())
++#endif
+ 				break;
+-			}
+-			if (!add_to_buf(ir)) {
++			if (!add_to_buf(ir))
+ 				wake_up_interruptible(&ir->buf->wait_poll);
+-			}
+ 		} else {
+ 			/* if device not opened so we can sleep half a second */
+ 			set_current_state(TASK_INTERRUPTIBLE);
+ 			schedule_timeout(HZ/2);
+ 		}
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	} while (!ir->shutdown);
+-	
+-	if (ir->t_notify2 != NULL) {
+-		down(ir->t_notify2);
+-	}
++
++	if (ir->t_notify2 != NULL)
++		wait_for_completion(ir->t_notify2);
+ 
+ 	ir->tpid = -1;
+-	if (ir->t_notify != NULL) {
+-		up(ir->t_notify);
+-	}
+-	
++	if (ir->t_notify != NULL)
++		complete(ir->t_notify);
++#else
++	} while (!kthread_should_stop());
++#endif
++
+ 	dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor);
+-	
++
+ 	return 0;
+ }
+ 
+-/*
+- *
+- */
+ int lirc_register_plugin(struct lirc_plugin *p)
+ {
+ 	struct irctl *ir;
+@@ -242,43 +264,43 @@
+ #ifdef LIRC_HAVE_DEVFS_24
+ 	char name[16];
+ #endif
+-	DECLARE_MUTEX_LOCKED(tn);
++	DECLARE_COMPLETION(tn);
+ 
+ 	if (!p) {
+-		printk("lirc_dev: lirc_register_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 		       "plugin pointer must be not NULL!\n");
+ 		err = -EBADRQC;
+ 		goto out;
+ 	}
+ 
+ 	if (MAX_IRCTL_DEVICES <= p->minor) {
+-		printk("lirc_dev: lirc_register_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 		       "\"minor\" must be between 0 and %d (%d)!\n",
+ 		       MAX_IRCTL_DEVICES-1, p->minor);
+ 		err = -EBADRQC;
+ 		goto out;
+ 	}
+ 
+-	if (1 > p->code_length || (BUFLEN*8) < p->code_length) {
+-		printk("lirc_dev: lirc_register_plugin: "
++	if (1 > p->code_length || (BUFLEN * 8) < p->code_length) {
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 		       "code length in bits for minor (%d) "
+ 		       "must be less than %d!\n",
+-		       p->minor, BUFLEN*8);
++		       p->minor, BUFLEN * 8);
+ 		err = -EBADRQC;
+ 		goto out;
+ 	}
+ 
+-	printk("lirc_dev: lirc_register_plugin: "
+-	       "sample_rate: %d\n",p->sample_rate);
++	printk(KERN_INFO "lirc_dev: lirc_register_plugin: sample_rate: %d\n",
++		p->sample_rate);
+ 	if (p->sample_rate) {
+ 		if (2 > p->sample_rate || HZ < p->sample_rate) {
+-			printk("lirc_dev: lirc_register_plugin: "
++			printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 			       "sample_rate must be between 2 and %d!\n", HZ);
+ 			err = -EBADRQC;
+ 			goto out;
+ 		}
+ 		if (!p->add_to_buf) {
+-			printk("lirc_dev: lirc_register_plugin: "
++			printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 			       "add_to_buf cannot be NULL when "
+ 			       "sample_rate is set\n");
+ 			err = -EBADRQC;
+@@ -286,15 +308,15 @@
+ 		}
+ 	} else if (!(p->fops && p->fops->read)
+ 		   && !p->get_queue && !p->rbuf) {
+-		printk("lirc_dev: lirc_register_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 		       "fops->read, get_queue and rbuf "
+ 		       "cannot all be NULL!\n");
+ 		err = -EBADRQC;
+ 		goto out;
+ 	} else if (!p->get_queue && !p->rbuf) {
+-		if (!(p->fops && p->fops->read && p->fops->poll) 
++		if (!(p->fops && p->fops->read && p->fops->poll)
+ 		    || (!p->fops->ioctl && !p->ioctl)) {
+-			printk("lirc_dev: lirc_register_plugin: "
++			printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 			       "neither read, poll nor ioctl can be NULL!\n");
+ 			err = -EBADRQC;
+ 			goto out;
+@@ -302,7 +324,7 @@
+ 	}
+ 
+ 	if (p->owner == NULL) {
+-		printk(KERN_WARNING "lirc_dev: lirc_register_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 				    "no module owner registered\n");
+ 		err = -EBADRQC;
+ 		goto out;
+@@ -314,17 +336,17 @@
+ 
+ 	if (0 > minor) {
+ 		/* find first free slot for plugin */
+-		for (minor=0; minor<MAX_IRCTL_DEVICES; minor++)
++		for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
+ 			if (irctls[minor].p.minor == NOPLUG)
+ 				break;
+ 		if (MAX_IRCTL_DEVICES == minor) {
+-			printk("lirc_dev: lirc_register_plugin: "
++			printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 			       "no free slots for plugins!\n");
+ 			err = -ENOMEM;
+ 			goto out_lock;
+ 		}
+ 	} else if (irctls[minor].p.minor != NOPLUG) {
+-		printk("lirc_dev: lirc_register_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 		       "minor (%d) just registered!\n", minor);
+ 		err = -EBUSY;
+ 		goto out_lock;
+@@ -335,32 +357,32 @@
+ 	if (p->sample_rate) {
+ 		ir->jiffies_to_wait = HZ / p->sample_rate;
+ 	} else {
+-                /* it means - wait for externeal event in task queue */
++		/* it means - wait for external event in task queue */
+ 		ir->jiffies_to_wait = 0;
+-	} 
++	}
+ 
+ 	/* some safety check 8-) */
+ 	p->name[sizeof(p->name)-1] = '\0';
+ 
+ 	bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0);
+-	
++
+ 	if (p->rbuf) {
+ 		ir->buf = p->rbuf;
+ 	} else {
+ 		ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+-		if(!ir->buf) {
++		if (!ir->buf) {
+ 			err = -ENOMEM;
+ 			goto out_lock;
+ 		}
+-		if(lirc_buffer_init
+-		   (ir->buf, bytes_in_key, BUFLEN/bytes_in_key) != 0) {
++		if (lirc_buffer_init(ir->buf, bytes_in_key,
++				     BUFLEN/bytes_in_key) != 0) {
+ 			kfree(ir->buf);
+ 			err = -ENOMEM;
+ 			goto out_lock;
+ 		}
+ 	}
+ 
+-	if (p->features==0)
++	if (p->features == 0)
+ 		p->features = (p->code_length > 8) ?
+ 			LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE;
+ 
+@@ -368,7 +390,7 @@
+ 	ir->p.minor = minor;
+ 
+ #if defined(LIRC_HAVE_DEVFS_24)
+-	sprintf (name, DEV_LIRC "/%d", ir->p.minor);
++	sprintf(name, DEV_LIRC "/%d", ir->p.minor);
+ 	ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+ 					  IRCTL_DEV_MAJOR, ir->p.minor,
+ 					  S_IFCHR | S_IRUSR | S_IWUSR,
+@@ -378,23 +400,30 @@
+ 			S_IFCHR|S_IRUSR|S_IWUSR,
+ 			DEV_LIRC "/%u", ir->p.minor);
+ #endif
+-	(void) lirc_class_device_create(lirc_class, NULL, 
++	(void) lirc_class_device_create(lirc_class, NULL,
+ 					MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
+ 					ir->p.dev, "lirc%u", ir->p.minor);
+ 
+-	if(p->sample_rate || p->get_queue) {
++	if (p->sample_rate || p->get_queue) {
+ 		/* try to fire up polling thread */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 		ir->t_notify = &tn;
+-		ir->tpid = kernel_thread(lirc_thread, (void*)ir, 0);
++		ir->tpid = kernel_thread(lirc_thread, (void *)ir, 0);
+ 		if (ir->tpid < 0) {
+-			printk("lirc_dev: lirc_register_plugin: "
++#else
++		ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev");
++		if (IS_ERR(ir->task)) {
++#endif
++			printk(KERN_ERR "lirc_dev: lirc_register_plugin: "
+ 			       "cannot run poll thread for minor = %d\n",
+ 			       p->minor);
+ 			err = -ECHILD;
+ 			goto out_sysfs;
+ 		}
+-		down(&tn);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
++		wait_for_completion(&tn);
+ 		ir->t_notify = NULL;
++#endif
+ 	}
+ 	ir->attached = 1;
+ 	up(&plugin_lock);
+@@ -410,9 +439,9 @@
+ 		ir->p.name, ir->p.minor);
+ 	p->minor = minor;
+ 	return minor;
+-	
++
+ out_sysfs:
+-	class_device_destroy(lirc_class,MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
++	class_device_destroy(lirc_class, MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ #ifdef LIRC_HAVE_DEVFS_24
+ 	devfs_unregister(ir->devfs_handle);
+ #endif
+@@ -424,18 +453,16 @@
+ out:
+ 	return err;
+ }
++EXPORT_SYMBOL(lirc_register_plugin);
+ 
+-/*
+- *
+- */
+ int lirc_unregister_plugin(int minor)
+ {
+ 	struct irctl *ir;
+-	DECLARE_MUTEX_LOCKED(tn);
+-	DECLARE_MUTEX_LOCKED(tn2);
++	DECLARE_COMPLETION(tn);
++	DECLARE_COMPLETION(tn2);
+ 
+ 	if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
+-		printk("lirc_dev: lirc_unregister_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: "
+ 		       "\"minor\" must be between 0 and %d!\n",
+ 		       MAX_IRCTL_DEVICES-1);
+ 		return -EBADRQC;
+@@ -446,21 +473,22 @@
+ 	down(&plugin_lock);
+ 
+ 	if (ir->p.minor != minor) {
+-		printk("lirc_dev: lirc_unregister_plugin: "
++		printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: "
+ 		       "minor (%d) device not registered!", minor);
+ 		up(&plugin_lock);
+ 		return -ENOENT;
+ 	}
+ 
+ 	/* end up polling thread */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	if (ir->tpid >= 0) {
+ 		ir->t_notify = &tn;
+ 		ir->t_notify2 = &tn2;
+ 		ir->shutdown = 1;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
+ 		{
+ 			struct task_struct *p;
+-			
++
+ 			p = find_task_by_pid(ir->tpid);
+ 			wake_up_process(p);
+ 		}
+@@ -468,11 +496,17 @@
+ 		/* 2.2.x does not export wake_up_process() */
+ 		wake_up_interruptible(ir->p.get_queue(ir->p.data));
+ #endif
+-		up(&tn2);
+-		down(&tn);
++		complete(&tn2);
++		wait_for_completion(&tn);
+ 		ir->t_notify = NULL;
+ 		ir->t_notify2 = NULL;
+ 	}
++#else /* kernel >= 2.6.23 */
++	if (ir->task) {
++		wake_up_process(ir->task);
++		kthread_stop(ir->task);
++	}
++#endif
+ 
+ 	dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n",
+ 		ir->p.name, ir->p.minor);
+@@ -486,11 +520,8 @@
+ 		ir->p.set_use_dec(ir->p.data);
+ 		module_put(ir->p.owner);
+ 		up(&ir->buffer_sem);
+-	}
+-	else
+-	{
++	} else
+ 		cleanup(ir);
+-	}
+ 	up(&plugin_lock);
+ 
+ /*
+@@ -503,6 +534,7 @@
+ 
+ 	return SUCCESS;
+ }
++EXPORT_SYMBOL(lirc_unregister_plugin);
+ 
+ /*
+  *
+@@ -511,7 +543,7 @@
+ {
+ 	struct irctl *ir;
+ 	int retval;
+-	
++
+ 	if (MINOR(inode->i_rdev) >= MAX_IRCTL_DEVICES) {
+ 		dprintk("lirc_dev [%d]: open result = -ENODEV\n",
+ 			MINOR(inode->i_rdev));
+@@ -523,13 +555,11 @@
+ 	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)
++	if (ir->p.fops && ir->p.fops->open)
+ 		return ir->p.fops->open(inode, file);
+ 
+ 	if (down_interruptible(&plugin_lock))
+-	{
+ 		return -ERESTARTSYS;
+-	}
+ 
+ 	if (ir->p.minor == NOPLUG) {
+ 		up(&plugin_lock);
+@@ -545,30 +575,27 @@
+ 		return -EBUSY;
+ 	}
+ 
+-	/* there is no need for locking here because ir->open is 0 
+-         * and lirc_thread isn't using buffer
++	/* there is no need for locking here because ir->open is 0
++	 * and lirc_thread isn't using buffer
+ 	 * plugins which use irq's should allocate them on set_use_inc,
+ 	 * so there should be no problem with those either.
+-         */
++	 */
+ 	ir->buf->head = ir->buf->tail;
+ 	ir->buf->fill = 0;
+ 
+-	if(ir->p.owner!=NULL && try_module_get(ir->p.owner))
+-	{
++	if (ir->p.owner != NULL && try_module_get(ir->p.owner)) {
+ 		++ir->open;
+ 		retval = ir->p.set_use_inc(ir->p.data);
+-		
++
+ 		if (retval != SUCCESS) {
+ 			module_put(ir->p.owner);
+ 			--ir->open;
+ 		}
+-	}
+-	else
+-	{
+-		if(ir->p.owner==NULL)
+-		{
+-			dprintk(LOGHEAD "no module owner!!!\n", ir->p.name, ir->p.minor);
+-		}
++	} else {
++		if (ir->p.owner == NULL)
++			dprintk(LOGHEAD "no module owner!!!\n",
++				ir->p.name, ir->p.minor);
++
+ 		retval = -ENODEV;
+ 	}
+ 
+@@ -586,24 +613,19 @@
+ 	struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
+ 
+ 	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)
++	if (ir->p.fops && ir->p.fops->release)
+ 		return ir->p.fops->release(inode, file);
+ 
+ 	if (down_interruptible(&plugin_lock))
+-	{
+ 		return -ERESTARTSYS;
+-	}
+ 
+ 	--ir->open;
+-	if(ir->attached)
+-	{
++	if (ir->attached) {
+ 		ir->p.set_use_dec(ir->p.data);
+ 		module_put(ir->p.owner);
+-	}
+-	else
+-	{
++	} else {
+ 		cleanup(ir);
+ 	}
+ 
+@@ -623,12 +645,11 @@
+ 	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)
++	if (ir->p.fops && ir->p.fops->poll)
+ 		return ir->p.fops->poll(file, wait);
+ 
+ 	down(&ir->buffer_sem);
+-	if(!ir->attached)
+-	{
++	if (!ir->attached) {
+ 		up(&ir->buffer_sem);
+ 		return POLLERR;
+ 	}
+@@ -636,11 +657,11 @@
+ 	poll_wait(file, &ir->buf->wait_poll, wait);
+ 
+ 	dprintk(LOGHEAD "poll result = %s\n",
+-		ir->p.name, ir->p.minor, 
++		ir->p.name, ir->p.minor,
+ 		lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM");
+ 
+ 	ret = lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM);
+-	
++
+ 	up(&ir->buffer_sem);
+ 	return ret;
+ }
+@@ -649,7 +670,7 @@
+  *
+  */
+ static int irctl_ioctl(struct inode *inode, struct file *file,
+-                       unsigned int cmd, unsigned long arg)
++		       unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned long mode;
+ 	int result;
+@@ -659,7 +680,7 @@
+ 		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)
++	if (ir->p.fops && ir->p.fops->ioctl)
+ 		return ir->p.fops->ioctl(inode, file, cmd, arg);
+ 
+ 	if (ir->p.minor == NOPLUG || !ir->attached) {
+@@ -669,7 +690,7 @@
+ 	}
+ 
+ 	/* Give the plugin a chance to handle the ioctl */
+-	if(ir->p.ioctl){
++	if (ir->p.ioctl) {
+ 		result = ir->p.ioctl(inode, file, cmd, arg);
+ 		if (result != -ENOIOCTLCMD)
+ 			return result;
+@@ -677,33 +698,32 @@
+ 	/* The plugin can't handle cmd */
+ 	result = SUCCESS;
+ 
+-	switch(cmd)
+-	{
++	switch (cmd) {
+ 	case LIRC_GET_FEATURES:
+-		result = put_user(ir->p.features, (unsigned long*)arg);
++		result = put_user(ir->p.features, (unsigned long *)arg);
+ 		break;
+ 	case LIRC_GET_REC_MODE:
+-		if(!(ir->p.features&LIRC_CAN_REC_MASK))
+-			return(-ENOSYS);
+-		
++		if (!(ir->p.features&LIRC_CAN_REC_MASK))
++			return -ENOSYS;
++
+ 		result = put_user(LIRC_REC2MODE
+ 				  (ir->p.features&LIRC_CAN_REC_MASK),
+-				  (unsigned long*)arg);
++				  (unsigned long *)arg);
+ 		break;
+ 	case LIRC_SET_REC_MODE:
+-		if(!(ir->p.features&LIRC_CAN_REC_MASK))
+-			return(-ENOSYS);
++		if (!(ir->p.features&LIRC_CAN_REC_MASK))
++			return -ENOSYS;
+ 
+-		result = get_user(mode, (unsigned long*)arg);
+-		if(!result && !(LIRC_MODE2REC(mode) & ir->p.features)) {
++		result = get_user(mode, (unsigned long *)arg);
++		if (!result && !(LIRC_MODE2REC(mode) & ir->p.features))
+ 			result = -EINVAL;
+-		}
+-		/* FIXME: We should actually set the mode somehow 
+-		 * but for now, lirc_serial doesn't support mode changin
+-		 * eighter */
++		/*
++		 * FIXME: We should actually set the mode somehow but
++		 * for now, lirc_serial doesn't support mode changing either
++		 */
+ 		break;
+ 	case LIRC_GET_LENGTH:
+-		result = put_user((unsigned long)ir->p.code_length, 
++		result = put_user((unsigned long)ir->p.code_length,
+ 				  (unsigned long *)arg);
+ 		break;
+ 	default:
+@@ -720,27 +740,24 @@
+  *
+  */
+ static ssize_t irctl_read(struct file *file,
+-			  char *buffer,   
+-			  size_t length, 
+-			  loff_t *ppos)     
++			  char *buffer,
++			  size_t length,
++			  loff_t *ppos)
+ {
+ 	struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
+ 	unsigned char buf[ir->buf->chunk_size];
+-	int ret=0, written=0;
++	int ret = 0, written = 0;
+ 	DECLARE_WAITQUEUE(wait, current);
+ 
+ 	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)
++	if (ir->p.fops && ir->p.fops->read)
+ 		return ir->p.fops->read(file, buffer, length, ppos);
+ 
+-	if(down_interruptible(&ir->buffer_sem))
+-	{
++	if (down_interruptible(&ir->buffer_sem))
+ 		return -ERESTARTSYS;
+-	}
+-	if(!ir->attached)
+-	{
++	if (!ir->attached) {
+ 		up(&ir->buffer_sem);
+ 		return -ENODEV;
+ 	}
+@@ -752,23 +769,26 @@
+ 		return -EINVAL;
+ 	}
+ 
+-	/* we add ourselves to the task queue before buffer check 
+-         * to avoid losing scan code (in case when queue is awaken somewhere 
++	/*
++	 * we add ourselves to the task queue before buffer check
++	 * to avoid losing scan code (in case when queue is awaken somewhere
+ 	 * beetwen while condition checking and scheduling)
+ 	 */
+ 	add_wait_queue(&ir->buf->wait_poll, &wait);
+ 	set_current_state(TASK_INTERRUPTIBLE);
+ 
+-	/* while we did't provide 'length' bytes, device is opened in blocking
++	/*
++	 * while we did't provide 'length' bytes, device is opened in blocking
+ 	 * mode and 'copy_to_user' is happy, wait for data.
+ 	 */
+-	while (written < length && ret == 0) { 
++	while (written < length && ret == 0) {
+ 		if (lirc_buffer_empty(ir->buf)) {
+ 			/* According to the read(2) man page, 'written' can be
+ 			 * returned as less than 'length', instead of blocking
+ 			 * again, returning -EWOULDBLOCK, or returning
+ 			 * -ERESTARTSYS */
+-			if (written) break;
++			if (written)
++				break;
+ 			if (file->f_flags & O_NONBLOCK) {
+ 				ret = -EWOULDBLOCK;
+ 				break;
+@@ -779,8 +799,7 @@
+ 			}
+ 			schedule();
+ 			set_current_state(TASK_INTERRUPTIBLE);
+-			if(!ir->attached)
+-			{
++			if (!ir->attached) {
+ 				ret = -ENODEV;
+ 				break;
+ 			}
+@@ -795,7 +814,7 @@
+ 	remove_wait_queue(&ir->buf->wait_poll, &wait);
+ 	set_current_state(TASK_RUNNING);
+ 	up(&ir->buffer_sem);
+-	
++
+ 	dprintk(LOGHEAD "read result = %s (%d)\n",
+ 		ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret);
+ 
+@@ -805,87 +824,78 @@
+ 
+ void *lirc_get_pdata(struct file *file)
+ {
+-	void *data=NULL;
++	void *data = NULL;
+ 
+ 	if (file && file->f_dentry && file->f_dentry->d_inode &&
+-	    file->f_dentry->d_inode->i_rdev )
+-	{
+-		struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
+-		data=ir->p.data;
++	    file->f_dentry->d_inode->i_rdev) {
++		struct irctl *ir;
++		ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
++		data = ir->p.data;
+ 	}
+ 
+ 	return data;
+ }
++EXPORT_SYMBOL(lirc_get_pdata);
+ 
+ 
+ static ssize_t irctl_write(struct file *file, const char *buffer,
+-			   size_t length, loff_t * ppos)
++			   size_t length, loff_t *ppos)
+ {
+ 	struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
+ 
+ 	dprintk(LOGHEAD "write 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)
++	if (ir->p.fops && ir->p.fops->write)
+ 		return ir->p.fops->write(file, buffer, length, ppos);
+ 
+-	if(!ir->attached)
+-	{
++	if (!ir->attached)
+ 		return -ENODEV;
+-	}
+ 
+ 	return -EINVAL;
+ }
+ 
+ 
+ static struct file_operations fops = {
+-	read:    irctl_read, 
+-	write:   irctl_write,
+-	poll:    irctl_poll,
+-	ioctl:   irctl_ioctl,
+-	open:    irctl_open,
+-	release: irctl_close
++	.read		= irctl_read,
++	.write		= irctl_write,
++	.poll		= irctl_poll,
++	.ioctl		= irctl_ioctl,
++	.open		= irctl_open,
++	.release	= irctl_close
+ };
+ 
+ 
+-EXPORT_SYMBOL(lirc_get_pdata);
+-EXPORT_SYMBOL(lirc_register_plugin);
+-EXPORT_SYMBOL(lirc_unregister_plugin);
+-
+-/*
+- *
+- */
+ static int lirc_dev_init(void)
+-{  	
++{
+ 	int i;
+ 
+-	for (i=0; i < MAX_IRCTL_DEVICES; ++i) {
+-		init_irctl(&irctls[i]);	
+-	}
++	for (i = 0; i < MAX_IRCTL_DEVICES; ++i)
++		init_irctl(&irctls[i]);
+ 
+-	if(register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) {
++	if (register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) {
+ 		printk(KERN_ERR "lirc_dev: register_chrdev failed\n");
+ 		goto out;
+ 	}
+ 
+ 	lirc_class = class_create(THIS_MODULE, "lirc");
+-	if(IS_ERR(lirc_class)) {
++	if (IS_ERR(lirc_class)) {
+ 		printk(KERN_ERR "lirc_dev: class_create failed\n");
+ 		goto out_unregister;
+ 	}
+ 
+-	printk("lirc_dev: IR Remote Control driver registered, at major %d \n", 
+-	       IRCTL_DEV_MAJOR);
++	printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, "
++	       "major %d \n", IRCTL_DEV_MAJOR);
+ 
+ 	return SUCCESS;
+ 
+ out_unregister:
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
++	if (unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME))
++		printk(KERN_ERR "lirc_dev: unregister_chrdev failed!\n");
++#else
+ 	/* unregister_chrdev returns void now */
+ 	unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
+-#else
+-	if(unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME))
+-		printk(KERN_ERR "lirc_dev: unregister_chrdev failed!\n");
+ #endif
+ out:
+ 	return -1;
+@@ -910,20 +920,22 @@
+  */
+ void cleanup_module(void)
+ {
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+-	/* unregister_chrdev returns void now */
+-	unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
+-	class_destroy(lirc_class);
+-#else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+ 	int ret;
+ 
+ 	ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
+ 	class_destroy(lirc_class);
+ 
+-	if(ret)
+-		printk("lirc_dev: error in module_unregister_chrdev: %d\n", ret);
++	if (ret)
++		printk(KERN_ERR "lirc_dev: error in "
++		       "module_unregister_chrdev: %d\n", ret);
+ 	else
+ 		dprintk("lirc_dev: module successfully unloaded\n");
++#else
++	/* unregister_chrdev returns void now */
++	unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
++	class_destroy(lirc_class);
++	dprintk("lirc_dev: module unloaded\n");
+ #endif
+ }
+ 
+
+--- lirc-0.8.2/drivers/lirc_dev/lirc_dev.h	2007/09/27 19:47:20	1.20
++++ lirc-0.8.2/drivers/lirc_dev/lirc_dev.h	2008/01/13 10:45:02	1.22
+@@ -14,18 +14,17 @@
+ #define MAX_IRCTL_DEVICES 4
+ #define BUFLEN            16
+ 
+-//#define LIRC_BUFF_POWER_OF_2
++/* #define LIRC_BUFF_POWER_OF_2 */
+ #ifdef LIRC_BUFF_POWER_OF_2
+-#define mod(n, div) ((n) & ((div) -1))
++#define mod(n, div) ((n) & ((div) - 1))
+ #else
+ #define mod(n, div) ((n) % (div))
+ #endif
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ 
+-struct lirc_buffer
+-{
+-        wait_queue_head_t wait_poll;
++struct lirc_buffer {
++	wait_queue_head_t wait_poll;
+ 	spinlock_t lock;
+ 
+ 	unsigned char *data;
+@@ -33,12 +32,14 @@
+ 	unsigned int size; /* in chunks */
+ 	unsigned int fill; /* in chunks */
+ 	int head, tail;    /* in chunks */
+-	/* Using chunks instead of bytes pretends to simplify boundary checking 
++	/* Using chunks instead of bytes pretends to simplify boundary checking
+ 	 * And should allow for some performance fine tunning later */
+ };
+ static inline void _lirc_buffer_clear(struct lirc_buffer *buf)
+ {
+-	buf->head = buf->tail = buf->fill = 0;
++	buf->head = 0;
++	buf->tail = 0;
++	buf->fill = 0;
+ }
+ static inline int lirc_buffer_init(struct lirc_buffer *buf,
+ 				    unsigned int chunk_size,
+@@ -61,7 +62,9 @@
+ {
+ 	kfree(buf->data);
+ 	buf->data = NULL;
+-	buf->head = buf->tail = buf->fill = 0;
++	buf->head = 0;
++	buf->tail = 0;
++	buf->fill = 0;
+ 	buf->chunk_size = 0;
+ 	buf->size = 0;
+ }
+@@ -77,11 +80,13 @@
+ {
+     return (buf->size - buf->fill);
+ }
+-static inline void lirc_buffer_lock(struct lirc_buffer *buf, unsigned long *flags)
++static inline void lirc_buffer_lock(struct lirc_buffer *buf,
++				    unsigned long *flags)
+ {
+ 	spin_lock_irqsave(&buf->lock, *flags);
+ }
+-static inline void lirc_buffer_unlock(struct lirc_buffer *buf, unsigned long *flags)
++static inline void lirc_buffer_unlock(struct lirc_buffer *buf,
++				      unsigned long *flags)
+ {
+ 	spin_unlock_irqrestore(&buf->lock, *flags);
+ }
+@@ -135,49 +140,48 @@
+ 	lirc_buffer_unlock(buf, &flags);
+ }
+ static inline void _lirc_buffer_write_n(struct lirc_buffer *buf,
+-					unsigned char* orig, int count)
++					unsigned char *orig, int count)
+ {
+-	memcpy(&buf->data[buf->tail*buf->chunk_size], orig,
+-	       count*buf->chunk_size);
+-	buf->tail = mod(buf->tail+count, buf->size);
++	memcpy(&buf->data[buf->tail * buf->chunk_size], orig,
++	       count * buf->chunk_size);
++	buf->tail = mod(buf->tail + count, buf->size);
+ 	buf->fill += count;
+ }
+ static inline void lirc_buffer_write_n(struct lirc_buffer *buf,
+-				       unsigned char* orig, int count)
++				       unsigned char *orig, int count)
+ {
+ 	unsigned long flags;
+ 	int space1;
+-	lirc_buffer_lock(buf,&flags);
+-	if( buf->head > buf->tail ) space1 = buf->head - buf->tail;
+-	else space1 = buf->size - buf->tail;
+-	
+-	if( count > space1 )
+-	{
++
++	lirc_buffer_lock(buf, &flags);
++	if (buf->head > buf->tail)
++		space1 = buf->head - buf->tail;
++	else
++		space1 = buf->size - buf->tail;
++
++	if (count > space1) {
+ 		_lirc_buffer_write_n(buf, orig, space1);
+ 		_lirc_buffer_write_n(buf, orig+(space1*buf->chunk_size),
+ 				     count-space1);
+-	}
+-	else
+-	{
++	} else {
+ 		_lirc_buffer_write_n(buf, orig, count);
+ 	}
+ 	lirc_buffer_unlock(buf, &flags);
+ }
+ 
+-struct lirc_plugin
+-{
++struct lirc_plugin {
+ 	char name[40];
+ 	int minor;
+ 	int code_length;
+ 	int sample_rate;
+ 	unsigned long features;
+-	void* data;
+-	int (*add_to_buf) (void* data, struct lirc_buffer* buf);
+-	wait_queue_head_t* (*get_queue) (void* data);
++	void *data;
++	int (*add_to_buf) (void *data, struct lirc_buffer *buf);
++	wait_queue_head_t* (*get_queue) (void *data);
+ 	struct lirc_buffer *rbuf;
+-	int (*set_use_inc) (void* data);
+-	void (*set_use_dec) (void* data);
+-	int (*ioctl) (struct inode *,struct file *,unsigned int,
++	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;
+ 	struct device *dev;
+@@ -188,7 +192,7 @@
+  *
+  * minor:
+  * indicates minor device (/dev/lirc) number for registered plugin
+- * if caller fills it with negative value, then the first free minor 
++ * if caller fills it with negative value, then the first free minor
+  * number will be used (if available)
+  *
+  * code_length:
+@@ -233,7 +237,7 @@
+  *
+  * fops:
+  * file_operations for drivers which don't fit the current plugin model.
+- * 
++ *
+  * owner:
+  * the module owning this struct
+  *
+@@ -242,7 +246,7 @@
+ 
+ /* following functions can be called ONLY from user context
+  *
+- * returns negative value on error or minor number 
++ * returns negative value on error or minor number
+  * of the registered device if success
+  * contens of the structure pointed by p is copied
+  */
+
+--- lirc-0.8.2/drivers/lirc_serial/lirc_serial.c	2007/11/08 21:27:30	5.86
++++ lirc-0.8.2/drivers/lirc_serial/lirc_serial.c	2007/12/15 17:28:01	5.87
+@@ -965,7 +965,7 @@
+ 	do_gettimeofday(&lasttv);
+ 
+ 	result=request_irq(irq,irq_handler,
+-			   SA_INTERRUPT | (share_irq ? SA_SHIRQ:0),
++			   IRQF_DISABLED | (share_irq ? IRQF_SHARED:0),
+ 			   LIRC_DRIVER_NAME,(void *)&hardware);
+ 	
+ 	switch(result)
+--- lirc-0.8.2/drivers/lirc_sir/lirc_sir.c	2007/09/27 19:47:23	1.47
++++ lirc-0.8.2/drivers/lirc_sir/lirc_sir.c	2007/12/15 17:28:01	1.48
+@@ -1025,7 +1025,7 @@
+ 		return -EBUSY;
+ 	}
+ #endif
+-	retval = request_irq(irq, sir_interrupt, SA_INTERRUPT,
++	retval = request_irq(irq, sir_interrupt, IRQF_DISABLED,
+ 			     LIRC_DRIVER_NAME, NULL);
+ 	if (retval < 0) {
+ #
+               ifndef LIRC_ON_SA1100
\ No newline at end of file
Index: extra/system/lirc/lirc.install
diff -u extra/system/lirc/lirc.install:1.17 extra/system/lirc/lirc.install:1.18
--- extra/system/lirc/lirc.install:1.17	Sat Oct 13 11:35:19 2007
+++ extra/system/lirc/lirc.install	Fri Jan 25 12:43:12 2008
@@ -10,7 +10,7 @@
 post_install() {
   # updating module dependencies
   echo ">>> Updating module dependencies. Please wait ..."
-  KERNEL_VERSION=2.6.23-ARCH
+  KERNEL_VERSION=2.6.24-ARCH
   depmod -v $KERNEL_VERSION > /dev/null 2>&1
   /bin/true
 }
@@ -26,7 +26,7 @@
 post_upgrade() {
   # updating module dependencies
   echo ">>> Updating module dependencies. Please wait ..."
-  KERNEL_VERSION=2.6.23-ARCH
+  KERNEL_VERSION=2.6.24-ARCH
   depmod -v $KERNEL_VERSION > /dev/null 2>&1
   /bin/true
 }
@@ -40,7 +40,7 @@
 post_remove() {
   # updating module dependencies
   echo ">>> Updating module dependencies. Please wait ..."
-  KERNEL_VERSION=2.6.23-ARCH
+  KERNEL_VERSION=2.6.24-ARCH
   depmod -v $KERNEL_VERSION > /dev/null 2>&1
   /bin/true
 }




More information about the arch-commits mailing list