From 525ff794ffbaa59414fdd94c9aa4dcfc6625fa2a Mon Sep 17 00:00:00 2001
From: Cecil Hugh Watson <knoppmyth@gmail.com>
Date: Sat, 4 Sep 2010 17:00:50 -0700
Subject: lirc_085:lirc package w/ pvr 150 support.

---
 abs/core-testing/lirc_085-utils/PKGBUILD           |   72 +
 abs/core-testing/lirc_085-utils/hw_commandir.c     | 1926 ++++++++++++++++++++
 abs/core-testing/lirc_085-utils/hw_commandir.h     |  175 ++
 .../lirc_085-utils/kernel-2.6.26.patch             |  122 ++
 abs/core-testing/lirc_085-utils/lirc.logrotate     |    8 +
 abs/core-testing/lirc_085-utils/lirc_atiusb.patch  |   27 +
 abs/core-testing/lirc_085-utils/lircd              |   43 +
 abs/core-testing/lirc_085-utils/lircd.conf.d       |    8 +
 abs/core-testing/lirc_085-utils/lircmd             |   36 +
 abs/core-testing/lirc_085/PKGBUILD                 |   86 +
 abs/core-testing/lirc_085/dvicoIR.rules            |   15 +
 abs/core-testing/lirc_085/hw_commandir.c           | 1926 ++++++++++++++++++++
 abs/core-testing/lirc_085/hw_commandir.h           |  175 ++
 abs/core-testing/lirc_085/kernel-2.6.26.patch      |  122 ++
 abs/core-testing/lirc_085/kernel-2.6.27.patch      |   78 +
 abs/core-testing/lirc_085/lirc.fdi                 |   11 +
 abs/core-testing/lirc_085/lirc.install             |   50 +
 abs/core-testing/lirc_085/lirc_atiusb.patch        |   27 +
 abs/core-testing/lirc_085/lirc_mod_mce.patch       |  187 ++
 19 files changed, 5094 insertions(+)
 create mode 100644 abs/core-testing/lirc_085-utils/PKGBUILD
 create mode 100755 abs/core-testing/lirc_085-utils/hw_commandir.c
 create mode 100755 abs/core-testing/lirc_085-utils/hw_commandir.h
 create mode 100644 abs/core-testing/lirc_085-utils/kernel-2.6.26.patch
 create mode 100644 abs/core-testing/lirc_085-utils/lirc.logrotate
 create mode 100644 abs/core-testing/lirc_085-utils/lirc_atiusb.patch
 create mode 100755 abs/core-testing/lirc_085-utils/lircd
 create mode 100644 abs/core-testing/lirc_085-utils/lircd.conf.d
 create mode 100755 abs/core-testing/lirc_085-utils/lircmd
 create mode 100644 abs/core-testing/lirc_085/PKGBUILD
 create mode 100644 abs/core-testing/lirc_085/dvicoIR.rules
 create mode 100755 abs/core-testing/lirc_085/hw_commandir.c
 create mode 100755 abs/core-testing/lirc_085/hw_commandir.h
 create mode 100644 abs/core-testing/lirc_085/kernel-2.6.26.patch
 create mode 100644 abs/core-testing/lirc_085/kernel-2.6.27.patch
 create mode 100644 abs/core-testing/lirc_085/lirc.fdi
 create mode 100644 abs/core-testing/lirc_085/lirc.install
 create mode 100644 abs/core-testing/lirc_085/lirc_atiusb.patch
 create mode 100644 abs/core-testing/lirc_085/lirc_mod_mce.patch

diff --git a/abs/core-testing/lirc_085-utils/PKGBUILD b/abs/core-testing/lirc_085-utils/PKGBUILD
new file mode 100644
index 0000000..c4d5759
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/PKGBUILD
@@ -0,0 +1,72 @@
+# $Id: PKGBUILD 6058 2008-07-23 02:50:00Z eric $
+# Maintainer: Paul Mattal <paul@archlinux.org>
+
+pkgname=lirc-utils
+pkgver=0.8.5CVS
+pkgrel=7
+pkgdesc="Linux Infrared Remote Control utils"
+arch=(i686 x86_64)
+url="http://www.lirc.org/"
+license=('GPL')
+_kernver=2.6.28-LinHES
+depends=('alsa-lib' 'libusb' 'libx11' 'libsm' 'iguanaIR')
+#makedepends=('help2man')
+replaces=('lirc+pctv')
+backup=('etc/lircd.conf' 'etc/lircmd.conf'\
+        'etc/conf.d/lircd')
+options=('!libtool' '!makeflags')
+source=(http://www.blushingpenguin.com/mark/lmilk/lirc-0.8.5-CVS-pvr150.tar.bz2 \
+	lircd lircmd lirc.logrotate lircd.conf.d \
+	kernel-2.6.26.patch lirc_atiusb.patch
+	hw_commandir.c 
+	hw_commandir.h) 
+md5sums=('b96dae91b566143b3af433fa2714ec9a' '909ad968afa10e4511e1da277bb23c3b'\
+         '85f7fdac55e5256967241864049bf5e9' '3deb02604b37811d41816e9b4385fcc3'\
+         '5b1f8c9cd788a39a6283f93302ce5c6e' '1753acd774f50b638e6173d364de53fd'\
+	 '7eccd7826ab99e5cf1b9154171c8b927')
+
+build() {
+	# configure
+	cd $startdir/src/lirc-0.8.5-CVS-pvr150 || return 1
+	cp $startdir/src/hw_commandir.* $startdir/src/lirc-0.8.5-CVS-pvr150/daemons
+#	patch -Np1 -i ../kernel-2.6.26.patch || return 1
+	patch -Np1 -i ../lirc_atiusb.patch || return 1
+
+      # Disabling lirc_gpio driver as it does no longer work Kernel 2.6.22+
+	sed -i -e "s:lirc_gpio\.o::" drivers/lirc_gpio/Makefile.am || return 1
+
+	autoreconf || return 1
+	libtoolize || return 1
+
+	./configure --enable-sandboxed --prefix=/usr \
+	--with-driver=all --with-kerneldir=/usr/src/linux-${_kernver} \
+	--with-moduledir=/lib/modules/${_kernver}/kernel/drivers/misc \
+	--with-transmitter \
+		|| return 1
+	# disable parallel and bt829
+        # because of incompatibility with smp systems
+        sed -i -e "s:lirc_parallel::" -e "s:lirc_bt829::" \
+		Makefile drivers/Makefile drivers/*/Makefile tools/Makefile \
+                || return 1
+
+  	# build
+	make || return 1
+	make DESTDIR=$startdir/pkg install || return 1
+	mkdir -p $startdir/pkg/usr/share/lirc $startdir/pkg/etc/rc.d \
+		|| return 1
+	cp $startdir/src/{lircd,lircmd} $startdir/pkg/etc/rc.d/ \
+		|| return 1
+	cp -rp remotes $startdir/pkg/usr/share/lirc || return 1
+	chmod -R go-w $startdir/pkg/usr/share/lirc/ || return 1
+
+	# install the logrotate config
+	install -D -m644 $startdir/src/lirc.logrotate \
+		$startdir/pkg/etc/logrotate.d/lirc || return 1
+	
+	# install conf.d file
+	install -D -m644 $startdir/src/lircd.conf.d \
+		$startdir/pkg/etc/conf.d/lircd || return 1
+
+	# remove built modules
+	rm -r $startdir/pkg/lib/
+}
diff --git a/abs/core-testing/lirc_085-utils/hw_commandir.c b/abs/core-testing/lirc_085-utils/hw_commandir.c
new file mode 100755
index 0000000..40ac0de
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/hw_commandir.c
@@ -0,0 +1,1926 @@
+/* CommandIR transceivers driver 0.96
+ * Supporting CommandIR II and CommandIR Mini (and multiple of both)
+ * April-June 2008, Matthew Bodkin
+ * December 2008, bug fixes, Matthew Bodkin
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+
+#include "hardware.h"
+#include "ir_remote.h"
+#include "lircd.h"
+#include "receive.h"
+#include "transmit.h"
+#include "hw_commandir.h"
+#include <usb.h>
+
+#define RAPID_DECODE 1
+
+extern struct ir_remote *repeat_remote;
+extern char *progname;
+
+
+/**********************************************************************
+ *
+ * internal function prototypes
+ *
+ **********************************************************************/
+static int commandir_init();
+static int commandir_deinit(void);
+static char *commandir_rec(struct ir_remote *remotes);
+static void commandir_read_loop();
+static int cmdir_convert_RX(unsigned char *orig_rxbuffer);
+static unsigned int get_time_value(unsigned int firstint, 
+		unsigned int secondint, unsigned char overflow);
+static lirc_t commandir_readdata(lirc_t timeout);
+static int commandir_send(struct ir_remote *remote,struct ir_ncode *code);
+static int commandir_ioctl(unsigned int cmd, void *arg);
+//static void setEmitterMask(unsigned char highbyte, unsigned char lowbyte);
+static void setEmitterMask(int bitmask);
+static void commandir_transmit(char *buffer, int bytes, int bitmask, 
+		unsigned int);
+static void commandir_child_init();
+static void shutdown_usb();
+static void hardware_scan();
+static void hardware_disconnect(int);
+static void hardware_setorder();
+static void raise_event(unsigned int);
+static int commandir_read();
+static int check_irsend_commandir(unsigned char *command);
+static int commandir_decode(char *command);
+static int commandir_receive_decode(struct ir_remote *remote,
+                   ir_code *prep,ir_code *codep,ir_code *postp,
+                   int *repeat_flagp,
+                   lirc_t *min_remaining_gapp, lirc_t *max_remaining_gapp);
+static void pipeline_check();
+static int inline get_bit(int bitnum);
+static void add_to_tx_pipeline(unsigned char *buffer, int bytes, 
+		int channel_mask, unsigned int);
+static void recalc_tx_available(int);
+static void set_hash_mask(int channel_mask);
+static int commandir2_convert_RX(unsigned short *bufferrx, 
+		unsigned char numvalues);
+static void cleanup_commandir_dev(int spotnum);
+
+/**********************************************************************
+ *
+ * CommandIR Vars
+ *
+ **********************************************************************/
+static int current_transmitter_mask = 0xff;
+static char unsigned commandir_data_buffer[512];
+static int last_mc_time = -1;	
+static int commandir_rx_num = 0;
+
+
+static char channels_en[MAX_DEVICES]; 
+static char open_bus_hash[USB_MAX_BUSES][USB_MAX_BUSDEV];
+static int tx_order[MAX_DEVICES];
+static char device_count = 0;
+static int mini_freq[MAX_DEVICES];
+static int child_pipe_write = 0;
+static char haveInited = 0;
+// Fake 'commandir' remote signal values
+static unsigned int signal_base[2][2] = { {100|PULSE_BIT, 200},
+		 {1000|PULSE_BIT, 200} };
+
+// Pipes to and from the child/parent
+static pid_t child_pid = -1;
+static int pipe_fd[2] = { -1, -1 };
+static int pipe_tochild[2] = { -1, -1 };
+static int tochild_read = -1, tochild_write = -1;
+
+struct commandir_device
+{
+	usb_dev_handle *cmdir_udev;
+	int bus;
+	int busdev;
+	int interface;
+	int location;
+	int hw_type;
+	int hw_revision;
+	int hw_subversion;
+	unsigned char devnum;
+	int endpoint_max[3];
+} open_commandir_devices[4];
+
+struct hardware hw_commandir =
+{
+	NULL,					 	/* default device */
+	-1,                 		/* fd */
+	LIRC_CAN_SET_SEND_CARRIER|
+	LIRC_CAN_SEND_PULSE|
+	LIRC_CAN_SET_TRANSMITTER_MASK|
+	LIRC_CAN_REC_MODE2, 		
+	LIRC_MODE_PULSE,			/* send_mode */ 
+	LIRC_MODE_MODE2,            /* rec_mode */
+	sizeof(lirc_t),        		/* code_length in BITS */
+	commandir_init,       		/* init_func */
+	NULL,     			  		/* config_func */
+	commandir_deinit,     		/* deinit_func */
+	commandir_send,				/* send_func */
+ 	commandir_rec,        		/* rec_func  */
+	commandir_receive_decode,   /* decode_func */
+	commandir_ioctl,            /* ioctl_func */
+	commandir_readdata,		    /* readdata */
+	"commandir"
+};
+
+/***   LIRC Interface Functions - Non-blocking parent thread
+*/
+
+static int commandir_receive_decode(struct ir_remote *remote,
+                   ir_code *prep,ir_code *codep,ir_code *postp,
+                   int *repeat_flagp,
+                   lirc_t *min_remaining_gapp, lirc_t *max_remaining_gapp) {
+
+	int i;
+	i = receive_decode(remote,
+                   prep,codep,postp,
+                   repeat_flagp,
+                   min_remaining_gapp, max_remaining_gapp);
+
+	if(i > 0){
+		static char rx_char[3] = {3, 0, RXDECODE_HEADER_LIRC};
+		write(tochild_write, rx_char, 3);	
+	}
+	
+	return i;
+}
+
+
+static int commandir_init()
+{
+	long fd_flags;
+	if(haveInited){
+		static char init_char[3] = {3, 0, INIT_HEADER_LIRC};
+		write(tochild_write, init_char, 3);	
+		return 1;
+	}
+	
+	init_rec_buffer();	// LIRC's rec
+	init_send_buffer();	// LIRC's send
+	
+	/* A separate process will be forked to read data from the USB
+	 * receiver and write it to a pipe. hw.fd is set to the readable
+	 * end of this pipe. */
+	if (pipe(pipe_fd) != 0)
+	{
+		logprintf(LOG_ERR, "couldn't open pipe 1");
+		return 0;
+	}
+	
+	hw.fd = pipe_fd[0];	// the READ end of the Pipe
+	
+	if (pipe(pipe_tochild) != 0)
+	{
+		logprintf(LOG_ERR, "couldn't open pipe 1");
+		return 0;
+	}
+	
+	tochild_read = pipe_tochild[0];	// the READ end of the Pipe 
+	tochild_write = pipe_tochild[1];	// the WRITE end of the Pipe 
+	
+	fd_flags = fcntl(pipe_tochild[0], F_GETFL);
+  	if(fcntl(pipe_tochild[0], F_SETFL, fd_flags | O_NONBLOCK) == -1)
+	{
+		logprintf(LOG_ERR, "can't set pipe to non-blocking");
+		return 0;
+	}	
+	
+	child_pid= fork();
+	if (child_pid== -1)
+	{
+		logprintf(LOG_ERR, "couldn't fork child process");
+		return 0;
+	}
+	else if (child_pid== 0)
+	{
+		child_pipe_write = pipe_fd[1];	
+		commandir_child_init();
+		commandir_read_loop();
+		return 0;	
+	}
+	haveInited = 1;
+	
+	logprintf(LOG_ERR, "CommandIR driver initialized");
+	return 1;	
+}
+
+
+static int commandir_deinit(void)
+{
+	/* Trying something a bit new with this driver. Keeping the driver
+	 * connected so in the future we can still monitor in the client */
+	if(USB_KEEP_WARM && (!strncmp(progname, "lircd", 5)))
+	{
+		static char deinit_char[3] = {3, 0, DEINIT_HEADER_LIRC};
+		write(tochild_write, deinit_char, 3);
+		logprintf(LOG_ERR, "LIRC_deinit but keeping warm");
+	}
+	else
+	{
+		if (tochild_read >= 0)
+		{
+			if (close(tochild_read) < 0) 
+			{
+				logprintf(LOG_ERR, "Error closing pipe2");;
+			}
+			tochild_read = tochild_write = -1;
+		}
+		
+		if(haveInited){
+			// shutdown all USB
+			if(child_pid > 0)
+			{
+				logprintf(LOG_ERR, "Closing child process");
+				kill(child_pid, SIGTERM);
+				waitpid(child_pid, NULL, 0);
+				child_pid = -1;
+				haveInited = 0;
+			}
+		}
+		
+		if (hw.fd >= 0)
+		{
+			if (close(hw.fd) < 0) logprintf(LOG_ERR, "Error closing pipe");
+			hw.fd = -1;
+		}
+		
+		logprintf(LOG_ERR, "commandir_deinit()");
+	}
+	return(1);
+}
+
+static int commandir_send(struct ir_remote *remote,struct ir_ncode *code)
+{
+	int length;
+	lirc_t *signals;
+
+	if(!init_send(remote,code)) {
+		return 0;
+	}
+
+	length = send_buffer.wptr;
+	signals = send_buffer.data;
+
+	if (length <= 0 || signals == NULL) {
+		return 0;
+	}
+	
+	int cmdir_cnt =0;
+	char cmdir_char[70];
+	
+	// Set the frequency of the signal along with the signal + transmitters
+	cmdir_char[0] = 7;
+	cmdir_char[1] = 0;
+
+	cmdir_char[2] = FREQ_HEADER_LIRC;
+	cmdir_char[3] = (remote->freq >> 24) & (0xff);
+	cmdir_char[4] = (remote->freq >> 16) & (0xff);
+	cmdir_char[5] = (remote->freq >> 8) & (0xff);
+	cmdir_char[6] = (remote->freq & 0xff);
+	
+	write(tochild_write, cmdir_char, cmdir_char[0]);
+
+	cmdir_cnt = 3;
+	
+	unsigned char * send_signals = malloc(sizeof(signals) * length + 4);
+	
+	send_signals[0] = (sizeof(lirc_t) * length + 4) & 0xff;
+	send_signals[1] = ((sizeof(lirc_t) * length + 4) >> 8) & 0xff;
+	
+	send_signals[2] = TX_LIRC_T;
+	send_signals[3] = (char)current_transmitter_mask;	
+	
+	memcpy(&send_signals[4], signals, sizeof(lirc_t) * length);
+	
+	if(write(tochild_write, send_signals, 
+		send_signals[0] + send_signals[1] * 256) < 0)
+	{
+		logprintf(LOG_ERR, "Error writing to child_write");
+	}
+	
+	free(send_signals);
+	return(length);
+}
+
+static char *commandir_rec(struct ir_remote *remotes)
+{
+	char * returnit;
+	if (!clear_rec_buffer()) return NULL;
+	returnit = decode_all(remotes);
+	return returnit;
+}
+
+static int commandir_ioctl(unsigned int cmd, void *arg)
+{
+	unsigned int ivalue;
+	char cmdir_char[5];
+	
+	switch(cmd)
+	{
+	case LIRC_SET_TRANSMITTER_MASK:
+		
+		ivalue=*(unsigned int*)arg;
+		
+		if(ivalue >= MAX_MASK) return (MAX_CHANNELS);
+		
+		/* Support the old way of setting the frequency of the signal along 
+		 * with the signal + transmitters */
+		cmdir_char[0] = 5;
+		cmdir_char[1] = 0;
+		cmdir_char[2] = CHANNEL_EN_MASK;
+		cmdir_char[3] = (unsigned char)(ivalue & 0x00FF);	// Low bits
+		cmdir_char[4] = (unsigned char)(ivalue >> 8);		// High bits
+		
+		write(tochild_write, cmdir_char, cmdir_char[0]);
+
+		return (0);
+		
+	default:
+		logprintf(LOG_ERR, "Unknown ioctl - %d", cmd);
+		return(-1);
+	}
+	
+	return 1;
+}
+
+static lirc_t commandir_readdata(lirc_t timeout)
+{
+	lirc_t code = 0;
+	struct timeval tv = {0, timeout};
+	fd_set fds;
+
+	FD_ZERO(&fds);
+	FD_SET(hw.fd, &fds);
+
+	/* attempt a read with a timeout using select */
+	if (select(hw.fd + 1, &fds, NULL, &fds, &tv) > 0)
+		/* if we failed to get data return 0 */
+		if (read(hw.fd, &code, sizeof(lirc_t)) <= 0)
+                        commandir_deinit();
+	return code;
+}
+
+/***  End of parent fork / LIRC accessible functions  */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***  CommandIR Client Process Functions (Handle all USB operations)
+ */
+ 
+int channels_space_available[MAX_CHANNELS]; 
+int channels_space_updated = 0; // last updated time
+
+char * signalq[MAX_SIGNALQ];	// how many signals can be queued
+int signalq_len[MAX_SIGNALQ];
+int signalq_bitmask[MAX_SIGNALQ];
+unsigned int signalq_frequency[MAX_SIGNALQ];
+
+int top_signalq = -1;
+int next_signalq_per_channel[MAX_CHANNELS];	
+
+unsigned char commandir_tx_start[MAX_CHANNELS*4];
+unsigned char commandir_tx_end[MAX_CHANNELS*4];
+unsigned char commandir_tx_available[MAX_CHANNELS];
+unsigned char lastSendSignalID[MAX_CHANNELS];
+unsigned char commandir_last_signal_id[MAX_CHANNELS];
+
+
+// Global variables to convert channel masks to consistant easier formats
+unsigned char hash_mask[MAX_CHANNELS];
+unsigned char selected_channels[MAX_CHANNELS];
+unsigned char total_selected_channels = 0;
+int shutdown_pending = 0;
+int read_delay = WAIT_BETWEEN_READS_US;
+int insert_fast_zeros = 0;
+
+int rx_hold = 0;
+
+// This is the only one for pre-pipelinging
+int pre_pipeline_emitter_mask = 0x000f; // default tx on only first CommandIR
+
+
+static void pipeline_check()
+{
+	/* Transmit from the pipeline if it's time and there's space
+	 * what's available should now be updated in the main_loop
+	 */
+	
+	int i,j,k;
+	
+	i=0;
+	if(top_signalq < 0) return;
+	
+	while(i <= top_signalq)
+	{
+
+		// Are ALL the channels this signal should TX on currently available?
+		int oktosend = 1;
+		set_hash_mask( signalq_bitmask[ i ] );
+		for(j = 0; j<total_selected_channels; j++)
+		{
+			if(commandir_tx_available[ selected_channels[j] ] < 
+				(36 + (signalq_len[ i ])/sizeof(lirc_t)))	
+			{
+				oktosend = 0;
+				break;
+			}
+		}
+		
+		if(oktosend)
+		{
+			// great, TX this on all the channels.
+			
+			commandir_transmit(signalq[ i ], signalq_len[ i ], signalq_bitmask[ i ], signalq_frequency[ i ]);
+			
+			for(j = 0; j<total_selected_channels; j++)
+			{
+				/*  commandir_tx_available[ selected_channels[j] ] -= 
+					(64 + (signalq_len[ i ])/sizeof(lirc_t));  */
+				commandir_tx_available[ selected_channels[j] ] = 0; 
+			}
+			
+			/* Free up the memory, and see if there are new next_signalq's 
+			 * (any more for this channel to TX)
+			 */
+			free(signalq[i]);
+			
+			for(k=i; k<top_signalq; k++)
+			{
+				signalq[k] = signalq[k+1];
+				signalq_len[k] = signalq_len[k+1];
+				signalq_bitmask[k] = signalq_bitmask[k+1];
+				signalq_frequency[k] = signalq_frequency[k+1];
+			}
+			top_signalq--;
+		}
+		else
+		{
+			i++;
+		}
+	}
+}
+
+static int get_bit(int bitnum)
+{
+	int r = 1;
+	return r << bitnum; // bit 0 is 1, bit 1 is 10, bit 2 is 100...
+}
+
+static void add_to_tx_pipeline(unsigned char *buffer, int bytes, 
+	int channel_mask, unsigned int frequency)
+{
+	/* *buffer points to a buffer that will be OVERWRITTEN; malloc our copy.
+	 * buffer is a LIRC_T packet for CommandIR 
+	 */
+	top_signalq++;
+	if(top_signalq > MAX_SIGNALQ)
+	{
+		logprintf(LOG_ERR, "Too many signals in queue: > %d", MAX_SIGNALQ);
+		return;
+	}
+	
+	signalq[top_signalq] = malloc(bytes);
+	
+	signalq_len[top_signalq] = bytes;
+	signalq_bitmask[top_signalq] = channel_mask;
+	signalq_frequency[top_signalq] = frequency;
+	
+	lirc_t *oldsignal, *newsignal;
+	int x, pulse_now = 1;
+	int projected_signal_length;
+	short aPCAFOM = 0;
+	float afPCAFOM = 0.0;
+	int difference = 0;
+					
+	afPCAFOM = (6000000.0 / ((frequency > 0) ? frequency : DEFAULT_FREQ)  ) ; 
+	aPCAFOM = afPCAFOM;
+	
+	// Trim off mid-modulation pulse fragments, add to space for exact signals
+	for(x=0; x<(bytes/sizeof(lirc_t)); x++)
+	{
+		oldsignal = (lirc_t *)&buffer[x*sizeof(lirc_t)];
+		newsignal = (lirc_t *)signalq[top_signalq];
+		newsignal += x;
+		
+		if(pulse_now==1){
+			projected_signal_length =  
+				(((int)( (*oldsignal * 12)/( afPCAFOM ) ))  * aPCAFOM) / 12;
+			difference = *oldsignal - projected_signal_length;
+			// take off difference plus 1 full FOM cycle
+			*newsignal = *oldsignal - difference - (aPCAFOM / 12);	
+			
+		}
+		else
+		{
+			if(difference != 0)
+			{
+				// Add anything subtracted from the pulse to the space
+				*newsignal = *oldsignal + difference + (aPCAFOM / 12);
+				difference = 0;
+			}
+		
+		}
+		
+		pulse_now++;
+		if(pulse_now > 1) pulse_now = 0;
+	}
+	
+	return;
+}
+
+static void recalc_tx_available(int which_commandir)
+{
+	int i;
+	int length = 0;
+	static int failsafe = 0;
+	
+	if(lastSendSignalID[which_commandir] != 
+		commandir_last_signal_id[which_commandir])
+	{
+		/* INNOVATIONONE_FLAG:REMOVE  This will be removed pending testing
+		 * for a future release
+		 */
+		if(failsafe++ < 1000)
+		{
+			return;
+		}
+		logprintf(LOG_ERR, "Error: required the failsafe");
+	}
+	
+	failsafe = 0;
+	for(i=which_commandir*4; i<((which_commandir+1)*4); i++)
+	{
+		length = commandir_tx_end[i] - commandir_tx_start[i];
+		if(length < 0) length += 0xff;
+		
+		if(commandir_tx_available[i] < 0xff - length)
+			commandir_tx_available[i] = 0xff - length;
+			
+	}
+}
+
+static void set_hash_mask(int channel_mask) // eg, 8
+{
+	// bitwise set of hash_mask for easier coding...
+	int i,j;
+	j=channel_mask;
+	total_selected_channels = 0;
+	for(i=0; i<MAX_CHANNELS; i++)
+	{
+		hash_mask[i] = j & 0x01;
+		j = j >> 1;
+		if(hash_mask[i])
+			selected_channels[total_selected_channels++] = i;
+	}
+}
+
+
+static void commandir_transmit(char *buffer, int bytes, int bitmask, 
+	unsigned int frequency)
+{
+	/*** Send a TX command to 1 or more CommandIRs.
+	 * Keep in mind: TX frequency, TX channels, TX signal length, 
+	 * which CommandIR, & what hardware version
+	 */
+	
+	int send_status;
+	unsigned char packet[TX_BUFFER_SIZE];
+	/* So we know where there should be gaps between signals and more 
+	 * importantly, where there shouldn't be
+	 */
+	static char signalid = 1;	
+	
+	/* Depending on the tx channels, then depending on what hardware it is, 
+	 * set the freq if needed, and send the buffer with the channel header 
+	 * that's right for that CommandIR
+	 */
+	
+	int devicenum = 0;
+	int sent = 0, tosend = 0;
+	unsigned char mini_tx_mask = 0;
+	lirc_t * signals;	// have bytes/sizeof(lirc_t) signals
+	signals = (lirc_t *)buffer;
+	int total_signals = 0;
+	int i;
+	char cmdir_char[66];
+	int which_signal = 0;
+	
+	total_signals = bytes / sizeof(lirc_t);
+	
+	setEmitterMask(bitmask);
+	
+	for(devicenum = 0; devicenum < device_count; devicenum++)
+	{
+		// Do we transmit on any channels on this device?
+		if(channels_en[ devicenum ])
+		{
+			which_signal = 0;
+			switch(open_commandir_devices[ tx_order[devicenum] ].hw_type)
+			{
+				case HW_COMMANDIR_2:
+					
+					mini_tx_mask = 0;
+					// Short enough loop to unroll
+					if(channels_en[ devicenum ] & 1) mini_tx_mask |= 0x10;
+					if(channels_en[ devicenum ] & 2) mini_tx_mask |= 0x20;
+					if(channels_en[ devicenum ] & 4) mini_tx_mask |= 0x40;
+					if(channels_en[ devicenum ] & 8) mini_tx_mask |= 0x80;
+					
+					packet[1] = TX_COMMANDIR_II;
+					packet[2] = mini_tx_mask;
+					
+					short PCAFOM = 0;
+					float fPCAFOM = 0.0;
+					
+					if(bytes/sizeof(lirc_t) > 255)
+					{
+						logprintf(LOG_ERR, "Error: signal over max size");
+						continue; 
+					}
+					
+					fPCAFOM = (6000000 / ((frequency > 0) ? frequency : 
+						DEFAULT_FREQ)  ) ; 
+					PCAFOM = fPCAFOM;
+					
+					lastSendSignalID[  tx_order[devicenum]   ] = packet[5] = (getpid() + signalid++) + 1;	
+					
+					packet[4] = PCAFOM & 0xff;
+					packet[3] = (PCAFOM >> 8) & 0xff;					
+					
+					short packlets_to_send = 0, sending_this_time = 0;
+					
+					packlets_to_send = bytes / sizeof(lirc_t);
+					
+					int attempts;
+					for(attempts = 0; attempts < 10; attempts++)
+					{
+					
+						if((packlets_to_send*3 + 7) > open_commandir_devices[ tx_order[devicenum] ].endpoint_max[1])
+						{
+							sending_this_time = open_commandir_devices[ tx_order[devicenum] ].endpoint_max[1]/3 - 3;
+						}
+						else
+						{
+							sending_this_time = packlets_to_send;
+						}
+						int sending;
+
+						for(i=0; i<sending_this_time; i++)
+						{
+							sending = signals[which_signal++];
+							
+							packet[i*3+7] = sending >> 8; // high1
+							packet[i*3+8] = sending & 0xff; // low
+							packet[i*3+9] = sending >> 16 & 0xff; // high2
+						}
+						
+						packet[0] = (sending_this_time * 3 + 7);
+						packet[6] = (sending_this_time == packlets_to_send)  ? 0xcb :  0x00;
+						
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							(char*)packet,
+							packet[0], 
+							USB_TIMEOUT_MS);
+						if(send_status < 0)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return;
+						}
+						
+						packlets_to_send -= ((send_status - 7) / 3);
+						if(!packlets_to_send)
+						{
+							// "No more packlets to send\n"
+							break;
+						}
+					}
+					continue; // for transmitting on next CommandIR device
+					
+			
+				case HW_COMMANDIR_MINI:
+					mini_tx_mask = 0;
+					if(channels_en[ devicenum ] & 1) mini_tx_mask |= 0x80;
+					if(channels_en[ devicenum ] & 2) mini_tx_mask |= 0x40;
+					if(channels_en[ devicenum ] & 4) mini_tx_mask |= 0x20;
+					if(channels_en[ devicenum ] & 8) mini_tx_mask |= 0x10;
+					
+					char freqPulseWidth = DEFAULT_PULSE_WIDTH;
+					
+					freqPulseWidth = (unsigned char)((1000000 / 
+						((frequency > 0) ? frequency: DEFAULT_FREQ)  ) / 2);
+					
+					if(freqPulseWidth == 0)
+					{
+						freqPulseWidth = DEFAULT_PULSE_WIDTH;
+					}
+					
+					if(mini_freq[ tx_order[devicenum] ] != freqPulseWidth)
+					{
+						// Update the CommandIR Mini's next tx frequency
+						cmdir_char[0] = FREQ_HEADER;
+						cmdir_char[1] = freqPulseWidth;
+						cmdir_char[2] = 0;
+						mini_freq[ tx_order[devicenum] ] = freqPulseWidth;
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							cmdir_char,
+							2, // 2 bytes
+							USB_TIMEOUT_MS);
+						if(send_status < 2)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return ;
+						}
+ 					}
+					
+					unsigned int mod_signal_length=0;
+					
+					cmdir_char[0] = TX_HEADER_NEW;
+ 					cmdir_char[1] = mini_tx_mask;
+					
+					unsigned int hibyte, lobyte;
+
+					sent = 0;
+					which_signal = 0;
+					while(sent < (bytes / sizeof(lirc_t) * 2 ) )
+					{
+ 						tosend = (bytes / sizeof(lirc_t) * 2 ) - sent;
+						
+						if(tosend > (MAX_HW_MINI_PACKET - 2))
+						{
+							tosend = MAX_HW_MINI_PACKET - 2;
+						}
+						
+						for(i=0;i<(tosend/2);i++) // 2 bytes per CommandIR pkt
+						{
+							mod_signal_length = signals[which_signal++] >> 3;
+							hibyte = mod_signal_length/256;
+							lobyte = mod_signal_length%256;
+							cmdir_char[i*2+3] = lobyte;
+							cmdir_char[i*2+2] = hibyte;
+						}
+
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							cmdir_char,
+							tosend + 2, 
+							USB_TIMEOUT_MS);
+						if(send_status < 1)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return;
+						}
+						sent += tosend;
+					} // while unsent data
+					continue; // for transmitting on next CommandIR device
+				default:
+					logprintf(LOG_ERR, "Unknown hardware: %d", 
+						open_commandir_devices[tx_order[devicenum]].hw_type);
+			} // hardware switch()
+		} // if we should tx on this device
+	} // for each device we have
+}
+
+
+static void commandir_child_init()
+{
+	alarm(0);
+	signal(SIGTERM, shutdown_usb);
+	signal(SIGPIPE, SIG_DFL);
+	signal(SIGINT, shutdown_usb);
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGALRM, SIG_IGN);
+	
+	logprintf(LOG_ERR, "Child Initializing CommandIR Hardware");
+	
+	usb_init();
+	int i;
+	for(i=0;i<MAX_CHANNELS;i++)
+	{
+		next_signalq_per_channel[i] = -1;
+		channels_en[i] = 0xff;
+	}
+/*	
+	// Check kernel version: support fast decoding
+	char checkV[] = {0,0,0,0,0,0,0,0,0,0};
+	FILE * checkfile;
+	int kernel_major = 0, kernel_minor = 0;
+	
+	checkfile=fopen("/proc/sys/kernel/osrelease", "r");
+	if(checkfile!=NULL)
+	{
+		fgets(checkV, 7, checkfile);
+		printf("Checking: %s.\n", checkV);
+		printf("Version checking %s.\n", &checkV[4]);
+		kernel_major = atoi(&checkV[2]);
+		kernel_minor = atoi(&checkV[4]);
+		printf("Major is: %d, minor is %d.\n", kernel_major, kernel_minor);
+		fclose(checkfile);
+	}
+	
+	if(kernel_major < 6){
+		insert_fast_zeros = 0;
+		logprintf(LOG_ERR, "Fast decoding disabled");
+	}
+	else
+	{
+		if(kernel_minor <= 24)
+		{
+			logprintf(LOG_ERR, "Fast decoding enabled (1)");
+			insert_fast_zeros = 1;
+		}
+		else
+		{
+			logprintf(LOG_ERR, "Fast decoding enabled");
+			insert_fast_zeros = 2;
+		}
+	}*/
+	hardware_scan();
+}
+
+static void hardware_disconnect(int commandir_spot)
+{
+	/* We had a read/write error, try disconnecting it and force _scan to 
+	 * reconnect - otherwise we may get perpetual read/write errors
+	 */
+	
+	int x;
+	
+	//	reset the hash so we don't try and disconnect this device again
+	//  device_count is decremented here
+	cleanup_commandir_dev(commandir_spot);
+	
+	raise_event(COMMANDIR_UNPLUG_1 + commandir_spot);
+	
+	/* Cases are:
+	removing device 0 when there's no more device (do nothing)
+	removing device < MAX when there's still 1+ devices (patch up)
+	removing device==MAX when there's more devices (do nothing)
+	*/
+	
+	// new device count-- from cleanup (if device_count > 0 AND commandir removed isn't 0 or max)
+	if( (device_count > 0) && (commandir_spot != device_count) )
+	{
+		/* It wasn't the top device removed, and there's 
+			* more than 1 device, so we have some vars to patch up
+			*/
+		for(x=commandir_spot; x<(device_count); x++)
+		{
+			channels_en[x] = channels_en[x+1];
+			mini_freq[x] = mini_freq[x+1];
+			commandir_last_signal_id[x] = commandir_last_signal_id[x+1];
+			lastSendSignalID[x] = lastSendSignalID[x+1];
+			memcpy(&open_commandir_devices[x], 
+				&open_commandir_devices[x+1], 
+				sizeof(struct commandir_device));	
+		}
+	
+	// Reset the TOP one that was just removed:
+		channels_en[(int)device_count] = 0x0f;
+		mini_freq[(int)device_count] = -1;
+		commandir_last_signal_id[(int)device_count] = 0;
+		lastSendSignalID[(int)device_count] = 0;
+		open_commandir_devices[(int)device_count].cmdir_udev = 0;
+		open_commandir_devices[(int)device_count].bus = 0;
+		open_commandir_devices[(int)device_count].busdev = 0;
+		open_commandir_devices[(int)device_count].interface = 0; 
+		open_commandir_devices[(int)device_count].hw_type = 0;
+		open_commandir_devices[(int)device_count].hw_revision = 0;
+		open_commandir_devices[(int)device_count].hw_subversion = 0;
+		
+	}
+	
+	if(commandir_rx_num>=commandir_spot)
+	{
+		commandir_rx_num--;	
+	}
+
+	hardware_setorder();
+}
+
+static void hardware_setorder(){
+	/* Tried to order to the detected CommandIRs based on bus and dev ids
+		* so they remain the same on reboot.  Adding a new device in front
+		* will mean it becomes device 0 and emitters or scripts must be fixed
+		* Need a different param, these still change. 
+		*/
+		
+	tx_order[0] = tx_order[1] = tx_order[2] = tx_order[3] = 0; 
+	mini_freq[0] = mini_freq[1] = mini_freq[2] = mini_freq[3] = -1;
+	int largest = 0;
+	int tmpvals[4];
+	int x, tx_spots, find_spot;
+	
+	for(x=0; x<device_count; x++)
+	{
+		tmpvals[x] = 256 * open_commandir_devices[x].bus + 
+			open_commandir_devices[x].busdev;
+	}
+	
+	for(tx_spots = 0; tx_spots < device_count; tx_spots++)
+	{
+		largest = 0;
+		for(find_spot = 0; find_spot < device_count; find_spot++)
+		{
+			if(tmpvals[find_spot] > tmpvals[largest])
+			{
+				largest = find_spot;
+			}
+		}
+		tx_order[device_count - tx_spots - 1 ] = largest;
+		tmpvals[largest] = 0;
+	}
+	
+	
+	// The formerly receiving CommandIR has been unplugged
+	if(commandir_rx_num < 0)
+	{
+		if(device_count > 0)
+			commandir_rx_num = 0;
+	}
+	
+	// Clear all pending signals
+	for(x=top_signalq; x >= 0; x--)
+	{
+		free(signalq[top_signalq]);
+	}
+	top_signalq = -1;
+	
+}
+
+static void cleanup_commandir_dev(int spotnum)
+{
+	int location, devnum;
+
+	location = open_commandir_devices[spotnum].location;
+	devnum = open_commandir_devices[spotnum].devnum;
+
+  open_bus_hash[ location ][ devnum ] = 0;
+	device_count--;	
+  
+	if(open_commandir_devices[spotnum].cmdir_udev==NULL)
+	{
+		return;
+	}
+	usb_release_interface(open_commandir_devices[spotnum].cmdir_udev, 
+		open_commandir_devices[spotnum].interface);
+	usb_close(open_commandir_devices[spotnum].cmdir_udev);
+	open_commandir_devices[spotnum].cmdir_udev = NULL;
+}
+
+
+static void hardware_scan()
+{
+	// Scan for hardware changes; libusb doesn't notify us...
+	unsigned char located = 0;
+	struct usb_bus *bus = 0;
+	struct usb_device *dev = 0;
+	
+	int scan_find[MAX_DEVICES][2]; // [0]=bus#, [1]=busdev#
+	unsigned char found = 0;
+	// Using hash for performance instead of memory conservation (+1k)
+	unsigned char still_found[USB_MAX_BUSES][USB_MAX_BUSDEV];
+	unsigned changed = 0;
+	int find_spot = 0;
+	
+	usb_find_busses();
+	usb_find_devices();
+ 	
+ 	for (bus = usb_busses; bus; bus = bus->next)
+	{
+		for (dev = bus->devices; dev; dev = dev->next)	
+		{
+			if (dev->descriptor.idVendor == USB_CMDIR_VENDOR_ID) 
+			{
+				located++;
+				// Do we already know about it?
+				if(!open_bus_hash[bus->location][dev->devnum]){
+				  // Then it's new, open it if we have a spot available
+				  for(find_spot=0; find_spot < MAX_DEVICES; find_spot++)
+				  {
+					if(open_commandir_devices[find_spot].cmdir_udev == NULL)
+					{
+					  // Try to open here
+					  open_commandir_devices[find_spot].cmdir_udev = usb_open(dev);
+					  if(open_commandir_devices[find_spot].cmdir_udev == NULL)
+					  {
+						logprintf(LOG_ERR, 
+						  "Error opening commandir - bus %d, device %d.",
+						  bus, dev);
+						  break;
+						}
+						else 
+						{
+						  
+						// Try to set configuration; not needed on Linux
+// 						int usb_set_configuration(usb_dev_handle *dev, int configuration);
+ 							int r = 0;
+// 							r = usb_set_configuration(open_commandir_devices[find_spot].cmdir_udev, 1);
+// 						printf("Set_configuration returned %d.\n", r);
+						  
+						  r = usb_claim_interface(
+						  	open_commandir_devices[find_spot].cmdir_udev,0);
+						  if(r < 0)
+						  {
+						  	cleanup_commandir_dev(find_spot);
+								logprintf(LOG_ERR, 
+								"Unable to claim CommandIR - Is it already busy?"
+								);
+								logprintf(LOG_ERR, 
+								"Try 'rmmod commandir' or check for other lircds"
+								);
+								break;
+						  }
+						  else 
+						  {
+							// great, it's ours
+							open_commandir_devices[find_spot].location = bus->location;
+							open_commandir_devices[find_spot].devnum = dev->devnum;
+							open_bus_hash[bus->location][dev->devnum] = 1;
+							open_commandir_devices[find_spot].bus = bus->location;
+							open_commandir_devices[find_spot].busdev = dev->devnum;
+							scan_find[++found][0] = bus->location;
+							scan_find[found][1] = dev->devnum;
+							device_count++;
+							changed++;
+							still_found[bus->location][dev->devnum] = 1;	
+							 
+							struct usb_config_descriptor *config = &dev->config[0];
+							struct usb_interface *interface = &config->interface[0];
+							struct usb_interface_descriptor *ainterface = &interface->altsetting[0];
+/*						struct usb_endpoint_descriptor *endpoint = &ainterface->endpoint[2];*/
+							
+							int i;// Load wMaxPacketSize for each endpoint; subtract 0x80 
+										// for double-buffer bit
+							for (i = 0; i < ainterface->bNumEndpoints; i++)
+							{
+								open_commandir_devices[find_spot].endpoint_max[ 
+									(ainterface->endpoint[i].bEndpointAddress >= 0x80) 
+									? (ainterface->endpoint[i].bEndpointAddress-0x80) 
+									: (ainterface->endpoint[i].bEndpointAddress)] 
+									= ainterface->endpoint[i].wMaxPacketSize;
+							}
+							
+							// compensate for double buffer:
+							open_commandir_devices[find_spot].endpoint_max[1] *= 2;
+							
+							// Always use the latest to RX:
+							commandir_rx_num = find_spot;	
+							
+							switch(dev->descriptor.iProduct)
+							{
+							 case 2:
+							 	logprintf(LOG_ERR, "Product identified as CommandIR II");
+							 	open_commandir_devices[find_spot].hw_type = HW_COMMANDIR_2;
+							  open_commandir_devices[find_spot].hw_revision = 0;
+							  open_commandir_devices[find_spot].hw_subversion = 0;
+							  
+							  int send_status = 0, tries=20;
+							  static char get_version[] = {2, GET_VERSION};
+
+								send_status = 4;	// just to start the while()
+								
+								while(tries--){
+									usleep(USB_TIMEOUT_US);	// wait a moment
+										
+									// try moving this below:
+									send_status = usb_bulk_write(
+									open_commandir_devices[find_spot].cmdir_udev, 
+										2, // endpoint2
+										get_version,
+										2, 
+										1500);
+									if(send_status < 0)
+									{
+										logprintf(LOG_ERR, 
+											"Unable to write version request - Is CommandIR busy? Error %d", send_status);
+										break;
+									}
+									
+									send_status = usb_bulk_read(
+										open_commandir_devices[find_spot].cmdir_udev,
+										1,
+										(char *)commandir_data_buffer,
+										open_commandir_devices[ find_spot ].endpoint_max[1],
+										1500);
+										
+									if(send_status < 0)
+									{
+										logprintf(LOG_ERR, 
+											"Unable to read version request - Is CommandIR busy? Error %d", send_status);
+										cleanup_commandir_dev(find_spot);
+										break;
+									}
+									if(send_status==3)
+									{
+										if(commandir_data_buffer[0]==GET_VERSION)
+										{
+											// Sending back version information.
+											open_commandir_devices[find_spot].hw_revision = 
+												commandir_data_buffer[1];
+											open_commandir_devices[find_spot].hw_subversion = 
+												commandir_data_buffer[2];
+											logprintf(LOG_ERR, "Hardware revision is %d.%d.", 
+												commandir_data_buffer[1], commandir_data_buffer[2]);
+											break;
+										}
+										else
+										{
+											continue;
+										}
+									}
+									
+							}
+							break;
+							default:
+								logprintf(LOG_ERR, "Product identified as CommandIR Mini");
+   							open_commandir_devices[find_spot].hw_type = 
+								HW_COMMANDIR_MINI;
+							}
+							
+							if(open_commandir_devices[find_spot].hw_type == 
+								HW_COMMANDIR_UNKNOWN)
+							{
+								logprintf(LOG_ERR, "Product UNKNOWN - cleanup");
+								cleanup_commandir_dev(find_spot);
+							}
+							else
+							{
+								lastSendSignalID[find_spot] = 0;
+								commandir_last_signal_id[find_spot] = 0;
+							}
+							break; // don't keep looping through find_spot
+							} // claim?
+						}// open?
+					}// spot available?
+				 }// for(spots)
+				} // if we haven't seen it before
+				else
+				{
+					still_found[bus->location][dev->devnum] = 1;
+				}
+			}// if it's a CommandIR
+		}// for bus dev's
+	}// for bus's
+	
+	if(!located)
+	{
+		logprintf(LOG_ERR, "No CommandIRs found");
+	}
+	
+	/* Check if any we currently know about have been removed
+	 * (Usually, we get a read/write error first)
+	 */
+	for(find_spot = 0; find_spot < MAX_DEVICES; find_spot++)
+	{
+		if(open_commandir_devices[find_spot].cmdir_udev != NULL)
+		{
+			if(still_found[open_commandir_devices[find_spot].location]
+				[open_commandir_devices[find_spot].devnum] != 1)
+			{
+				logprintf(LOG_ERR, "Commandir %d removed from [%d][%d].", find_spot,open_commandir_devices[find_spot].location, open_commandir_devices[find_spot].devnum);
+				raise_event(COMMANDIR_UNPLUG_1 + find_spot);
+				hardware_disconnect(find_spot);
+				commandir_rx_num = -1;
+				changed++;
+			}
+		}
+	}
+	
+	if(changed)
+	{
+		hardware_setorder();
+		raise_event(COMMANDIR_REORDERED);
+	}
+	
+}
+
+
+// Shutdown everything and terminate 
+static void shutdown_usb()
+{
+	int x;
+	
+	// Wait for any TX to complete before shutting down
+	if(top_signalq >= 0)
+	{
+		shutdown_pending++;
+		logprintf(LOG_ERR, "Waiting for signals to finish transmitting before shutdown");
+		return;
+	}
+	
+	for(x=0; x<MAX_DEVICES; x++)
+	{
+		if(open_commandir_devices[x].cmdir_udev )
+		{
+			usb_release_interface(open_commandir_devices[x].cmdir_udev, 
+				open_commandir_devices[x].interface);
+			usb_close(open_commandir_devices[x].cmdir_udev);
+		}
+	}
+	logprintf(LOG_ERR, "CommandIR driver child cleaned up and exiting");
+	raise_event(COMMANDIR_STOPPED);
+
+	_exit(EXIT_SUCCESS);
+}
+
+static void commandir_read_loop()
+{
+	// Read from CommandIR, Write to pipe
+	
+	unsigned char commands[MAX_COMMAND];
+	int curCommandStart = 0;
+	int curCommandLength = 0;
+	int bytes_read;
+	unsigned char periodic_checks = 0;
+	static unsigned char rx_decode_led[7] = {7, PROC_SET, 0x40, 0, 0,4, 2}; 
+	static unsigned char init_led[7] = {7, PROC_SET, 0x00, 0x01, 3, 55, 2}; 
+	static unsigned char deinit_led[7] = {7, PROC_SET, 0x0, 0x02, 3, 45, 2}; 
+	static unsigned int LIRC_frequency = 38000; 
+
+	int send_status = 0; 
+	int i = 0;
+	int tmp = 0;
+	int tmp2 = 0;
+
+	raise_event(COMMANDIR_READY);
+	
+	for(;;){
+		/*** This is the main loop the monitors control and TX events from 
+		  * the parent, and monitors the CommandIR RX buffer
+		  */
+		
+		curCommandStart = 0;
+		curCommandLength = 0;
+		bytes_read = read(tochild_read, commands, MAX_COMMAND); 
+		
+		if(shutdown_pending > 0 && (top_signalq==-1))
+			shutdown_usb();
+		
+		if(bytes_read > 0){
+		
+			while(curCommandStart < bytes_read){
+				curCommandLength = commands[curCommandStart] + 
+					commands[curCommandStart + 1] * 256;
+				
+				switch(commands[curCommandStart + 2]){	// the control value
+					case DEINIT_HEADER_LIRC:
+						for(i=0; i<device_count; i++)
+						{
+						 if(open_commandir_devices[tx_order[i]].hw_type ==
+						  HW_COMMANDIR_2)
+						 {
+						  if(open_commandir_devices[tx_order[i]].cmdir_udev > 0)
+						  {
+							send_status=usb_bulk_write(
+								open_commandir_devices[tx_order[i]].cmdir_udev, 
+								2, // endpoint2
+								(char*)deinit_led,
+								7, // bytes
+								USB_TIMEOUT_MS);
+						  }
+						  rx_hold = 1;	// Put a hold on RX, but queue events
+						 }
+						}
+						
+						break;
+					case INIT_HEADER_LIRC:
+						for(i=0; i<device_count; i++)
+						{
+						 if(open_commandir_devices[tx_order[i]].hw_type == 
+							HW_COMMANDIR_2)
+						 {
+						 if(open_commandir_devices[tx_order[i] ].cmdir_udev > 0)
+						  {
+							send_status=usb_bulk_write(
+								open_commandir_devices[tx_order[i] ].cmdir_udev,
+								2, // endpoint2
+								(char*)init_led,
+								7, // bytes
+								USB_TIMEOUT_MS);
+						  }
+						  rx_hold = 0;	// Resume RX after queue events
+						 }
+						}
+						break;
+					case RXDECODE_HEADER_LIRC:
+					  //	Successful RX decode: show it on the light.
+					  if(open_commandir_devices[commandir_rx_num].cmdir_udev > 0)
+					  {
+						send_status=usb_bulk_write(
+							open_commandir_devices[commandir_rx_num].cmdir_udev,
+							2, // endpoint2
+							(char*)rx_decode_led,
+							7, // bytes
+							USB_TIMEOUT_MS);
+
+					  }
+					  break;
+
+					case FREQ_HEADER_LIRC:
+						LIRC_frequency = (commands[curCommandStart + 6] & 0x000000ff) | 
+							((commands[curCommandStart + 5] << 8) & 0x0000ff00) | 
+							((commands[curCommandStart + 4] << 16) & 0x00ff0000) | 
+							((commands[curCommandStart + 3] << 24) & 0xff000000);
+						if(!LIRC_frequency)
+							LIRC_frequency = DEFAULT_FREQ;
+						break;
+					case TX_HEADER_NEW:
+					case TX_LIRC_T:
+						if(curCommandLength==64)
+						{
+							if(check_irsend_commandir(&commands[curCommandStart + 4]))
+							{
+								break; // it's a command for us
+							}
+						}
+						add_to_tx_pipeline(&commands[curCommandStart + 4], 
+							curCommandLength - 4, pre_pipeline_emitter_mask, LIRC_frequency);
+						break;
+						
+					case CHANNEL_EN_MASK:
+						pre_pipeline_emitter_mask = (commands[curCommandStart+4] << 8) |
+							 commands[curCommandStart+3];
+						break;
+				}
+				curCommandStart += curCommandLength;
+			
+			}
+		}
+		// If we're receiving, make sure the commandir buffer doesn't overrun
+		if(commandir_read() < 20 )
+			tmp = 2;
+		while(tmp-- > 0)
+		{
+			tmp2 = commandir_read();
+// 		printf("commandir_read() (%d) returning %d.\n", tmp,tmp2);
+		}
+		if(tmp2 < 20 ){
+			// once in a while, but never while we're retreaving a signal
+			if(++periodic_checks>100)
+			{
+				hardware_scan();
+				periodic_checks = 0;
+			}
+			else
+			{
+ 				usleep(read_delay);
+ 			}
+		}
+	}
+
+}
+
+static int check_irsend_commandir(unsigned char *command)
+{
+	// decode the code like LIRC would do, and take an action
+	int commandir_code = 0;
+	
+	commandir_code = commandir_decode((char*)command);
+	
+	if(commandir_code > 0xef)
+	{
+		// It's a settransmitters command
+		int channel = commandir_code & 0x0f;
+		
+		// can only set 1 bit from here so far..,
+		pre_pipeline_emitter_mask = 0x0001 << channel;	
+		
+		return commandir_code;
+	}
+	
+	switch(commandir_code)
+	{
+		case 0x53:
+			read_delay /= 2;	// "faster" means less time
+			if(read_delay < MIN_WAIT_BETWEEN_READS_US)
+				read_delay = MIN_WAIT_BETWEEN_READS_US;
+			break;
+		case 0x54:
+			read_delay *= 2;	// "slower" means more time
+			if(read_delay > MAX_WAIT_BETWEEN_READS_US)
+				read_delay = MAX_WAIT_BETWEEN_READS_US;
+			break;
+	
+		case 0x09: 
+		case 0x0A:
+			logprintf(LOG_ERR, "Re-selecting RX not implemented yet");
+			break;
+			
+		case 0xe6:	//	disable-fast-decode
+			logprintf(LOG_ERR, "Fast decoding disabled");
+			insert_fast_zeros = 0;
+			break;
+			
+		case 0xe7:	//	enable-fast-decode
+		case 0xe9:	//	force-fast-decode-2
+			logprintf(LOG_ERR, "Fast decoding enabled");
+			insert_fast_zeros = 2;
+			break;
+		
+		case 0xe8:	//	force-fast-decode-1
+			logprintf(LOG_ERR, "Fast decoding enabled (1)");
+			insert_fast_zeros = 1;
+			break;
+			
+		default:
+			if(commandir_code > 0x60 && commandir_code < 0xf0)
+			{
+				int ledhigh = 0, ledlow = 0, ledprog = -1;
+				// LED Command
+				switch(commandir_code >> 4)
+				{
+					case 0x6: ledlow = 0x80; break;
+					case 0x7: ledlow = 0x40; break;
+					case 0x8: ledlow = 0x20; break;
+					case 0x9: ledlow = 0x10; break;
+					case 0xa: ledlow = 0x04; break;
+					case 0xb: ledhigh = 0x80; break;
+					case 0xc: ledlow = 0x01; break;
+					case 0xd: ledlow = 0x02; break;
+					case 0xe: ledlow = 0x08; break;
+				}
+				ledprog = (commandir_code & 0x0f) - 1;
+				
+				if( ((ledhigh + ledlow) > 0) && ledprog > -1)
+				{
+					//	Set light:
+					static unsigned char lightchange[7] = {7, 
+					PROC_SET, 0, 0, 0, 0, 3}; 
+					lightchange[2] = ledhigh;
+					lightchange[3] = ledlow;
+					lightchange[4] = ledprog;
+					int send_status = 0; 
+					
+					send_status=usb_bulk_write(
+						open_commandir_devices[tx_order[0]].cmdir_udev, 
+						2, // endpoint2
+						(char *)lightchange,
+						7, // bytes
+						USB_TIMEOUT_MS);
+				}
+				
+				return commandir_code; // done
+			}
+		
+	}
+
+	return commandir_code;
+}
+
+
+// return how many RX's were in the last receive; so we know whether to poll more frequently or not
+static int commandir_read() 
+{
+	
+	/***  Which CommandIRs do we have to read from?  Poll RX CommandIRs 
+		* regularly, but non-receiving CommandIRs should be more periodically
+		*/
+	
+	int i,j;
+	int read_received = 0;
+	int read_retval = 0;
+	int conv_retval = 0;
+	int max_read = 5;
+	static int zeroterminated = 0;
+
+	for(i=0; i<device_count; i++)
+	{
+	
+		switch(open_commandir_devices[tx_order[i]].hw_type)
+		{
+			case HW_COMMANDIR_2:
+		
+				read_retval = usb_bulk_read(
+					open_commandir_devices[ tx_order[i] ].cmdir_udev,
+					1,
+					(char *)commandir_data_buffer,
+					open_commandir_devices[ tx_order[i] ].endpoint_max[1],
+					5000);	
+					
+				if(read_retval==0)
+					break;
+				
+				if(read_retval < 1)
+				{
+					if(read_retval < 0)
+					{
+						if(read_retval == -19){
+							logprintf(LOG_ERR, "Read Error - CommandIR probably unplugged");
+						}
+						else
+						{
+							logprintf(LOG_ERR, 
+								"Didn't receive a full packet from a CommandIR II! - err %d ."
+								, read_retval);
+						}
+						hardware_disconnect(tx_order[i]);
+						hardware_scan();
+					}
+					// 0 bytes is the most frequency case; nothing to report
+
+					break;
+				} 
+				
+				if(commandir_data_buffer[0]==RX_HEADER_TXAVAIL)
+				{
+					// sending us the current tx_start, tx_end arrays, and where it's at
+					commandir_tx_start[tx_order[i]*4] = commandir_data_buffer[4];
+					commandir_tx_start[tx_order[i]*4+1] = commandir_data_buffer[3];
+					commandir_tx_start[tx_order[i]*4+2] = commandir_data_buffer[2];
+					commandir_tx_start[tx_order[i]*4+3] = commandir_data_buffer[1];
+					
+					commandir_tx_end[tx_order[i]*4] = commandir_data_buffer[8];
+					commandir_tx_end[tx_order[i]*4+1] = commandir_data_buffer[7];
+					commandir_tx_end[tx_order[i]*4+2] = commandir_data_buffer[6];
+					commandir_tx_end[tx_order[i]*4+3] = commandir_data_buffer[5];
+					
+					commandir_last_signal_id[ tx_order[i] ] = commandir_data_buffer[9];
+					
+					recalc_tx_available(tx_order[i]); 
+					pipeline_check();
+					if(top_signalq > 0)
+					{
+						read_received++;	
+					}
+					
+					// This ALSO implies there's NO MORE RX DATA.
+					lirc_t lirc_zero_buffer[2] = {0, 0};
+					
+					int tmp4 = 0;
+					if(zeroterminated>1001)
+					{
+						// Send LIRC a 0,0 packet to allow IMMEDIATE decoding
+						if(insert_fast_zeros > 0)
+						{
+							tmp4 = write(child_pipe_write, lirc_zero_buffer, sizeof(lirc_t)*insert_fast_zeros);
+						}
+						zeroterminated = 0;
+					}
+					else
+					{
+						if((zeroterminated < 1000) && (zeroterminated > 0))
+							zeroterminated += 1000;
+						if(zeroterminated > 1000)
+							zeroterminated++;
+					}
+					
+					break;
+				}
+						
+						
+				if(commandir_data_buffer[0]==RX_HEADER_EVENTS)
+				{
+					for(j=1; j<(read_retval); j++)
+					{
+						raise_event(commandir_data_buffer[j]+tx_order[i]*0x10);
+					}
+				}
+				else
+				{
+					if( (commandir_data_buffer[0]==RX_HEADER_DATA) && 
+						(commandir_rx_num==tx_order[i]) )
+					{
+						if(rx_hold==0)	// Only if we should be listening for remote cmds
+						{
+							zeroterminated = 1;
+							conv_retval = commandir2_convert_RX(
+								(unsigned short *)&commandir_data_buffer[2], 
+								commandir_data_buffer[1]);
+							read_received = conv_retval; // header
+						}
+					}
+				}
+				break;
+			
+			case HW_COMMANDIR_MINI:
+			
+				max_read = 5;
+				while(max_read--){
+					
+					read_retval = usb_bulk_read(
+						open_commandir_devices[ tx_order[i] ].cmdir_udev,
+						1,
+						(char *)commandir_data_buffer,
+						64,
+						USB_TIMEOUT_MS);
+							
+					if (!(read_retval == MAX_HW_MINI_PACKET)) 
+					{
+						if(read_retval == -19){
+							logprintf(LOG_ERR, "Read Error - CommandIR probably unplugged");
+						}
+						else
+						{
+							logprintf(LOG_ERR, 
+								"Didn't receive a full packet from a Mini! - err %d ."
+								, read_retval);
+						}
+						
+						hardware_disconnect(tx_order[i]);
+						hardware_scan();
+						break; 
+					}
+
+					
+					if ( (commandir_data_buffer[1] > 0)  && 
+						(commandir_rx_num==tx_order[i]) ) 
+					{
+						conv_retval = cmdir_convert_RX(commandir_data_buffer);
+						
+						read_received += commandir_data_buffer[1];					
+						
+						if(commandir_data_buffer[1] < 20)
+						{
+							// Lots of hardware buffer room left; don't tie up CPU
+							break;
+						}
+					}
+					else
+					{
+						break;
+					}
+				} // while; should only repeat if there's more RX data
+				
+				/* CommandIR Mini only has 1 buffer  */
+				commandir_tx_start[tx_order[i]*4] = 0;
+				commandir_tx_start[tx_order[i]*4+1] = 0;
+				commandir_tx_start[tx_order[i]*4+2] = 0;
+				commandir_tx_start[tx_order[i]*4+3] = 0;
+				
+				commandir_tx_end[tx_order[i]*4] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+1] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+2] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+3] = commandir_data_buffer[2];
+				
+				/* .. and it can't pipeline... */
+				commandir_last_signal_id[i] = lastSendSignalID[i];
+				recalc_tx_available(tx_order[i]); 
+				pipeline_check();
+				break;
+			case HW_COMMANDIR_UNKNOWN:
+					break;
+		} // end switch
+	} // for each attached hardware device
+	return read_received;
+}
+
+static void setEmitterMask(int bitmask)
+{
+	channels_en[0] = bitmask & 0x0F;
+	channels_en[1] = (bitmask >> 4) & 0xfF;
+	channels_en[2] = (bitmask >> 8) & 0xfF;
+	channels_en[3] = (bitmask >> 12) & 0xfF;
+}
+
+
+static int commandir2_convert_RX(unsigned short *bufferrx, 
+	unsigned char numvalues)
+{
+	// convert hardware timestamp values to elapsed time values
+	
+	int i;
+	int curpos = 0;
+	int bytes_w = 0;
+	lirc_t lirc_data_buffer[256];	
+	
+	i=0;
+	int pca_count = 0;
+	int overflows = 0;
+	
+	while(curpos < numvalues )
+	{
+		pca_count = (bufferrx[curpos] & 0x3fff) << 2; 
+		pca_count = pca_count / 12;
+		
+		if(bufferrx[curpos] & COMMANDIR_2_OVERFLOW_MASK)
+		{
+			overflows = bufferrx[curpos+1];
+			lirc_data_buffer[i] =  pca_count + (overflows * 0xffff / 12);
+			
+			if(bufferrx[curpos] & COMMANDIR_2_PULSE_MASK)
+			{
+				lirc_data_buffer[i] |= PULSE_BIT;
+			}
+			curpos++;
+		
+		}
+		else
+		{
+			lirc_data_buffer[i] = pca_count;
+			if(bufferrx[curpos] & COMMANDIR_2_PULSE_MASK)
+			{
+				lirc_data_buffer[i] |= PULSE_BIT;
+			}
+		}
+		
+		curpos++;
+		i++;
+		if(i> 255)
+		{
+			break;
+		}
+	}
+		
+ 	bytes_w = write(child_pipe_write, lirc_data_buffer, sizeof(lirc_t)*i);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+		return 0;
+	}	
+	
+	return bytes_w;
+}
+
+
+
+
+// Originally from lirc_cmdir.c
+static int cmdir_convert_RX(unsigned char *orig_rxbuffer)
+{
+	unsigned int num_data_values = 0;
+	unsigned int num_data_bytes = 0;
+	unsigned int asint1 = 0, asint2 = 0, overflows = 0;
+	int i;
+	int bytes_w;	// Pipe write
+	lirc_t lirc_data_buffer[256];	
+	
+
+	num_data_bytes = orig_rxbuffer[1];
+	
+	/* check if num_bytes is multiple of 3; if not, error  */
+	if (num_data_bytes%3 > 0) return -1;
+	if (num_data_bytes > 60) return -3; 
+	if (num_data_bytes < 3) return -2;
+	
+	num_data_values = num_data_bytes/3;
+	
+	asint2 = orig_rxbuffer[3] + orig_rxbuffer[4] * 0xff;
+	if(last_mc_time==-1)
+	{
+		// The first time we run there's no previous time value
+		last_mc_time = asint2 - 110000;	
+		if(last_mc_time < 0) last_mc_time+=0xffff;
+	}
+	
+	asint1 = last_mc_time;
+	overflows = orig_rxbuffer[5];
+	
+	for(i=2; i<num_data_values+2; i++)
+	{
+		if(overflows < 0xff)
+		{
+			// space
+			lirc_data_buffer[i-2] = get_time_value(asint1,
+				 asint2, overflows) - 26;
+		} 
+		else 
+		{	// pulse
+			lirc_data_buffer[i-2] = get_time_value(asint1,
+				 asint2, 0) + 26;
+			lirc_data_buffer[i-2] |= PULSE_BIT;
+		}	
+		asint1 = asint2; 
+		asint2 = orig_rxbuffer[i*3] + orig_rxbuffer[i*3+1] * 0xff;
+		overflows = orig_rxbuffer[i*3+2];	
+	}
+	last_mc_time = asint1;
+	
+	
+ 	bytes_w = write(child_pipe_write, lirc_data_buffer, sizeof(lirc_t)*num_data_values);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+		goto done;
+	}	
+	
+done:
+	return bytes_w;
+
+}
+
+
+
+
+static unsigned int get_time_value(unsigned int firstint, 
+	unsigned int secondint, unsigned char overflow) 
+{	
+	/* get difference between two MCU timestamps, CommandIR Mini version  */
+	unsigned int t_answer = 0;
+	
+	if (secondint > firstint) 
+	{
+		t_answer = secondint - firstint + overflow*0xffff;
+	} 
+	else 
+	{
+		if (overflow > 0) 
+		{
+			t_answer = (65536 - firstint) + secondint + (overflow - 1)*0xffff - 250;
+		} 
+		else 
+		{
+			t_answer = (65536 - firstint) + secondint;
+		}
+	}
+
+	/* clamp to long signal  */
+	if (t_answer > 16000000) t_answer = PULSE_MASK;
+	return t_answer;
+}
+
+
+static void raise_event(unsigned int eventid)
+{
+	/* Raise an LIRC Event by
+	 * Generating lirc_t Pattern
+	 */
+	static lirc_t event_data[18] = {LIRCCODE_GAP, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	int i, bytes_w;
+
+	// 	logprintf(LOG_ERR, "Raising event %d", eventid);
+	for(i=0; i<8; i++)
+	{
+		if( (eventid & 0x80) )
+		{
+			event_data[i*2+1] = signal_base[0][0];
+			event_data[i*2+2] = signal_base[0][1];
+		}
+		else
+		{
+			event_data[i*2+1] = signal_base[1][0];
+			event_data[i*2+2] = signal_base[1][1];
+		}
+		eventid = eventid << 1;
+	}
+	
+ 	event_data[16] = LIRCCODE_GAP*4;
+ 	
+ 	bytes_w = write(child_pipe_write, event_data, sizeof(lirc_t) * 17);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+	}	
+	
+}
+
+static int commandir_decode(char *command)
+{
+	// Decode the signal to a number, just like LIRC; 
+	// there's probably a built-in way to do this.
+	int i;
+	int code = 0;
+	
+	lirc_t *codes;	
+	codes = (lirc_t *)command;
+	
+	for(i=0; i<15; i+=2)
+	{
+		code = code << 1;
+		if(codes[i]==100)
+			code |= 1;
+	}
+	return code;
+}
+
diff --git a/abs/core-testing/lirc_085-utils/hw_commandir.h b/abs/core-testing/lirc_085-utils/hw_commandir.h
new file mode 100755
index 0000000..2280f6c
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/hw_commandir.h
@@ -0,0 +1,175 @@
+ 
+/****************************************************************************
+ ** hw_commandir.h **********************************************************
+ ****************************************************************************
+ * 
+ * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
+ * -- Original hw_default.h
+ * Modified for CommandIR Transceivers, April-June 2008, Matthew Bodkin 
+ *
+ */
+
+#ifndef HW_COMMANDIR_H
+#define HW_COMMANDIR_H
+
+#define RX_BUFFER_SIZE 1024
+#define TX_BUFFER_SIZE 1024
+#define TX_QUEUE 1
+#define RX_QUEUE 0
+#define MAX_COMMANDIRS 4
+#define MAX_COMMAND 8192
+
+/* transmitter channel control */
+#define MAX_DEVICES		4
+#define MAX_CHANNELS    16
+#define DEVICE_CHANNELS	4
+#define MAX_MASK 		0xffff
+#define MAX_SIGNALQ		100
+
+/* CommandIR control codes */
+#define CHANNEL_EN_MASK	1
+#define FREQ_HEADER     2
+#define MCU_CTRL_SIZE   3
+#define TX_HEADER       7
+#define TX_HEADER_NEW	8
+/* New for CommandIR II  */
+
+#define READ_INPUTS		10
+#define PROC_SET		11
+#define INIT_FUNCTION	12
+#define RX_SELECT		13
+#define TX_COMMANDIR_II 14
+/* Internal to driver */
+#define TX_LIRC_T	    15
+#define FREQ_HEADER_LIRC 16
+#define RXDECODE_HEADER_LIRC 17
+#define INIT_HEADER_LIRC 18
+#define DEINIT_HEADER_LIRC 19
+#define GET_VERSION 	20
+
+#define COMMANDIR_2_PULSE_MASK 0x8000
+#define COMMANDIR_2_OVERFLOW_MASK 0x4000
+
+#define DEFAULT_PULSE_WIDTH 13
+
+#define USB_CMDIR_VENDOR_ID		0x10c4
+#define USB_CMDIR_PRODUCT_ID	0x0003
+#define USB_CMDIR_MINOR_BASE	192
+
+#define HW_COMMANDIR_MINI 	1
+#define HW_COMMANDIR_2		2
+#define HW_COMMANDIR_UNKNOWN 127
+
+#define MAX_HW_MINI_PACKET 64
+
+// CommandIR has lots of buffer room, we don't need to poll constantly
+#define USB_TIMEOUT_MS 5000
+#define USB_TIMEOUT_US 1000
+#define WAIT_BETWEEN_READS_US 10000
+#define MAX_WAIT_BETWEEN_READS_US 5000000
+#define MIN_WAIT_BETWEEN_READS_US 5000
+
+#define USB_MAX_BUSES	8
+#define USB_MAX_BUSDEV	127
+
+#define RX_HEADER_DATA 		0x01
+#define RX_HEADER_EVENTS 	0x02
+#define RX_HEADER_TXAVAIL 	0x03
+
+
+// We keep CommandIR's OPEN even on -deinit for speed and to monitor 
+// Other non-LIRC events (plugin, suspend, etc)
+#define USB_KEEP_WARM 1
+
+// CommandIR lircd.conf event driven code definitions
+#define LIRCCODE_GAP  125000
+#define JACK_PLUG_1		0x01
+#define JACK_PLUG_2		0x02
+#define JACK_PLUG_3		0x03
+#define JACK_PLUG_4		0x04
+#define JACK_PLUG_5		0x11
+#define JACK_PLUG_6		0x12
+#define JACK_PLUG_7		0x13
+#define JACK_PLUG_8		0x14
+#define JACK_PLUG_9		0x21
+#define JACK_PLUG_10	0x22
+#define JACK_PLUG_11	0x23
+#define JACK_PLUG_12	0x24
+#define JACK_PLUG_13	0x31
+#define JACK_PLUG_14	0x32
+#define JACK_PLUG_15	0x33
+#define JACK_PLUG_16	0x34
+
+#define JACK_UNPLUG_1	0x05
+#define JACK_UNPLUG_2	0x06
+#define JACK_UNPLUG_3	0x07
+#define JACK_UNPLUG_4	0x08
+#define JACK_UNPLUG_5	0x15
+#define JACK_UNPLUG_6	0x16
+#define JACK_UNPLUG_7	0x17
+#define JACK_UNPLUG_8	0x18
+#define JACK_UNPLUG_9	0x25
+#define JACK_UNPLUG_10	0x26
+#define JACK_UNPLUG_11	0x27
+#define JACK_UNPLUG_12	0x28
+#define JACK_UNPLUG_13	0x35
+#define JACK_UNPLUG_14	0x36
+#define JACK_UNPLUG_15	0x37
+#define JACK_UNPLUG_16	0x38
+
+#define SELECT_TX_INTERNAL	0x09
+#define SELECT_TX_ExTERNAL	0x0A
+
+#define SELECT_TX_ON_1		0x0D
+#define SELECT_TX_ON_2		0x1D
+#define SELECT_TX_ON_3		0x2D
+#define SELECT_TX_ON_4		0x3D
+
+#define JACK_PLUG_RX_1		0x0B
+#define JACK_UNPLUG_RX_1	0x0C
+#define JACK_PLUG_RX_2		0x1B
+#define JACK_UNPLUG_RX_2	0x1C
+#define JACK_PLUG_RX_3		0x2B
+#define JACK_UNPLUG_RX_3	0x2C
+#define JACK_PLUG_RX_4		0x3B
+#define JACK_UNPLUG_RX_4	0x3C
+
+#define COMMANDIR_PLUG_1	0x41
+#define COMMANDIR_PLUG_2	0x42
+#define COMMANDIR_PLUG_3	0x43
+#define COMMANDIR_PLUG_4	0x44
+
+#define COMMANDIR_UNPLUG_1	0x45
+#define COMMANDIR_UNPLUG_2	0x46
+#define COMMANDIR_UNPLUG_3	0x47
+#define COMMANDIR_UNPLUG_4	0x48
+
+#define COMMANDIR_REORDERED	0x50
+#define COMMANDIR_READY		0x51
+#define COMMANDIR_STOPPED	0x52
+#define COMMANDIR_POLL_FASTER	0x53
+#define COMMANDIR_POLL_SLOWER	0x54
+
+#define SETTRANSMITTERS_1	0xf0
+#define SETTRANSMITTERS_2	0xf1
+#define SETTRANSMITTERS_3	0xf2
+#define SETTRANSMITTERS_4	0xf3
+#define SETTRANSMITTERS_5	0xf4
+#define SETTRANSMITTERS_6	0xf5
+#define SETTRANSMITTERS_7	0xf6
+#define SETTRANSMITTERS_8	0xf7
+#define SETTRANSMITTERS_9	0xf8
+#define SETTRANSMITTERS_10	0xf9
+#define SETTRANSMITTERS_11	0xfa
+#define SETTRANSMITTERS_12	0xfb
+#define SETTRANSMITTERS_13	0xfc
+#define SETTRANSMITTERS_14	0xfd
+#define SETTRANSMITTERS_15	0xfe
+#define SETTRANSMITTERS_16	0xff
+
+// What's in a returning data packet
+#define COMMANDIR_RX_EVENTS 		0x02
+#define COMMANDIR_RX_DATA			0x01
+
+
+#endif
diff --git a/abs/core-testing/lirc_085-utils/kernel-2.6.26.patch b/abs/core-testing/lirc_085-utils/kernel-2.6.26.patch
new file mode 100644
index 0000000..74bb986
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/kernel-2.6.26.patch
@@ -0,0 +1,122 @@
+--- a/drivers/kcompat.h	2008-01-13 11:26:28.000000000 +0100
++++ b/drivers/kcompat.h	2008-05-14 18:37:49.000000000 +0200
+@@ -1,4 +1,4 @@
+-/*      $Id: kcompat.h,v 5.34 2008/01/13 10:26:28 lirc Exp $      */
++/*      $Id: kcompat.h,v 5.36 2008/05/14 16:37:49 lirc Exp $      */
+ 
+ #ifndef _KCOMPAT_H
+ #define _KCOMPAT_H
+@@ -36,10 +36,10 @@
+ 	class_simple_destroy(cls);
+ }
+ 
+-#define lirc_class_device_create(cs, parent, dev, device, fmt, args...) \
+-	class_simple_device_add(cs, dev, device, fmt, ## args)
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_simple_device_add(cs, dev, parent, fmt, ## args)
+ 
+-static inline void class_device_destroy(lirc_class_t *cls, dev_t devt)
++static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt)
+ {
+ 	class_simple_device_remove(devt);
+ }
+@@ -48,20 +48,40 @@
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
+ 
+-#define lirc_class_device_create(cs, parent, dev, device, fmt, args...) \
+-	class_device_create(cs, dev, device, fmt, ## args)
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_device_create(cs, dev, parent, fmt, ## args)
+ 
+ #else /* >= 2.6.15 */
+ 
+-#define lirc_class_device_create class_device_create
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
++
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_device_create(cs, NULL, dev, parent, fmt, ## args)
++
++#else /* >= 2.6.26 */
++
++#define lirc_device_create device_create
++
++#endif /* >= 2.6.26 */
++
+ #define LIRC_DEVFS_PREFIX
+ 
+-#endif
++#endif /* >= 2.6.15 */
+ 
+ typedef struct class lirc_class_t;
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
++
++#define lirc_device_destroy class_device_destroy
++
++#else
++
++#define lirc_device_destroy device_destroy
++
+ #endif
+ 
++#endif /* >= 2.6.13 */
++
+ #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
+ #define LIRC_HAVE_DEVFS
+ #define LIRC_HAVE_DEVFS_24
+@@ -133,8 +153,8 @@
+ #ifndef LIRC_HAVE_SYSFS
+ #define class_destroy(x) do { } while (0)
+ #define class_create(x, y) NULL
+-#define class_device_destroy(x, y) do { } while (0)
+-#define lirc_class_device_create(x, y, z, xx, yy, zz) 0
++#define lirc_class_destroy(x, y) do { } while (0)
++#define lirc_class_create(x, y, z, xx, yy, zz) 0
+ #define IS_ERR(x) 0
+ typedef struct class_simple
+ {
+--- a/drivers/lirc_dev/lirc_dev.c	2008-01-13 11:45:02.000000000 +0100
++++ b/drivers/lirc_dev/lirc_dev.c	2008-05-14 18:37:49.000000000 +0200
+@@ -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.56 2008/01/13 10:45:02 lirc Exp $
++ * $Id: lirc_dev.c,v 1.58 2008/05/14 16:37:49 lirc Exp $
+  *
+  */
+ 
+@@ -145,7 +145,8 @@
+ #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));
++	lirc_device_destroy(lirc_class,
++			    MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ 
+ 	if (ir->buf != ir->p.rbuf) {
+ 		lirc_buffer_free(ir->buf);
+@@ -400,9 +401,9 @@
+ 			S_IFCHR|S_IRUSR|S_IWUSR,
+ 			DEV_LIRC "/%u", ir->p.minor);
+ #endif
+-	(void) lirc_class_device_create(lirc_class, NULL,
+-					MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
+-					ir->p.dev, "lirc%u", ir->p.minor);
++	(void) lirc_device_create(lirc_class, ir->p.dev,
++				  MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
++				  "lirc%u", ir->p.minor);
+ 
+ 	if (p->sample_rate || p->get_queue) {
+ 		/* try to fire up polling thread */
+@@ -441,7 +442,8 @@
+ 	return minor;
+ 
+ out_sysfs:
+-	class_device_destroy(lirc_class, MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
++	lirc_device_destroy(lirc_class,
++			    MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ #ifdef LIRC_HAVE_DEVFS_24
+ 	devfs_unregister(ir->devfs_handle);
+ #endif
diff --git a/abs/core-testing/lirc_085-utils/lirc.logrotate b/abs/core-testing/lirc_085-utils/lirc.logrotate
new file mode 100644
index 0000000..df97c60
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/lirc.logrotate
@@ -0,0 +1,8 @@
+/var/log/lircd {
+   missingok
+   notifempty
+   delaycompress
+   postrotate
+      /usr/bin/killall -HUP -q lircd
+   endscript
+}
diff --git a/abs/core-testing/lirc_085-utils/lirc_atiusb.patch b/abs/core-testing/lirc_085-utils/lirc_atiusb.patch
new file mode 100644
index 0000000..2f0c61e
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/lirc_atiusb.patch
@@ -0,0 +1,27 @@
+diff -ruaN lirc-0.8.4.orig/drivers/lirc_atiusb/lirc_atiusb.c lirc-0.8.4/drivers/lirc_atiusb/lirc_atiusb.c
+--- lirc-0.8.4.orig/drivers/lirc_atiusb/lirc_atiusb.c	2008-05-19 08:10:35.000000000 +0000
++++ lirc-0.8.4/drivers/lirc_atiusb/lirc_atiusb.c	2009-02-14 22:35:44.000000000 +0000
+@@ -192,8 +192,9 @@
+ /* init strings */
+ #define USB_OUTLEN		7
+ 
+-static char init1[] = {0x01, 0x00, 0x20, 0x14};
+-static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20};
++static char init1[] = {0x80, 0x05, 0x1b, 0x15, 0x14, 0x20, 0x24, 0x15};
++static char init2[] = {0x83, 0x03};
++static char init3[] = {0x84, 0xd7, 0x020};
+ 
+ struct in_endpt {
+ 	/* inner link in list of endpoints for the remote specified by ir */
+@@ -1183,8 +1184,9 @@
+ 			oep->buf, USB_OUTLEN, usb_remote_send,
+ 			oep, oep->ep->bInterval);
+ 
+-		send_packet(oep, 0x8004, init1);
+-		send_packet(oep, 0x8007, init2);
++               send_packet(oep, 0x8007, init1);
++               send_packet(oep, 0x8002, init2);
++               send_packet(oep, 0x8003, init3);
+ 	}
+ }
+ 
diff --git a/abs/core-testing/lirc_085-utils/lircd b/abs/core-testing/lirc_085-utils/lircd
new file mode 100755
index 0000000..f4686d7
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/lircd
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+. /etc/rc.conf
+. /etc/rc.d/functions
+. /etc/conf.d/lircd
+
+PID=$(pidof -o %PPID /usr/sbin/lircd)
+case "$1" in
+  start)
+    stat_busy "Starting LIRC Daemon"
+    [ -n "$LIRC_DRIVER" ] && LIRC_EXTRAOPTS="-H $LIRC_DRIVER $LIRC_EXTRAOPTS"
+    [ -z "$PID" ] && 
+      if [ -n "$LIRC_DEVICE" ] ; then
+        /usr/sbin/lircd -d "$LIRC_DEVICE" $LIRC_EXTRAOPTS $LIRC_CONFIGFILE
+      else
+        /usr/sbin/lircd $LIRC_EXTRAOPTS $LIRC_CONFIGFILE
+      fi
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      add_daemon lircd
+      stat_done
+    fi
+    ;;
+  stop)
+    stat_busy "Stopping LIRC Daemon"
+    [ ! -z "$PID" ] && kill $PID &> /dev/null
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      rm_daemon lircd
+      stat_done
+    fi
+    ;;
+  restart)
+    $0 stop
+    sleep 1
+    $0 start
+    ;;
+  *)
+    echo "usage: $0 {start|stop|restart}"
+esac
+exit 0
diff --git a/abs/core-testing/lirc_085-utils/lircd.conf.d b/abs/core-testing/lirc_085-utils/lircd.conf.d
new file mode 100644
index 0000000..760dab0
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/lircd.conf.d
@@ -0,0 +1,8 @@
+#
+# Parameters for lirc daemon
+#
+
+LIRC_DEVICE="/dev/lirc0"
+LIRC_DRIVER=""
+LIRC_EXTRAOPTS=""
+LIRC_CONFIGFILE=""
diff --git a/abs/core-testing/lirc_085-utils/lircmd b/abs/core-testing/lirc_085-utils/lircmd
new file mode 100755
index 0000000..220c47c
--- /dev/null
+++ b/abs/core-testing/lirc_085-utils/lircmd
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+. /etc/rc.conf
+. /etc/rc.d/functions
+
+PID=`pidof -o %PPID /usr/sbin/lircmd`
+case "$1" in
+  start)
+    stat_busy "Starting lircmd Daemon"
+    [ -z "$PID" ] && /usr/sbin/lircmd
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      add_daemon lircmd
+      stat_done
+    fi
+    ;;
+  stop)
+    stat_busy "Stopping lircmd Daemon"
+    [ ! -z "$PID" ]  && kill $PID &> /dev/null
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      rm_daemon lircmd
+      stat_done
+    fi
+    ;;
+  restart)
+    $0 stop
+    sleep 1
+    $0 start
+    ;;
+  *)
+    echo "usage: $0 {start|stop|restart}"
+esac
+exit 0
diff --git a/abs/core-testing/lirc_085/PKGBUILD b/abs/core-testing/lirc_085/PKGBUILD
new file mode 100644
index 0000000..12dc3b4
--- /dev/null
+++ b/abs/core-testing/lirc_085/PKGBUILD
@@ -0,0 +1,86 @@
+# $Id: PKGBUILD 14978 2008-10-11 21:04:37Z tpowa $
+# Maintainer: Paul Mattal <paul@archlinux.org>
+
+pkgname=lirc
+pkgver=0.8.5CVS
+pkgrel=17
+_kernver=2.6.28-LinHES
+pkgdesc="Linux Infrared Remote Control kernel modules for stock arch kernel"
+arch=(i686 x86_64)
+url="http://www.lirc.org/"
+license=('GPL')
+depends=('lirc-utils=0.8.5CVS' 'kernel26>=2.6.27' 'kernel26<2.6.29' 'iguanaIR')
+makedepends=('python')
+replaces=('lirc+pctv')
+options=('!makeflags')
+install=$pkgname.install
+source=(http://www.blushingpenguin.com/mark/lmilk/lirc-0.8.5-CVS-pvr150.tar.bz2 \
+	kernel-2.6.26.patch
+	kernel-2.6.27.patch
+	lirc_atiusb.patch
+	http://superb-east.dl.sourceforge.net/sourceforge/mod-mce/lirc_mod_mce-0.1.5.tar.bz2
+	lirc_mod_mce.patch
+	hw_commandir.c
+	hw_commandir.h
+	dvicoIR.rules
+        lirc.fdi)
+
+build() {
+	# configure
+	cd $startdir/src/lirc-0.8.5-CVS-pvr150 || return 1
+	cp $startdir/src/hw_commandir.* $startdir/src/lirc-0.8.5-CVS-pvr150/daemons
+#	patch -Np1 -i ../kernel-2.6.26.patch || return 1
+#	patch -Np1 -i ../kernel-2.6.27.patch || return 1
+	patch -Np1 -i ../lirc_atiusb.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 \
+	        --with-transmitter \
+		|| return 1
+
+	# disable parallel and bt829
+        # because of incompatibility with smp systems
+        sed -i -e "s:lirc_parallel::" -e "s:lirc_bt829::" \
+		Makefile drivers/Makefile drivers/*/Makefile tools/Makefile \
+                || return 1
+	# disable lirc_gpio due to brokeness of kernel 2.6.23
+	sed -i -e "s:lirc_gpio::" \
+		Makefile drivers/Makefile drivers/*/Makefile tools/Makefile \
+                || return 1
+
+	# build
+	cd drivers || return 1
+	make || return 1
+	make DESTDIR=$startdir/pkg install || return 1
+
+	# set the kernel we've built for inside the install script
+	sed -i -e "s/KERNEL_VERSION=.*/KERNEL_VERSION=${_kernver}/g" \
+		$startdir/lirc.install || return 1
+	cd $startdir/src/lirc_mod_mce
+	cp ../lirc-0.8.5-CVS-pvr150/drivers/lirc_dev/lirc_dev.h .
+	patch -p1 < ../lirc_mod_mce.patch
+	make KDIR=/usr/src/linux-2.6.28-LinHES/
+	cp lirc_mod_mce.ko $startdir/pkg/lib/modules/2.6.28-LinHES/kernel/drivers/misc/
+	mv $startdir/pkg/lib/modules/2.6.28-LinHES/kernel/drivers/misc/lirc_mceusb2.ko $startdir/pkg/lib/modules/2.6.28-LinHES/kernel/drivers/misc/lirc_mceusb2.ko.not
+	#remove old commandir
+	rm $startdir/pkg/lib/modules/$_kernver/kernel/drivers/misc/lirc_cmdir.ko
+	rm $startdir/pkg/lib/modules/$_kernver/kernel/drivers/misc/commandir.ko
+
+	# Add a udev rule for the DVICO remote so that if there is more than 
+	# one hiddev device, the system cant get confused.
+	install -D -m644 $srcdir/dvicoIR.rules $pkgdir/etc/udev/rules.d/dvicoIR.rules
+
+	# Add the fdi file to prevent the Dvico dual 4 remotes from screwing up keyboard interaction.
+	install -D -m644 $srcdir/lirc.fdi $pkgdir/usr/share/hal/fdi/preprobe/20thirdparty/lirc.fdi
+}
+md5sums=('b96dae91b566143b3af433fa2714ec9a'
+         '1753acd774f50b638e6173d364de53fd'
+         '6f151eb4e81fc7776a06c9063e6ad9a5'
+         '7eccd7826ab99e5cf1b9154171c8b927'
+         '21ce358809105f005e888e3b138c59e6'
+         'b5d52566a9dae8d76e24e8753f33abef'
+         'f059f4030afc682c9539a03bf837c1cf'
+         '4e698654cc44fc6c4163814acda5a7ee'
+         '9a3a6dc03647ee6674a166dfb884ddd6'
+         '203d9cd014c4276be4c84cecd103919d')
diff --git a/abs/core-testing/lirc_085/dvicoIR.rules b/abs/core-testing/lirc_085/dvicoIR.rules
new file mode 100644
index 0000000..ada5466
--- /dev/null
+++ b/abs/core-testing/lirc_085/dvicoIR.rules
@@ -0,0 +1,15 @@
+# This rule is for the Dvico Dual Digital 4 Rev 2. It has 2 IR modules 
+# identified, only the first of which is connected to the receiver.
+# The KERNELS=="*-1" part of this rule makes sure that the first 
+# device is the one that gets the symlink.
+KERNEL=="event*", \
+    KERNELS=="*-1", \
+    ATTRS{manufacturer}=="Dvico", \
+    ATTRS{idVendor}=="0fe9", \
+    ATTRS{idProduct}=="db98", \
+    SYMLINK="input/irremote"
+
+# This rule is for the older style USB DVICO remote dongles.
+SUBSYSTEMS=="usb", KERNEL=="hiddev*", \
+    ATTRS{product}=="DVICO USB HID Remocon V1.00", \
+    SYMLINK+="usb/dvicoIR"
diff --git a/abs/core-testing/lirc_085/hw_commandir.c b/abs/core-testing/lirc_085/hw_commandir.c
new file mode 100755
index 0000000..40ac0de
--- /dev/null
+++ b/abs/core-testing/lirc_085/hw_commandir.c
@@ -0,0 +1,1926 @@
+/* CommandIR transceivers driver 0.96
+ * Supporting CommandIR II and CommandIR Mini (and multiple of both)
+ * April-June 2008, Matthew Bodkin
+ * December 2008, bug fixes, Matthew Bodkin
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+
+#include "hardware.h"
+#include "ir_remote.h"
+#include "lircd.h"
+#include "receive.h"
+#include "transmit.h"
+#include "hw_commandir.h"
+#include <usb.h>
+
+#define RAPID_DECODE 1
+
+extern struct ir_remote *repeat_remote;
+extern char *progname;
+
+
+/**********************************************************************
+ *
+ * internal function prototypes
+ *
+ **********************************************************************/
+static int commandir_init();
+static int commandir_deinit(void);
+static char *commandir_rec(struct ir_remote *remotes);
+static void commandir_read_loop();
+static int cmdir_convert_RX(unsigned char *orig_rxbuffer);
+static unsigned int get_time_value(unsigned int firstint, 
+		unsigned int secondint, unsigned char overflow);
+static lirc_t commandir_readdata(lirc_t timeout);
+static int commandir_send(struct ir_remote *remote,struct ir_ncode *code);
+static int commandir_ioctl(unsigned int cmd, void *arg);
+//static void setEmitterMask(unsigned char highbyte, unsigned char lowbyte);
+static void setEmitterMask(int bitmask);
+static void commandir_transmit(char *buffer, int bytes, int bitmask, 
+		unsigned int);
+static void commandir_child_init();
+static void shutdown_usb();
+static void hardware_scan();
+static void hardware_disconnect(int);
+static void hardware_setorder();
+static void raise_event(unsigned int);
+static int commandir_read();
+static int check_irsend_commandir(unsigned char *command);
+static int commandir_decode(char *command);
+static int commandir_receive_decode(struct ir_remote *remote,
+                   ir_code *prep,ir_code *codep,ir_code *postp,
+                   int *repeat_flagp,
+                   lirc_t *min_remaining_gapp, lirc_t *max_remaining_gapp);
+static void pipeline_check();
+static int inline get_bit(int bitnum);
+static void add_to_tx_pipeline(unsigned char *buffer, int bytes, 
+		int channel_mask, unsigned int);
+static void recalc_tx_available(int);
+static void set_hash_mask(int channel_mask);
+static int commandir2_convert_RX(unsigned short *bufferrx, 
+		unsigned char numvalues);
+static void cleanup_commandir_dev(int spotnum);
+
+/**********************************************************************
+ *
+ * CommandIR Vars
+ *
+ **********************************************************************/
+static int current_transmitter_mask = 0xff;
+static char unsigned commandir_data_buffer[512];
+static int last_mc_time = -1;	
+static int commandir_rx_num = 0;
+
+
+static char channels_en[MAX_DEVICES]; 
+static char open_bus_hash[USB_MAX_BUSES][USB_MAX_BUSDEV];
+static int tx_order[MAX_DEVICES];
+static char device_count = 0;
+static int mini_freq[MAX_DEVICES];
+static int child_pipe_write = 0;
+static char haveInited = 0;
+// Fake 'commandir' remote signal values
+static unsigned int signal_base[2][2] = { {100|PULSE_BIT, 200},
+		 {1000|PULSE_BIT, 200} };
+
+// Pipes to and from the child/parent
+static pid_t child_pid = -1;
+static int pipe_fd[2] = { -1, -1 };
+static int pipe_tochild[2] = { -1, -1 };
+static int tochild_read = -1, tochild_write = -1;
+
+struct commandir_device
+{
+	usb_dev_handle *cmdir_udev;
+	int bus;
+	int busdev;
+	int interface;
+	int location;
+	int hw_type;
+	int hw_revision;
+	int hw_subversion;
+	unsigned char devnum;
+	int endpoint_max[3];
+} open_commandir_devices[4];
+
+struct hardware hw_commandir =
+{
+	NULL,					 	/* default device */
+	-1,                 		/* fd */
+	LIRC_CAN_SET_SEND_CARRIER|
+	LIRC_CAN_SEND_PULSE|
+	LIRC_CAN_SET_TRANSMITTER_MASK|
+	LIRC_CAN_REC_MODE2, 		
+	LIRC_MODE_PULSE,			/* send_mode */ 
+	LIRC_MODE_MODE2,            /* rec_mode */
+	sizeof(lirc_t),        		/* code_length in BITS */
+	commandir_init,       		/* init_func */
+	NULL,     			  		/* config_func */
+	commandir_deinit,     		/* deinit_func */
+	commandir_send,				/* send_func */
+ 	commandir_rec,        		/* rec_func  */
+	commandir_receive_decode,   /* decode_func */
+	commandir_ioctl,            /* ioctl_func */
+	commandir_readdata,		    /* readdata */
+	"commandir"
+};
+
+/***   LIRC Interface Functions - Non-blocking parent thread
+*/
+
+static int commandir_receive_decode(struct ir_remote *remote,
+                   ir_code *prep,ir_code *codep,ir_code *postp,
+                   int *repeat_flagp,
+                   lirc_t *min_remaining_gapp, lirc_t *max_remaining_gapp) {
+
+	int i;
+	i = receive_decode(remote,
+                   prep,codep,postp,
+                   repeat_flagp,
+                   min_remaining_gapp, max_remaining_gapp);
+
+	if(i > 0){
+		static char rx_char[3] = {3, 0, RXDECODE_HEADER_LIRC};
+		write(tochild_write, rx_char, 3);	
+	}
+	
+	return i;
+}
+
+
+static int commandir_init()
+{
+	long fd_flags;
+	if(haveInited){
+		static char init_char[3] = {3, 0, INIT_HEADER_LIRC};
+		write(tochild_write, init_char, 3);	
+		return 1;
+	}
+	
+	init_rec_buffer();	// LIRC's rec
+	init_send_buffer();	// LIRC's send
+	
+	/* A separate process will be forked to read data from the USB
+	 * receiver and write it to a pipe. hw.fd is set to the readable
+	 * end of this pipe. */
+	if (pipe(pipe_fd) != 0)
+	{
+		logprintf(LOG_ERR, "couldn't open pipe 1");
+		return 0;
+	}
+	
+	hw.fd = pipe_fd[0];	// the READ end of the Pipe
+	
+	if (pipe(pipe_tochild) != 0)
+	{
+		logprintf(LOG_ERR, "couldn't open pipe 1");
+		return 0;
+	}
+	
+	tochild_read = pipe_tochild[0];	// the READ end of the Pipe 
+	tochild_write = pipe_tochild[1];	// the WRITE end of the Pipe 
+	
+	fd_flags = fcntl(pipe_tochild[0], F_GETFL);
+  	if(fcntl(pipe_tochild[0], F_SETFL, fd_flags | O_NONBLOCK) == -1)
+	{
+		logprintf(LOG_ERR, "can't set pipe to non-blocking");
+		return 0;
+	}	
+	
+	child_pid= fork();
+	if (child_pid== -1)
+	{
+		logprintf(LOG_ERR, "couldn't fork child process");
+		return 0;
+	}
+	else if (child_pid== 0)
+	{
+		child_pipe_write = pipe_fd[1];	
+		commandir_child_init();
+		commandir_read_loop();
+		return 0;	
+	}
+	haveInited = 1;
+	
+	logprintf(LOG_ERR, "CommandIR driver initialized");
+	return 1;	
+}
+
+
+static int commandir_deinit(void)
+{
+	/* Trying something a bit new with this driver. Keeping the driver
+	 * connected so in the future we can still monitor in the client */
+	if(USB_KEEP_WARM && (!strncmp(progname, "lircd", 5)))
+	{
+		static char deinit_char[3] = {3, 0, DEINIT_HEADER_LIRC};
+		write(tochild_write, deinit_char, 3);
+		logprintf(LOG_ERR, "LIRC_deinit but keeping warm");
+	}
+	else
+	{
+		if (tochild_read >= 0)
+		{
+			if (close(tochild_read) < 0) 
+			{
+				logprintf(LOG_ERR, "Error closing pipe2");;
+			}
+			tochild_read = tochild_write = -1;
+		}
+		
+		if(haveInited){
+			// shutdown all USB
+			if(child_pid > 0)
+			{
+				logprintf(LOG_ERR, "Closing child process");
+				kill(child_pid, SIGTERM);
+				waitpid(child_pid, NULL, 0);
+				child_pid = -1;
+				haveInited = 0;
+			}
+		}
+		
+		if (hw.fd >= 0)
+		{
+			if (close(hw.fd) < 0) logprintf(LOG_ERR, "Error closing pipe");
+			hw.fd = -1;
+		}
+		
+		logprintf(LOG_ERR, "commandir_deinit()");
+	}
+	return(1);
+}
+
+static int commandir_send(struct ir_remote *remote,struct ir_ncode *code)
+{
+	int length;
+	lirc_t *signals;
+
+	if(!init_send(remote,code)) {
+		return 0;
+	}
+
+	length = send_buffer.wptr;
+	signals = send_buffer.data;
+
+	if (length <= 0 || signals == NULL) {
+		return 0;
+	}
+	
+	int cmdir_cnt =0;
+	char cmdir_char[70];
+	
+	// Set the frequency of the signal along with the signal + transmitters
+	cmdir_char[0] = 7;
+	cmdir_char[1] = 0;
+
+	cmdir_char[2] = FREQ_HEADER_LIRC;
+	cmdir_char[3] = (remote->freq >> 24) & (0xff);
+	cmdir_char[4] = (remote->freq >> 16) & (0xff);
+	cmdir_char[5] = (remote->freq >> 8) & (0xff);
+	cmdir_char[6] = (remote->freq & 0xff);
+	
+	write(tochild_write, cmdir_char, cmdir_char[0]);
+
+	cmdir_cnt = 3;
+	
+	unsigned char * send_signals = malloc(sizeof(signals) * length + 4);
+	
+	send_signals[0] = (sizeof(lirc_t) * length + 4) & 0xff;
+	send_signals[1] = ((sizeof(lirc_t) * length + 4) >> 8) & 0xff;
+	
+	send_signals[2] = TX_LIRC_T;
+	send_signals[3] = (char)current_transmitter_mask;	
+	
+	memcpy(&send_signals[4], signals, sizeof(lirc_t) * length);
+	
+	if(write(tochild_write, send_signals, 
+		send_signals[0] + send_signals[1] * 256) < 0)
+	{
+		logprintf(LOG_ERR, "Error writing to child_write");
+	}
+	
+	free(send_signals);
+	return(length);
+}
+
+static char *commandir_rec(struct ir_remote *remotes)
+{
+	char * returnit;
+	if (!clear_rec_buffer()) return NULL;
+	returnit = decode_all(remotes);
+	return returnit;
+}
+
+static int commandir_ioctl(unsigned int cmd, void *arg)
+{
+	unsigned int ivalue;
+	char cmdir_char[5];
+	
+	switch(cmd)
+	{
+	case LIRC_SET_TRANSMITTER_MASK:
+		
+		ivalue=*(unsigned int*)arg;
+		
+		if(ivalue >= MAX_MASK) return (MAX_CHANNELS);
+		
+		/* Support the old way of setting the frequency of the signal along 
+		 * with the signal + transmitters */
+		cmdir_char[0] = 5;
+		cmdir_char[1] = 0;
+		cmdir_char[2] = CHANNEL_EN_MASK;
+		cmdir_char[3] = (unsigned char)(ivalue & 0x00FF);	// Low bits
+		cmdir_char[4] = (unsigned char)(ivalue >> 8);		// High bits
+		
+		write(tochild_write, cmdir_char, cmdir_char[0]);
+
+		return (0);
+		
+	default:
+		logprintf(LOG_ERR, "Unknown ioctl - %d", cmd);
+		return(-1);
+	}
+	
+	return 1;
+}
+
+static lirc_t commandir_readdata(lirc_t timeout)
+{
+	lirc_t code = 0;
+	struct timeval tv = {0, timeout};
+	fd_set fds;
+
+	FD_ZERO(&fds);
+	FD_SET(hw.fd, &fds);
+
+	/* attempt a read with a timeout using select */
+	if (select(hw.fd + 1, &fds, NULL, &fds, &tv) > 0)
+		/* if we failed to get data return 0 */
+		if (read(hw.fd, &code, sizeof(lirc_t)) <= 0)
+                        commandir_deinit();
+	return code;
+}
+
+/***  End of parent fork / LIRC accessible functions  */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***  CommandIR Client Process Functions (Handle all USB operations)
+ */
+ 
+int channels_space_available[MAX_CHANNELS]; 
+int channels_space_updated = 0; // last updated time
+
+char * signalq[MAX_SIGNALQ];	// how many signals can be queued
+int signalq_len[MAX_SIGNALQ];
+int signalq_bitmask[MAX_SIGNALQ];
+unsigned int signalq_frequency[MAX_SIGNALQ];
+
+int top_signalq = -1;
+int next_signalq_per_channel[MAX_CHANNELS];	
+
+unsigned char commandir_tx_start[MAX_CHANNELS*4];
+unsigned char commandir_tx_end[MAX_CHANNELS*4];
+unsigned char commandir_tx_available[MAX_CHANNELS];
+unsigned char lastSendSignalID[MAX_CHANNELS];
+unsigned char commandir_last_signal_id[MAX_CHANNELS];
+
+
+// Global variables to convert channel masks to consistant easier formats
+unsigned char hash_mask[MAX_CHANNELS];
+unsigned char selected_channels[MAX_CHANNELS];
+unsigned char total_selected_channels = 0;
+int shutdown_pending = 0;
+int read_delay = WAIT_BETWEEN_READS_US;
+int insert_fast_zeros = 0;
+
+int rx_hold = 0;
+
+// This is the only one for pre-pipelinging
+int pre_pipeline_emitter_mask = 0x000f; // default tx on only first CommandIR
+
+
+static void pipeline_check()
+{
+	/* Transmit from the pipeline if it's time and there's space
+	 * what's available should now be updated in the main_loop
+	 */
+	
+	int i,j,k;
+	
+	i=0;
+	if(top_signalq < 0) return;
+	
+	while(i <= top_signalq)
+	{
+
+		// Are ALL the channels this signal should TX on currently available?
+		int oktosend = 1;
+		set_hash_mask( signalq_bitmask[ i ] );
+		for(j = 0; j<total_selected_channels; j++)
+		{
+			if(commandir_tx_available[ selected_channels[j] ] < 
+				(36 + (signalq_len[ i ])/sizeof(lirc_t)))	
+			{
+				oktosend = 0;
+				break;
+			}
+		}
+		
+		if(oktosend)
+		{
+			// great, TX this on all the channels.
+			
+			commandir_transmit(signalq[ i ], signalq_len[ i ], signalq_bitmask[ i ], signalq_frequency[ i ]);
+			
+			for(j = 0; j<total_selected_channels; j++)
+			{
+				/*  commandir_tx_available[ selected_channels[j] ] -= 
+					(64 + (signalq_len[ i ])/sizeof(lirc_t));  */
+				commandir_tx_available[ selected_channels[j] ] = 0; 
+			}
+			
+			/* Free up the memory, and see if there are new next_signalq's 
+			 * (any more for this channel to TX)
+			 */
+			free(signalq[i]);
+			
+			for(k=i; k<top_signalq; k++)
+			{
+				signalq[k] = signalq[k+1];
+				signalq_len[k] = signalq_len[k+1];
+				signalq_bitmask[k] = signalq_bitmask[k+1];
+				signalq_frequency[k] = signalq_frequency[k+1];
+			}
+			top_signalq--;
+		}
+		else
+		{
+			i++;
+		}
+	}
+}
+
+static int get_bit(int bitnum)
+{
+	int r = 1;
+	return r << bitnum; // bit 0 is 1, bit 1 is 10, bit 2 is 100...
+}
+
+static void add_to_tx_pipeline(unsigned char *buffer, int bytes, 
+	int channel_mask, unsigned int frequency)
+{
+	/* *buffer points to a buffer that will be OVERWRITTEN; malloc our copy.
+	 * buffer is a LIRC_T packet for CommandIR 
+	 */
+	top_signalq++;
+	if(top_signalq > MAX_SIGNALQ)
+	{
+		logprintf(LOG_ERR, "Too many signals in queue: > %d", MAX_SIGNALQ);
+		return;
+	}
+	
+	signalq[top_signalq] = malloc(bytes);
+	
+	signalq_len[top_signalq] = bytes;
+	signalq_bitmask[top_signalq] = channel_mask;
+	signalq_frequency[top_signalq] = frequency;
+	
+	lirc_t *oldsignal, *newsignal;
+	int x, pulse_now = 1;
+	int projected_signal_length;
+	short aPCAFOM = 0;
+	float afPCAFOM = 0.0;
+	int difference = 0;
+					
+	afPCAFOM = (6000000.0 / ((frequency > 0) ? frequency : DEFAULT_FREQ)  ) ; 
+	aPCAFOM = afPCAFOM;
+	
+	// Trim off mid-modulation pulse fragments, add to space for exact signals
+	for(x=0; x<(bytes/sizeof(lirc_t)); x++)
+	{
+		oldsignal = (lirc_t *)&buffer[x*sizeof(lirc_t)];
+		newsignal = (lirc_t *)signalq[top_signalq];
+		newsignal += x;
+		
+		if(pulse_now==1){
+			projected_signal_length =  
+				(((int)( (*oldsignal * 12)/( afPCAFOM ) ))  * aPCAFOM) / 12;
+			difference = *oldsignal - projected_signal_length;
+			// take off difference plus 1 full FOM cycle
+			*newsignal = *oldsignal - difference - (aPCAFOM / 12);	
+			
+		}
+		else
+		{
+			if(difference != 0)
+			{
+				// Add anything subtracted from the pulse to the space
+				*newsignal = *oldsignal + difference + (aPCAFOM / 12);
+				difference = 0;
+			}
+		
+		}
+		
+		pulse_now++;
+		if(pulse_now > 1) pulse_now = 0;
+	}
+	
+	return;
+}
+
+static void recalc_tx_available(int which_commandir)
+{
+	int i;
+	int length = 0;
+	static int failsafe = 0;
+	
+	if(lastSendSignalID[which_commandir] != 
+		commandir_last_signal_id[which_commandir])
+	{
+		/* INNOVATIONONE_FLAG:REMOVE  This will be removed pending testing
+		 * for a future release
+		 */
+		if(failsafe++ < 1000)
+		{
+			return;
+		}
+		logprintf(LOG_ERR, "Error: required the failsafe");
+	}
+	
+	failsafe = 0;
+	for(i=which_commandir*4; i<((which_commandir+1)*4); i++)
+	{
+		length = commandir_tx_end[i] - commandir_tx_start[i];
+		if(length < 0) length += 0xff;
+		
+		if(commandir_tx_available[i] < 0xff - length)
+			commandir_tx_available[i] = 0xff - length;
+			
+	}
+}
+
+static void set_hash_mask(int channel_mask) // eg, 8
+{
+	// bitwise set of hash_mask for easier coding...
+	int i,j;
+	j=channel_mask;
+	total_selected_channels = 0;
+	for(i=0; i<MAX_CHANNELS; i++)
+	{
+		hash_mask[i] = j & 0x01;
+		j = j >> 1;
+		if(hash_mask[i])
+			selected_channels[total_selected_channels++] = i;
+	}
+}
+
+
+static void commandir_transmit(char *buffer, int bytes, int bitmask, 
+	unsigned int frequency)
+{
+	/*** Send a TX command to 1 or more CommandIRs.
+	 * Keep in mind: TX frequency, TX channels, TX signal length, 
+	 * which CommandIR, & what hardware version
+	 */
+	
+	int send_status;
+	unsigned char packet[TX_BUFFER_SIZE];
+	/* So we know where there should be gaps between signals and more 
+	 * importantly, where there shouldn't be
+	 */
+	static char signalid = 1;	
+	
+	/* Depending on the tx channels, then depending on what hardware it is, 
+	 * set the freq if needed, and send the buffer with the channel header 
+	 * that's right for that CommandIR
+	 */
+	
+	int devicenum = 0;
+	int sent = 0, tosend = 0;
+	unsigned char mini_tx_mask = 0;
+	lirc_t * signals;	// have bytes/sizeof(lirc_t) signals
+	signals = (lirc_t *)buffer;
+	int total_signals = 0;
+	int i;
+	char cmdir_char[66];
+	int which_signal = 0;
+	
+	total_signals = bytes / sizeof(lirc_t);
+	
+	setEmitterMask(bitmask);
+	
+	for(devicenum = 0; devicenum < device_count; devicenum++)
+	{
+		// Do we transmit on any channels on this device?
+		if(channels_en[ devicenum ])
+		{
+			which_signal = 0;
+			switch(open_commandir_devices[ tx_order[devicenum] ].hw_type)
+			{
+				case HW_COMMANDIR_2:
+					
+					mini_tx_mask = 0;
+					// Short enough loop to unroll
+					if(channels_en[ devicenum ] & 1) mini_tx_mask |= 0x10;
+					if(channels_en[ devicenum ] & 2) mini_tx_mask |= 0x20;
+					if(channels_en[ devicenum ] & 4) mini_tx_mask |= 0x40;
+					if(channels_en[ devicenum ] & 8) mini_tx_mask |= 0x80;
+					
+					packet[1] = TX_COMMANDIR_II;
+					packet[2] = mini_tx_mask;
+					
+					short PCAFOM = 0;
+					float fPCAFOM = 0.0;
+					
+					if(bytes/sizeof(lirc_t) > 255)
+					{
+						logprintf(LOG_ERR, "Error: signal over max size");
+						continue; 
+					}
+					
+					fPCAFOM = (6000000 / ((frequency > 0) ? frequency : 
+						DEFAULT_FREQ)  ) ; 
+					PCAFOM = fPCAFOM;
+					
+					lastSendSignalID[  tx_order[devicenum]   ] = packet[5] = (getpid() + signalid++) + 1;	
+					
+					packet[4] = PCAFOM & 0xff;
+					packet[3] = (PCAFOM >> 8) & 0xff;					
+					
+					short packlets_to_send = 0, sending_this_time = 0;
+					
+					packlets_to_send = bytes / sizeof(lirc_t);
+					
+					int attempts;
+					for(attempts = 0; attempts < 10; attempts++)
+					{
+					
+						if((packlets_to_send*3 + 7) > open_commandir_devices[ tx_order[devicenum] ].endpoint_max[1])
+						{
+							sending_this_time = open_commandir_devices[ tx_order[devicenum] ].endpoint_max[1]/3 - 3;
+						}
+						else
+						{
+							sending_this_time = packlets_to_send;
+						}
+						int sending;
+
+						for(i=0; i<sending_this_time; i++)
+						{
+							sending = signals[which_signal++];
+							
+							packet[i*3+7] = sending >> 8; // high1
+							packet[i*3+8] = sending & 0xff; // low
+							packet[i*3+9] = sending >> 16 & 0xff; // high2
+						}
+						
+						packet[0] = (sending_this_time * 3 + 7);
+						packet[6] = (sending_this_time == packlets_to_send)  ? 0xcb :  0x00;
+						
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							(char*)packet,
+							packet[0], 
+							USB_TIMEOUT_MS);
+						if(send_status < 0)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return;
+						}
+						
+						packlets_to_send -= ((send_status - 7) / 3);
+						if(!packlets_to_send)
+						{
+							// "No more packlets to send\n"
+							break;
+						}
+					}
+					continue; // for transmitting on next CommandIR device
+					
+			
+				case HW_COMMANDIR_MINI:
+					mini_tx_mask = 0;
+					if(channels_en[ devicenum ] & 1) mini_tx_mask |= 0x80;
+					if(channels_en[ devicenum ] & 2) mini_tx_mask |= 0x40;
+					if(channels_en[ devicenum ] & 4) mini_tx_mask |= 0x20;
+					if(channels_en[ devicenum ] & 8) mini_tx_mask |= 0x10;
+					
+					char freqPulseWidth = DEFAULT_PULSE_WIDTH;
+					
+					freqPulseWidth = (unsigned char)((1000000 / 
+						((frequency > 0) ? frequency: DEFAULT_FREQ)  ) / 2);
+					
+					if(freqPulseWidth == 0)
+					{
+						freqPulseWidth = DEFAULT_PULSE_WIDTH;
+					}
+					
+					if(mini_freq[ tx_order[devicenum] ] != freqPulseWidth)
+					{
+						// Update the CommandIR Mini's next tx frequency
+						cmdir_char[0] = FREQ_HEADER;
+						cmdir_char[1] = freqPulseWidth;
+						cmdir_char[2] = 0;
+						mini_freq[ tx_order[devicenum] ] = freqPulseWidth;
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							cmdir_char,
+							2, // 2 bytes
+							USB_TIMEOUT_MS);
+						if(send_status < 2)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return ;
+						}
+ 					}
+					
+					unsigned int mod_signal_length=0;
+					
+					cmdir_char[0] = TX_HEADER_NEW;
+ 					cmdir_char[1] = mini_tx_mask;
+					
+					unsigned int hibyte, lobyte;
+
+					sent = 0;
+					which_signal = 0;
+					while(sent < (bytes / sizeof(lirc_t) * 2 ) )
+					{
+ 						tosend = (bytes / sizeof(lirc_t) * 2 ) - sent;
+						
+						if(tosend > (MAX_HW_MINI_PACKET - 2))
+						{
+							tosend = MAX_HW_MINI_PACKET - 2;
+						}
+						
+						for(i=0;i<(tosend/2);i++) // 2 bytes per CommandIR pkt
+						{
+							mod_signal_length = signals[which_signal++] >> 3;
+							hibyte = mod_signal_length/256;
+							lobyte = mod_signal_length%256;
+							cmdir_char[i*2+3] = lobyte;
+							cmdir_char[i*2+2] = hibyte;
+						}
+
+						send_status=usb_bulk_write(
+							open_commandir_devices[ tx_order[devicenum] ].cmdir_udev, 
+							2, // endpoint2
+							cmdir_char,
+							tosend + 2, 
+							USB_TIMEOUT_MS);
+						if(send_status < 1)
+						{
+							// Error transmitting.
+							hardware_scan();
+							return;
+						}
+						sent += tosend;
+					} // while unsent data
+					continue; // for transmitting on next CommandIR device
+				default:
+					logprintf(LOG_ERR, "Unknown hardware: %d", 
+						open_commandir_devices[tx_order[devicenum]].hw_type);
+			} // hardware switch()
+		} // if we should tx on this device
+	} // for each device we have
+}
+
+
+static void commandir_child_init()
+{
+	alarm(0);
+	signal(SIGTERM, shutdown_usb);
+	signal(SIGPIPE, SIG_DFL);
+	signal(SIGINT, shutdown_usb);
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGALRM, SIG_IGN);
+	
+	logprintf(LOG_ERR, "Child Initializing CommandIR Hardware");
+	
+	usb_init();
+	int i;
+	for(i=0;i<MAX_CHANNELS;i++)
+	{
+		next_signalq_per_channel[i] = -1;
+		channels_en[i] = 0xff;
+	}
+/*	
+	// Check kernel version: support fast decoding
+	char checkV[] = {0,0,0,0,0,0,0,0,0,0};
+	FILE * checkfile;
+	int kernel_major = 0, kernel_minor = 0;
+	
+	checkfile=fopen("/proc/sys/kernel/osrelease", "r");
+	if(checkfile!=NULL)
+	{
+		fgets(checkV, 7, checkfile);
+		printf("Checking: %s.\n", checkV);
+		printf("Version checking %s.\n", &checkV[4]);
+		kernel_major = atoi(&checkV[2]);
+		kernel_minor = atoi(&checkV[4]);
+		printf("Major is: %d, minor is %d.\n", kernel_major, kernel_minor);
+		fclose(checkfile);
+	}
+	
+	if(kernel_major < 6){
+		insert_fast_zeros = 0;
+		logprintf(LOG_ERR, "Fast decoding disabled");
+	}
+	else
+	{
+		if(kernel_minor <= 24)
+		{
+			logprintf(LOG_ERR, "Fast decoding enabled (1)");
+			insert_fast_zeros = 1;
+		}
+		else
+		{
+			logprintf(LOG_ERR, "Fast decoding enabled");
+			insert_fast_zeros = 2;
+		}
+	}*/
+	hardware_scan();
+}
+
+static void hardware_disconnect(int commandir_spot)
+{
+	/* We had a read/write error, try disconnecting it and force _scan to 
+	 * reconnect - otherwise we may get perpetual read/write errors
+	 */
+	
+	int x;
+	
+	//	reset the hash so we don't try and disconnect this device again
+	//  device_count is decremented here
+	cleanup_commandir_dev(commandir_spot);
+	
+	raise_event(COMMANDIR_UNPLUG_1 + commandir_spot);
+	
+	/* Cases are:
+	removing device 0 when there's no more device (do nothing)
+	removing device < MAX when there's still 1+ devices (patch up)
+	removing device==MAX when there's more devices (do nothing)
+	*/
+	
+	// new device count-- from cleanup (if device_count > 0 AND commandir removed isn't 0 or max)
+	if( (device_count > 0) && (commandir_spot != device_count) )
+	{
+		/* It wasn't the top device removed, and there's 
+			* more than 1 device, so we have some vars to patch up
+			*/
+		for(x=commandir_spot; x<(device_count); x++)
+		{
+			channels_en[x] = channels_en[x+1];
+			mini_freq[x] = mini_freq[x+1];
+			commandir_last_signal_id[x] = commandir_last_signal_id[x+1];
+			lastSendSignalID[x] = lastSendSignalID[x+1];
+			memcpy(&open_commandir_devices[x], 
+				&open_commandir_devices[x+1], 
+				sizeof(struct commandir_device));	
+		}
+	
+	// Reset the TOP one that was just removed:
+		channels_en[(int)device_count] = 0x0f;
+		mini_freq[(int)device_count] = -1;
+		commandir_last_signal_id[(int)device_count] = 0;
+		lastSendSignalID[(int)device_count] = 0;
+		open_commandir_devices[(int)device_count].cmdir_udev = 0;
+		open_commandir_devices[(int)device_count].bus = 0;
+		open_commandir_devices[(int)device_count].busdev = 0;
+		open_commandir_devices[(int)device_count].interface = 0; 
+		open_commandir_devices[(int)device_count].hw_type = 0;
+		open_commandir_devices[(int)device_count].hw_revision = 0;
+		open_commandir_devices[(int)device_count].hw_subversion = 0;
+		
+	}
+	
+	if(commandir_rx_num>=commandir_spot)
+	{
+		commandir_rx_num--;	
+	}
+
+	hardware_setorder();
+}
+
+static void hardware_setorder(){
+	/* Tried to order to the detected CommandIRs based on bus and dev ids
+		* so they remain the same on reboot.  Adding a new device in front
+		* will mean it becomes device 0 and emitters or scripts must be fixed
+		* Need a different param, these still change. 
+		*/
+		
+	tx_order[0] = tx_order[1] = tx_order[2] = tx_order[3] = 0; 
+	mini_freq[0] = mini_freq[1] = mini_freq[2] = mini_freq[3] = -1;
+	int largest = 0;
+	int tmpvals[4];
+	int x, tx_spots, find_spot;
+	
+	for(x=0; x<device_count; x++)
+	{
+		tmpvals[x] = 256 * open_commandir_devices[x].bus + 
+			open_commandir_devices[x].busdev;
+	}
+	
+	for(tx_spots = 0; tx_spots < device_count; tx_spots++)
+	{
+		largest = 0;
+		for(find_spot = 0; find_spot < device_count; find_spot++)
+		{
+			if(tmpvals[find_spot] > tmpvals[largest])
+			{
+				largest = find_spot;
+			}
+		}
+		tx_order[device_count - tx_spots - 1 ] = largest;
+		tmpvals[largest] = 0;
+	}
+	
+	
+	// The formerly receiving CommandIR has been unplugged
+	if(commandir_rx_num < 0)
+	{
+		if(device_count > 0)
+			commandir_rx_num = 0;
+	}
+	
+	// Clear all pending signals
+	for(x=top_signalq; x >= 0; x--)
+	{
+		free(signalq[top_signalq]);
+	}
+	top_signalq = -1;
+	
+}
+
+static void cleanup_commandir_dev(int spotnum)
+{
+	int location, devnum;
+
+	location = open_commandir_devices[spotnum].location;
+	devnum = open_commandir_devices[spotnum].devnum;
+
+  open_bus_hash[ location ][ devnum ] = 0;
+	device_count--;	
+  
+	if(open_commandir_devices[spotnum].cmdir_udev==NULL)
+	{
+		return;
+	}
+	usb_release_interface(open_commandir_devices[spotnum].cmdir_udev, 
+		open_commandir_devices[spotnum].interface);
+	usb_close(open_commandir_devices[spotnum].cmdir_udev);
+	open_commandir_devices[spotnum].cmdir_udev = NULL;
+}
+
+
+static void hardware_scan()
+{
+	// Scan for hardware changes; libusb doesn't notify us...
+	unsigned char located = 0;
+	struct usb_bus *bus = 0;
+	struct usb_device *dev = 0;
+	
+	int scan_find[MAX_DEVICES][2]; // [0]=bus#, [1]=busdev#
+	unsigned char found = 0;
+	// Using hash for performance instead of memory conservation (+1k)
+	unsigned char still_found[USB_MAX_BUSES][USB_MAX_BUSDEV];
+	unsigned changed = 0;
+	int find_spot = 0;
+	
+	usb_find_busses();
+	usb_find_devices();
+ 	
+ 	for (bus = usb_busses; bus; bus = bus->next)
+	{
+		for (dev = bus->devices; dev; dev = dev->next)	
+		{
+			if (dev->descriptor.idVendor == USB_CMDIR_VENDOR_ID) 
+			{
+				located++;
+				// Do we already know about it?
+				if(!open_bus_hash[bus->location][dev->devnum]){
+				  // Then it's new, open it if we have a spot available
+				  for(find_spot=0; find_spot < MAX_DEVICES; find_spot++)
+				  {
+					if(open_commandir_devices[find_spot].cmdir_udev == NULL)
+					{
+					  // Try to open here
+					  open_commandir_devices[find_spot].cmdir_udev = usb_open(dev);
+					  if(open_commandir_devices[find_spot].cmdir_udev == NULL)
+					  {
+						logprintf(LOG_ERR, 
+						  "Error opening commandir - bus %d, device %d.",
+						  bus, dev);
+						  break;
+						}
+						else 
+						{
+						  
+						// Try to set configuration; not needed on Linux
+// 						int usb_set_configuration(usb_dev_handle *dev, int configuration);
+ 							int r = 0;
+// 							r = usb_set_configuration(open_commandir_devices[find_spot].cmdir_udev, 1);
+// 						printf("Set_configuration returned %d.\n", r);
+						  
+						  r = usb_claim_interface(
+						  	open_commandir_devices[find_spot].cmdir_udev,0);
+						  if(r < 0)
+						  {
+						  	cleanup_commandir_dev(find_spot);
+								logprintf(LOG_ERR, 
+								"Unable to claim CommandIR - Is it already busy?"
+								);
+								logprintf(LOG_ERR, 
+								"Try 'rmmod commandir' or check for other lircds"
+								);
+								break;
+						  }
+						  else 
+						  {
+							// great, it's ours
+							open_commandir_devices[find_spot].location = bus->location;
+							open_commandir_devices[find_spot].devnum = dev->devnum;
+							open_bus_hash[bus->location][dev->devnum] = 1;
+							open_commandir_devices[find_spot].bus = bus->location;
+							open_commandir_devices[find_spot].busdev = dev->devnum;
+							scan_find[++found][0] = bus->location;
+							scan_find[found][1] = dev->devnum;
+							device_count++;
+							changed++;
+							still_found[bus->location][dev->devnum] = 1;	
+							 
+							struct usb_config_descriptor *config = &dev->config[0];
+							struct usb_interface *interface = &config->interface[0];
+							struct usb_interface_descriptor *ainterface = &interface->altsetting[0];
+/*						struct usb_endpoint_descriptor *endpoint = &ainterface->endpoint[2];*/
+							
+							int i;// Load wMaxPacketSize for each endpoint; subtract 0x80 
+										// for double-buffer bit
+							for (i = 0; i < ainterface->bNumEndpoints; i++)
+							{
+								open_commandir_devices[find_spot].endpoint_max[ 
+									(ainterface->endpoint[i].bEndpointAddress >= 0x80) 
+									? (ainterface->endpoint[i].bEndpointAddress-0x80) 
+									: (ainterface->endpoint[i].bEndpointAddress)] 
+									= ainterface->endpoint[i].wMaxPacketSize;
+							}
+							
+							// compensate for double buffer:
+							open_commandir_devices[find_spot].endpoint_max[1] *= 2;
+							
+							// Always use the latest to RX:
+							commandir_rx_num = find_spot;	
+							
+							switch(dev->descriptor.iProduct)
+							{
+							 case 2:
+							 	logprintf(LOG_ERR, "Product identified as CommandIR II");
+							 	open_commandir_devices[find_spot].hw_type = HW_COMMANDIR_2;
+							  open_commandir_devices[find_spot].hw_revision = 0;
+							  open_commandir_devices[find_spot].hw_subversion = 0;
+							  
+							  int send_status = 0, tries=20;
+							  static char get_version[] = {2, GET_VERSION};
+
+								send_status = 4;	// just to start the while()
+								
+								while(tries--){
+									usleep(USB_TIMEOUT_US);	// wait a moment
+										
+									// try moving this below:
+									send_status = usb_bulk_write(
+									open_commandir_devices[find_spot].cmdir_udev, 
+										2, // endpoint2
+										get_version,
+										2, 
+										1500);
+									if(send_status < 0)
+									{
+										logprintf(LOG_ERR, 
+											"Unable to write version request - Is CommandIR busy? Error %d", send_status);
+										break;
+									}
+									
+									send_status = usb_bulk_read(
+										open_commandir_devices[find_spot].cmdir_udev,
+										1,
+										(char *)commandir_data_buffer,
+										open_commandir_devices[ find_spot ].endpoint_max[1],
+										1500);
+										
+									if(send_status < 0)
+									{
+										logprintf(LOG_ERR, 
+											"Unable to read version request - Is CommandIR busy? Error %d", send_status);
+										cleanup_commandir_dev(find_spot);
+										break;
+									}
+									if(send_status==3)
+									{
+										if(commandir_data_buffer[0]==GET_VERSION)
+										{
+											// Sending back version information.
+											open_commandir_devices[find_spot].hw_revision = 
+												commandir_data_buffer[1];
+											open_commandir_devices[find_spot].hw_subversion = 
+												commandir_data_buffer[2];
+											logprintf(LOG_ERR, "Hardware revision is %d.%d.", 
+												commandir_data_buffer[1], commandir_data_buffer[2]);
+											break;
+										}
+										else
+										{
+											continue;
+										}
+									}
+									
+							}
+							break;
+							default:
+								logprintf(LOG_ERR, "Product identified as CommandIR Mini");
+   							open_commandir_devices[find_spot].hw_type = 
+								HW_COMMANDIR_MINI;
+							}
+							
+							if(open_commandir_devices[find_spot].hw_type == 
+								HW_COMMANDIR_UNKNOWN)
+							{
+								logprintf(LOG_ERR, "Product UNKNOWN - cleanup");
+								cleanup_commandir_dev(find_spot);
+							}
+							else
+							{
+								lastSendSignalID[find_spot] = 0;
+								commandir_last_signal_id[find_spot] = 0;
+							}
+							break; // don't keep looping through find_spot
+							} // claim?
+						}// open?
+					}// spot available?
+				 }// for(spots)
+				} // if we haven't seen it before
+				else
+				{
+					still_found[bus->location][dev->devnum] = 1;
+				}
+			}// if it's a CommandIR
+		}// for bus dev's
+	}// for bus's
+	
+	if(!located)
+	{
+		logprintf(LOG_ERR, "No CommandIRs found");
+	}
+	
+	/* Check if any we currently know about have been removed
+	 * (Usually, we get a read/write error first)
+	 */
+	for(find_spot = 0; find_spot < MAX_DEVICES; find_spot++)
+	{
+		if(open_commandir_devices[find_spot].cmdir_udev != NULL)
+		{
+			if(still_found[open_commandir_devices[find_spot].location]
+				[open_commandir_devices[find_spot].devnum] != 1)
+			{
+				logprintf(LOG_ERR, "Commandir %d removed from [%d][%d].", find_spot,open_commandir_devices[find_spot].location, open_commandir_devices[find_spot].devnum);
+				raise_event(COMMANDIR_UNPLUG_1 + find_spot);
+				hardware_disconnect(find_spot);
+				commandir_rx_num = -1;
+				changed++;
+			}
+		}
+	}
+	
+	if(changed)
+	{
+		hardware_setorder();
+		raise_event(COMMANDIR_REORDERED);
+	}
+	
+}
+
+
+// Shutdown everything and terminate 
+static void shutdown_usb()
+{
+	int x;
+	
+	// Wait for any TX to complete before shutting down
+	if(top_signalq >= 0)
+	{
+		shutdown_pending++;
+		logprintf(LOG_ERR, "Waiting for signals to finish transmitting before shutdown");
+		return;
+	}
+	
+	for(x=0; x<MAX_DEVICES; x++)
+	{
+		if(open_commandir_devices[x].cmdir_udev )
+		{
+			usb_release_interface(open_commandir_devices[x].cmdir_udev, 
+				open_commandir_devices[x].interface);
+			usb_close(open_commandir_devices[x].cmdir_udev);
+		}
+	}
+	logprintf(LOG_ERR, "CommandIR driver child cleaned up and exiting");
+	raise_event(COMMANDIR_STOPPED);
+
+	_exit(EXIT_SUCCESS);
+}
+
+static void commandir_read_loop()
+{
+	// Read from CommandIR, Write to pipe
+	
+	unsigned char commands[MAX_COMMAND];
+	int curCommandStart = 0;
+	int curCommandLength = 0;
+	int bytes_read;
+	unsigned char periodic_checks = 0;
+	static unsigned char rx_decode_led[7] = {7, PROC_SET, 0x40, 0, 0,4, 2}; 
+	static unsigned char init_led[7] = {7, PROC_SET, 0x00, 0x01, 3, 55, 2}; 
+	static unsigned char deinit_led[7] = {7, PROC_SET, 0x0, 0x02, 3, 45, 2}; 
+	static unsigned int LIRC_frequency = 38000; 
+
+	int send_status = 0; 
+	int i = 0;
+	int tmp = 0;
+	int tmp2 = 0;
+
+	raise_event(COMMANDIR_READY);
+	
+	for(;;){
+		/*** This is the main loop the monitors control and TX events from 
+		  * the parent, and monitors the CommandIR RX buffer
+		  */
+		
+		curCommandStart = 0;
+		curCommandLength = 0;
+		bytes_read = read(tochild_read, commands, MAX_COMMAND); 
+		
+		if(shutdown_pending > 0 && (top_signalq==-1))
+			shutdown_usb();
+		
+		if(bytes_read > 0){
+		
+			while(curCommandStart < bytes_read){
+				curCommandLength = commands[curCommandStart] + 
+					commands[curCommandStart + 1] * 256;
+				
+				switch(commands[curCommandStart + 2]){	// the control value
+					case DEINIT_HEADER_LIRC:
+						for(i=0; i<device_count; i++)
+						{
+						 if(open_commandir_devices[tx_order[i]].hw_type ==
+						  HW_COMMANDIR_2)
+						 {
+						  if(open_commandir_devices[tx_order[i]].cmdir_udev > 0)
+						  {
+							send_status=usb_bulk_write(
+								open_commandir_devices[tx_order[i]].cmdir_udev, 
+								2, // endpoint2
+								(char*)deinit_led,
+								7, // bytes
+								USB_TIMEOUT_MS);
+						  }
+						  rx_hold = 1;	// Put a hold on RX, but queue events
+						 }
+						}
+						
+						break;
+					case INIT_HEADER_LIRC:
+						for(i=0; i<device_count; i++)
+						{
+						 if(open_commandir_devices[tx_order[i]].hw_type == 
+							HW_COMMANDIR_2)
+						 {
+						 if(open_commandir_devices[tx_order[i] ].cmdir_udev > 0)
+						  {
+							send_status=usb_bulk_write(
+								open_commandir_devices[tx_order[i] ].cmdir_udev,
+								2, // endpoint2
+								(char*)init_led,
+								7, // bytes
+								USB_TIMEOUT_MS);
+						  }
+						  rx_hold = 0;	// Resume RX after queue events
+						 }
+						}
+						break;
+					case RXDECODE_HEADER_LIRC:
+					  //	Successful RX decode: show it on the light.
+					  if(open_commandir_devices[commandir_rx_num].cmdir_udev > 0)
+					  {
+						send_status=usb_bulk_write(
+							open_commandir_devices[commandir_rx_num].cmdir_udev,
+							2, // endpoint2
+							(char*)rx_decode_led,
+							7, // bytes
+							USB_TIMEOUT_MS);
+
+					  }
+					  break;
+
+					case FREQ_HEADER_LIRC:
+						LIRC_frequency = (commands[curCommandStart + 6] & 0x000000ff) | 
+							((commands[curCommandStart + 5] << 8) & 0x0000ff00) | 
+							((commands[curCommandStart + 4] << 16) & 0x00ff0000) | 
+							((commands[curCommandStart + 3] << 24) & 0xff000000);
+						if(!LIRC_frequency)
+							LIRC_frequency = DEFAULT_FREQ;
+						break;
+					case TX_HEADER_NEW:
+					case TX_LIRC_T:
+						if(curCommandLength==64)
+						{
+							if(check_irsend_commandir(&commands[curCommandStart + 4]))
+							{
+								break; // it's a command for us
+							}
+						}
+						add_to_tx_pipeline(&commands[curCommandStart + 4], 
+							curCommandLength - 4, pre_pipeline_emitter_mask, LIRC_frequency);
+						break;
+						
+					case CHANNEL_EN_MASK:
+						pre_pipeline_emitter_mask = (commands[curCommandStart+4] << 8) |
+							 commands[curCommandStart+3];
+						break;
+				}
+				curCommandStart += curCommandLength;
+			
+			}
+		}
+		// If we're receiving, make sure the commandir buffer doesn't overrun
+		if(commandir_read() < 20 )
+			tmp = 2;
+		while(tmp-- > 0)
+		{
+			tmp2 = commandir_read();
+// 		printf("commandir_read() (%d) returning %d.\n", tmp,tmp2);
+		}
+		if(tmp2 < 20 ){
+			// once in a while, but never while we're retreaving a signal
+			if(++periodic_checks>100)
+			{
+				hardware_scan();
+				periodic_checks = 0;
+			}
+			else
+			{
+ 				usleep(read_delay);
+ 			}
+		}
+	}
+
+}
+
+static int check_irsend_commandir(unsigned char *command)
+{
+	// decode the code like LIRC would do, and take an action
+	int commandir_code = 0;
+	
+	commandir_code = commandir_decode((char*)command);
+	
+	if(commandir_code > 0xef)
+	{
+		// It's a settransmitters command
+		int channel = commandir_code & 0x0f;
+		
+		// can only set 1 bit from here so far..,
+		pre_pipeline_emitter_mask = 0x0001 << channel;	
+		
+		return commandir_code;
+	}
+	
+	switch(commandir_code)
+	{
+		case 0x53:
+			read_delay /= 2;	// "faster" means less time
+			if(read_delay < MIN_WAIT_BETWEEN_READS_US)
+				read_delay = MIN_WAIT_BETWEEN_READS_US;
+			break;
+		case 0x54:
+			read_delay *= 2;	// "slower" means more time
+			if(read_delay > MAX_WAIT_BETWEEN_READS_US)
+				read_delay = MAX_WAIT_BETWEEN_READS_US;
+			break;
+	
+		case 0x09: 
+		case 0x0A:
+			logprintf(LOG_ERR, "Re-selecting RX not implemented yet");
+			break;
+			
+		case 0xe6:	//	disable-fast-decode
+			logprintf(LOG_ERR, "Fast decoding disabled");
+			insert_fast_zeros = 0;
+			break;
+			
+		case 0xe7:	//	enable-fast-decode
+		case 0xe9:	//	force-fast-decode-2
+			logprintf(LOG_ERR, "Fast decoding enabled");
+			insert_fast_zeros = 2;
+			break;
+		
+		case 0xe8:	//	force-fast-decode-1
+			logprintf(LOG_ERR, "Fast decoding enabled (1)");
+			insert_fast_zeros = 1;
+			break;
+			
+		default:
+			if(commandir_code > 0x60 && commandir_code < 0xf0)
+			{
+				int ledhigh = 0, ledlow = 0, ledprog = -1;
+				// LED Command
+				switch(commandir_code >> 4)
+				{
+					case 0x6: ledlow = 0x80; break;
+					case 0x7: ledlow = 0x40; break;
+					case 0x8: ledlow = 0x20; break;
+					case 0x9: ledlow = 0x10; break;
+					case 0xa: ledlow = 0x04; break;
+					case 0xb: ledhigh = 0x80; break;
+					case 0xc: ledlow = 0x01; break;
+					case 0xd: ledlow = 0x02; break;
+					case 0xe: ledlow = 0x08; break;
+				}
+				ledprog = (commandir_code & 0x0f) - 1;
+				
+				if( ((ledhigh + ledlow) > 0) && ledprog > -1)
+				{
+					//	Set light:
+					static unsigned char lightchange[7] = {7, 
+					PROC_SET, 0, 0, 0, 0, 3}; 
+					lightchange[2] = ledhigh;
+					lightchange[3] = ledlow;
+					lightchange[4] = ledprog;
+					int send_status = 0; 
+					
+					send_status=usb_bulk_write(
+						open_commandir_devices[tx_order[0]].cmdir_udev, 
+						2, // endpoint2
+						(char *)lightchange,
+						7, // bytes
+						USB_TIMEOUT_MS);
+				}
+				
+				return commandir_code; // done
+			}
+		
+	}
+
+	return commandir_code;
+}
+
+
+// return how many RX's were in the last receive; so we know whether to poll more frequently or not
+static int commandir_read() 
+{
+	
+	/***  Which CommandIRs do we have to read from?  Poll RX CommandIRs 
+		* regularly, but non-receiving CommandIRs should be more periodically
+		*/
+	
+	int i,j;
+	int read_received = 0;
+	int read_retval = 0;
+	int conv_retval = 0;
+	int max_read = 5;
+	static int zeroterminated = 0;
+
+	for(i=0; i<device_count; i++)
+	{
+	
+		switch(open_commandir_devices[tx_order[i]].hw_type)
+		{
+			case HW_COMMANDIR_2:
+		
+				read_retval = usb_bulk_read(
+					open_commandir_devices[ tx_order[i] ].cmdir_udev,
+					1,
+					(char *)commandir_data_buffer,
+					open_commandir_devices[ tx_order[i] ].endpoint_max[1],
+					5000);	
+					
+				if(read_retval==0)
+					break;
+				
+				if(read_retval < 1)
+				{
+					if(read_retval < 0)
+					{
+						if(read_retval == -19){
+							logprintf(LOG_ERR, "Read Error - CommandIR probably unplugged");
+						}
+						else
+						{
+							logprintf(LOG_ERR, 
+								"Didn't receive a full packet from a CommandIR II! - err %d ."
+								, read_retval);
+						}
+						hardware_disconnect(tx_order[i]);
+						hardware_scan();
+					}
+					// 0 bytes is the most frequency case; nothing to report
+
+					break;
+				} 
+				
+				if(commandir_data_buffer[0]==RX_HEADER_TXAVAIL)
+				{
+					// sending us the current tx_start, tx_end arrays, and where it's at
+					commandir_tx_start[tx_order[i]*4] = commandir_data_buffer[4];
+					commandir_tx_start[tx_order[i]*4+1] = commandir_data_buffer[3];
+					commandir_tx_start[tx_order[i]*4+2] = commandir_data_buffer[2];
+					commandir_tx_start[tx_order[i]*4+3] = commandir_data_buffer[1];
+					
+					commandir_tx_end[tx_order[i]*4] = commandir_data_buffer[8];
+					commandir_tx_end[tx_order[i]*4+1] = commandir_data_buffer[7];
+					commandir_tx_end[tx_order[i]*4+2] = commandir_data_buffer[6];
+					commandir_tx_end[tx_order[i]*4+3] = commandir_data_buffer[5];
+					
+					commandir_last_signal_id[ tx_order[i] ] = commandir_data_buffer[9];
+					
+					recalc_tx_available(tx_order[i]); 
+					pipeline_check();
+					if(top_signalq > 0)
+					{
+						read_received++;	
+					}
+					
+					// This ALSO implies there's NO MORE RX DATA.
+					lirc_t lirc_zero_buffer[2] = {0, 0};
+					
+					int tmp4 = 0;
+					if(zeroterminated>1001)
+					{
+						// Send LIRC a 0,0 packet to allow IMMEDIATE decoding
+						if(insert_fast_zeros > 0)
+						{
+							tmp4 = write(child_pipe_write, lirc_zero_buffer, sizeof(lirc_t)*insert_fast_zeros);
+						}
+						zeroterminated = 0;
+					}
+					else
+					{
+						if((zeroterminated < 1000) && (zeroterminated > 0))
+							zeroterminated += 1000;
+						if(zeroterminated > 1000)
+							zeroterminated++;
+					}
+					
+					break;
+				}
+						
+						
+				if(commandir_data_buffer[0]==RX_HEADER_EVENTS)
+				{
+					for(j=1; j<(read_retval); j++)
+					{
+						raise_event(commandir_data_buffer[j]+tx_order[i]*0x10);
+					}
+				}
+				else
+				{
+					if( (commandir_data_buffer[0]==RX_HEADER_DATA) && 
+						(commandir_rx_num==tx_order[i]) )
+					{
+						if(rx_hold==0)	// Only if we should be listening for remote cmds
+						{
+							zeroterminated = 1;
+							conv_retval = commandir2_convert_RX(
+								(unsigned short *)&commandir_data_buffer[2], 
+								commandir_data_buffer[1]);
+							read_received = conv_retval; // header
+						}
+					}
+				}
+				break;
+			
+			case HW_COMMANDIR_MINI:
+			
+				max_read = 5;
+				while(max_read--){
+					
+					read_retval = usb_bulk_read(
+						open_commandir_devices[ tx_order[i] ].cmdir_udev,
+						1,
+						(char *)commandir_data_buffer,
+						64,
+						USB_TIMEOUT_MS);
+							
+					if (!(read_retval == MAX_HW_MINI_PACKET)) 
+					{
+						if(read_retval == -19){
+							logprintf(LOG_ERR, "Read Error - CommandIR probably unplugged");
+						}
+						else
+						{
+							logprintf(LOG_ERR, 
+								"Didn't receive a full packet from a Mini! - err %d ."
+								, read_retval);
+						}
+						
+						hardware_disconnect(tx_order[i]);
+						hardware_scan();
+						break; 
+					}
+
+					
+					if ( (commandir_data_buffer[1] > 0)  && 
+						(commandir_rx_num==tx_order[i]) ) 
+					{
+						conv_retval = cmdir_convert_RX(commandir_data_buffer);
+						
+						read_received += commandir_data_buffer[1];					
+						
+						if(commandir_data_buffer[1] < 20)
+						{
+							// Lots of hardware buffer room left; don't tie up CPU
+							break;
+						}
+					}
+					else
+					{
+						break;
+					}
+				} // while; should only repeat if there's more RX data
+				
+				/* CommandIR Mini only has 1 buffer  */
+				commandir_tx_start[tx_order[i]*4] = 0;
+				commandir_tx_start[tx_order[i]*4+1] = 0;
+				commandir_tx_start[tx_order[i]*4+2] = 0;
+				commandir_tx_start[tx_order[i]*4+3] = 0;
+				
+				commandir_tx_end[tx_order[i]*4] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+1] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+2] = commandir_data_buffer[2];
+				commandir_tx_end[tx_order[i]*4+3] = commandir_data_buffer[2];
+				
+				/* .. and it can't pipeline... */
+				commandir_last_signal_id[i] = lastSendSignalID[i];
+				recalc_tx_available(tx_order[i]); 
+				pipeline_check();
+				break;
+			case HW_COMMANDIR_UNKNOWN:
+					break;
+		} // end switch
+	} // for each attached hardware device
+	return read_received;
+}
+
+static void setEmitterMask(int bitmask)
+{
+	channels_en[0] = bitmask & 0x0F;
+	channels_en[1] = (bitmask >> 4) & 0xfF;
+	channels_en[2] = (bitmask >> 8) & 0xfF;
+	channels_en[3] = (bitmask >> 12) & 0xfF;
+}
+
+
+static int commandir2_convert_RX(unsigned short *bufferrx, 
+	unsigned char numvalues)
+{
+	// convert hardware timestamp values to elapsed time values
+	
+	int i;
+	int curpos = 0;
+	int bytes_w = 0;
+	lirc_t lirc_data_buffer[256];	
+	
+	i=0;
+	int pca_count = 0;
+	int overflows = 0;
+	
+	while(curpos < numvalues )
+	{
+		pca_count = (bufferrx[curpos] & 0x3fff) << 2; 
+		pca_count = pca_count / 12;
+		
+		if(bufferrx[curpos] & COMMANDIR_2_OVERFLOW_MASK)
+		{
+			overflows = bufferrx[curpos+1];
+			lirc_data_buffer[i] =  pca_count + (overflows * 0xffff / 12);
+			
+			if(bufferrx[curpos] & COMMANDIR_2_PULSE_MASK)
+			{
+				lirc_data_buffer[i] |= PULSE_BIT;
+			}
+			curpos++;
+		
+		}
+		else
+		{
+			lirc_data_buffer[i] = pca_count;
+			if(bufferrx[curpos] & COMMANDIR_2_PULSE_MASK)
+			{
+				lirc_data_buffer[i] |= PULSE_BIT;
+			}
+		}
+		
+		curpos++;
+		i++;
+		if(i> 255)
+		{
+			break;
+		}
+	}
+		
+ 	bytes_w = write(child_pipe_write, lirc_data_buffer, sizeof(lirc_t)*i);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+		return 0;
+	}	
+	
+	return bytes_w;
+}
+
+
+
+
+// Originally from lirc_cmdir.c
+static int cmdir_convert_RX(unsigned char *orig_rxbuffer)
+{
+	unsigned int num_data_values = 0;
+	unsigned int num_data_bytes = 0;
+	unsigned int asint1 = 0, asint2 = 0, overflows = 0;
+	int i;
+	int bytes_w;	// Pipe write
+	lirc_t lirc_data_buffer[256];	
+	
+
+	num_data_bytes = orig_rxbuffer[1];
+	
+	/* check if num_bytes is multiple of 3; if not, error  */
+	if (num_data_bytes%3 > 0) return -1;
+	if (num_data_bytes > 60) return -3; 
+	if (num_data_bytes < 3) return -2;
+	
+	num_data_values = num_data_bytes/3;
+	
+	asint2 = orig_rxbuffer[3] + orig_rxbuffer[4] * 0xff;
+	if(last_mc_time==-1)
+	{
+		// The first time we run there's no previous time value
+		last_mc_time = asint2 - 110000;	
+		if(last_mc_time < 0) last_mc_time+=0xffff;
+	}
+	
+	asint1 = last_mc_time;
+	overflows = orig_rxbuffer[5];
+	
+	for(i=2; i<num_data_values+2; i++)
+	{
+		if(overflows < 0xff)
+		{
+			// space
+			lirc_data_buffer[i-2] = get_time_value(asint1,
+				 asint2, overflows) - 26;
+		} 
+		else 
+		{	// pulse
+			lirc_data_buffer[i-2] = get_time_value(asint1,
+				 asint2, 0) + 26;
+			lirc_data_buffer[i-2] |= PULSE_BIT;
+		}	
+		asint1 = asint2; 
+		asint2 = orig_rxbuffer[i*3] + orig_rxbuffer[i*3+1] * 0xff;
+		overflows = orig_rxbuffer[i*3+2];	
+	}
+	last_mc_time = asint1;
+	
+	
+ 	bytes_w = write(child_pipe_write, lirc_data_buffer, sizeof(lirc_t)*num_data_values);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+		goto done;
+	}	
+	
+done:
+	return bytes_w;
+
+}
+
+
+
+
+static unsigned int get_time_value(unsigned int firstint, 
+	unsigned int secondint, unsigned char overflow) 
+{	
+	/* get difference between two MCU timestamps, CommandIR Mini version  */
+	unsigned int t_answer = 0;
+	
+	if (secondint > firstint) 
+	{
+		t_answer = secondint - firstint + overflow*0xffff;
+	} 
+	else 
+	{
+		if (overflow > 0) 
+		{
+			t_answer = (65536 - firstint) + secondint + (overflow - 1)*0xffff - 250;
+		} 
+		else 
+		{
+			t_answer = (65536 - firstint) + secondint;
+		}
+	}
+
+	/* clamp to long signal  */
+	if (t_answer > 16000000) t_answer = PULSE_MASK;
+	return t_answer;
+}
+
+
+static void raise_event(unsigned int eventid)
+{
+	/* Raise an LIRC Event by
+	 * Generating lirc_t Pattern
+	 */
+	static lirc_t event_data[18] = {LIRCCODE_GAP, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	int i, bytes_w;
+
+	// 	logprintf(LOG_ERR, "Raising event %d", eventid);
+	for(i=0; i<8; i++)
+	{
+		if( (eventid & 0x80) )
+		{
+			event_data[i*2+1] = signal_base[0][0];
+			event_data[i*2+2] = signal_base[0][1];
+		}
+		else
+		{
+			event_data[i*2+1] = signal_base[1][0];
+			event_data[i*2+2] = signal_base[1][1];
+		}
+		eventid = eventid << 1;
+	}
+	
+ 	event_data[16] = LIRCCODE_GAP*4;
+ 	
+ 	bytes_w = write(child_pipe_write, event_data, sizeof(lirc_t) * 17);
+	
+	if (bytes_w < 0)
+	{
+		logprintf(LOG_ERR, "Can't write to LIRC pipe! %d", child_pipe_write);
+	}	
+	
+}
+
+static int commandir_decode(char *command)
+{
+	// Decode the signal to a number, just like LIRC; 
+	// there's probably a built-in way to do this.
+	int i;
+	int code = 0;
+	
+	lirc_t *codes;	
+	codes = (lirc_t *)command;
+	
+	for(i=0; i<15; i+=2)
+	{
+		code = code << 1;
+		if(codes[i]==100)
+			code |= 1;
+	}
+	return code;
+}
+
diff --git a/abs/core-testing/lirc_085/hw_commandir.h b/abs/core-testing/lirc_085/hw_commandir.h
new file mode 100755
index 0000000..2280f6c
--- /dev/null
+++ b/abs/core-testing/lirc_085/hw_commandir.h
@@ -0,0 +1,175 @@
+ 
+/****************************************************************************
+ ** hw_commandir.h **********************************************************
+ ****************************************************************************
+ * 
+ * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
+ * -- Original hw_default.h
+ * Modified for CommandIR Transceivers, April-June 2008, Matthew Bodkin 
+ *
+ */
+
+#ifndef HW_COMMANDIR_H
+#define HW_COMMANDIR_H
+
+#define RX_BUFFER_SIZE 1024
+#define TX_BUFFER_SIZE 1024
+#define TX_QUEUE 1
+#define RX_QUEUE 0
+#define MAX_COMMANDIRS 4
+#define MAX_COMMAND 8192
+
+/* transmitter channel control */
+#define MAX_DEVICES		4
+#define MAX_CHANNELS    16
+#define DEVICE_CHANNELS	4
+#define MAX_MASK 		0xffff
+#define MAX_SIGNALQ		100
+
+/* CommandIR control codes */
+#define CHANNEL_EN_MASK	1
+#define FREQ_HEADER     2
+#define MCU_CTRL_SIZE   3
+#define TX_HEADER       7
+#define TX_HEADER_NEW	8
+/* New for CommandIR II  */
+
+#define READ_INPUTS		10
+#define PROC_SET		11
+#define INIT_FUNCTION	12
+#define RX_SELECT		13
+#define TX_COMMANDIR_II 14
+/* Internal to driver */
+#define TX_LIRC_T	    15
+#define FREQ_HEADER_LIRC 16
+#define RXDECODE_HEADER_LIRC 17
+#define INIT_HEADER_LIRC 18
+#define DEINIT_HEADER_LIRC 19
+#define GET_VERSION 	20
+
+#define COMMANDIR_2_PULSE_MASK 0x8000
+#define COMMANDIR_2_OVERFLOW_MASK 0x4000
+
+#define DEFAULT_PULSE_WIDTH 13
+
+#define USB_CMDIR_VENDOR_ID		0x10c4
+#define USB_CMDIR_PRODUCT_ID	0x0003
+#define USB_CMDIR_MINOR_BASE	192
+
+#define HW_COMMANDIR_MINI 	1
+#define HW_COMMANDIR_2		2
+#define HW_COMMANDIR_UNKNOWN 127
+
+#define MAX_HW_MINI_PACKET 64
+
+// CommandIR has lots of buffer room, we don't need to poll constantly
+#define USB_TIMEOUT_MS 5000
+#define USB_TIMEOUT_US 1000
+#define WAIT_BETWEEN_READS_US 10000
+#define MAX_WAIT_BETWEEN_READS_US 5000000
+#define MIN_WAIT_BETWEEN_READS_US 5000
+
+#define USB_MAX_BUSES	8
+#define USB_MAX_BUSDEV	127
+
+#define RX_HEADER_DATA 		0x01
+#define RX_HEADER_EVENTS 	0x02
+#define RX_HEADER_TXAVAIL 	0x03
+
+
+// We keep CommandIR's OPEN even on -deinit for speed and to monitor 
+// Other non-LIRC events (plugin, suspend, etc)
+#define USB_KEEP_WARM 1
+
+// CommandIR lircd.conf event driven code definitions
+#define LIRCCODE_GAP  125000
+#define JACK_PLUG_1		0x01
+#define JACK_PLUG_2		0x02
+#define JACK_PLUG_3		0x03
+#define JACK_PLUG_4		0x04
+#define JACK_PLUG_5		0x11
+#define JACK_PLUG_6		0x12
+#define JACK_PLUG_7		0x13
+#define JACK_PLUG_8		0x14
+#define JACK_PLUG_9		0x21
+#define JACK_PLUG_10	0x22
+#define JACK_PLUG_11	0x23
+#define JACK_PLUG_12	0x24
+#define JACK_PLUG_13	0x31
+#define JACK_PLUG_14	0x32
+#define JACK_PLUG_15	0x33
+#define JACK_PLUG_16	0x34
+
+#define JACK_UNPLUG_1	0x05
+#define JACK_UNPLUG_2	0x06
+#define JACK_UNPLUG_3	0x07
+#define JACK_UNPLUG_4	0x08
+#define JACK_UNPLUG_5	0x15
+#define JACK_UNPLUG_6	0x16
+#define JACK_UNPLUG_7	0x17
+#define JACK_UNPLUG_8	0x18
+#define JACK_UNPLUG_9	0x25
+#define JACK_UNPLUG_10	0x26
+#define JACK_UNPLUG_11	0x27
+#define JACK_UNPLUG_12	0x28
+#define JACK_UNPLUG_13	0x35
+#define JACK_UNPLUG_14	0x36
+#define JACK_UNPLUG_15	0x37
+#define JACK_UNPLUG_16	0x38
+
+#define SELECT_TX_INTERNAL	0x09
+#define SELECT_TX_ExTERNAL	0x0A
+
+#define SELECT_TX_ON_1		0x0D
+#define SELECT_TX_ON_2		0x1D
+#define SELECT_TX_ON_3		0x2D
+#define SELECT_TX_ON_4		0x3D
+
+#define JACK_PLUG_RX_1		0x0B
+#define JACK_UNPLUG_RX_1	0x0C
+#define JACK_PLUG_RX_2		0x1B
+#define JACK_UNPLUG_RX_2	0x1C
+#define JACK_PLUG_RX_3		0x2B
+#define JACK_UNPLUG_RX_3	0x2C
+#define JACK_PLUG_RX_4		0x3B
+#define JACK_UNPLUG_RX_4	0x3C
+
+#define COMMANDIR_PLUG_1	0x41
+#define COMMANDIR_PLUG_2	0x42
+#define COMMANDIR_PLUG_3	0x43
+#define COMMANDIR_PLUG_4	0x44
+
+#define COMMANDIR_UNPLUG_1	0x45
+#define COMMANDIR_UNPLUG_2	0x46
+#define COMMANDIR_UNPLUG_3	0x47
+#define COMMANDIR_UNPLUG_4	0x48
+
+#define COMMANDIR_REORDERED	0x50
+#define COMMANDIR_READY		0x51
+#define COMMANDIR_STOPPED	0x52
+#define COMMANDIR_POLL_FASTER	0x53
+#define COMMANDIR_POLL_SLOWER	0x54
+
+#define SETTRANSMITTERS_1	0xf0
+#define SETTRANSMITTERS_2	0xf1
+#define SETTRANSMITTERS_3	0xf2
+#define SETTRANSMITTERS_4	0xf3
+#define SETTRANSMITTERS_5	0xf4
+#define SETTRANSMITTERS_6	0xf5
+#define SETTRANSMITTERS_7	0xf6
+#define SETTRANSMITTERS_8	0xf7
+#define SETTRANSMITTERS_9	0xf8
+#define SETTRANSMITTERS_10	0xf9
+#define SETTRANSMITTERS_11	0xfa
+#define SETTRANSMITTERS_12	0xfb
+#define SETTRANSMITTERS_13	0xfc
+#define SETTRANSMITTERS_14	0xfd
+#define SETTRANSMITTERS_15	0xfe
+#define SETTRANSMITTERS_16	0xff
+
+// What's in a returning data packet
+#define COMMANDIR_RX_EVENTS 		0x02
+#define COMMANDIR_RX_DATA			0x01
+
+
+#endif
diff --git a/abs/core-testing/lirc_085/kernel-2.6.26.patch b/abs/core-testing/lirc_085/kernel-2.6.26.patch
new file mode 100644
index 0000000..74bb986
--- /dev/null
+++ b/abs/core-testing/lirc_085/kernel-2.6.26.patch
@@ -0,0 +1,122 @@
+--- a/drivers/kcompat.h	2008-01-13 11:26:28.000000000 +0100
++++ b/drivers/kcompat.h	2008-05-14 18:37:49.000000000 +0200
+@@ -1,4 +1,4 @@
+-/*      $Id: kcompat.h,v 5.34 2008/01/13 10:26:28 lirc Exp $      */
++/*      $Id: kcompat.h,v 5.36 2008/05/14 16:37:49 lirc Exp $      */
+ 
+ #ifndef _KCOMPAT_H
+ #define _KCOMPAT_H
+@@ -36,10 +36,10 @@
+ 	class_simple_destroy(cls);
+ }
+ 
+-#define lirc_class_device_create(cs, parent, dev, device, fmt, args...) \
+-	class_simple_device_add(cs, dev, device, fmt, ## args)
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_simple_device_add(cs, dev, parent, fmt, ## args)
+ 
+-static inline void class_device_destroy(lirc_class_t *cls, dev_t devt)
++static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt)
+ {
+ 	class_simple_device_remove(devt);
+ }
+@@ -48,20 +48,40 @@
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
+ 
+-#define lirc_class_device_create(cs, parent, dev, device, fmt, args...) \
+-	class_device_create(cs, dev, device, fmt, ## args)
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_device_create(cs, dev, parent, fmt, ## args)
+ 
+ #else /* >= 2.6.15 */
+ 
+-#define lirc_class_device_create class_device_create
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
++
++#define lirc_device_create(cs, parent, dev, fmt, args...) \
++	class_device_create(cs, NULL, dev, parent, fmt, ## args)
++
++#else /* >= 2.6.26 */
++
++#define lirc_device_create device_create
++
++#endif /* >= 2.6.26 */
++
+ #define LIRC_DEVFS_PREFIX
+ 
+-#endif
++#endif /* >= 2.6.15 */
+ 
+ typedef struct class lirc_class_t;
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
++
++#define lirc_device_destroy class_device_destroy
++
++#else
++
++#define lirc_device_destroy device_destroy
++
+ #endif
+ 
++#endif /* >= 2.6.13 */
++
+ #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
+ #define LIRC_HAVE_DEVFS
+ #define LIRC_HAVE_DEVFS_24
+@@ -133,8 +153,8 @@
+ #ifndef LIRC_HAVE_SYSFS
+ #define class_destroy(x) do { } while (0)
+ #define class_create(x, y) NULL
+-#define class_device_destroy(x, y) do { } while (0)
+-#define lirc_class_device_create(x, y, z, xx, yy, zz) 0
++#define lirc_class_destroy(x, y) do { } while (0)
++#define lirc_class_create(x, y, z, xx, yy, zz) 0
+ #define IS_ERR(x) 0
+ typedef struct class_simple
+ {
+--- a/drivers/lirc_dev/lirc_dev.c	2008-01-13 11:45:02.000000000 +0100
++++ b/drivers/lirc_dev/lirc_dev.c	2008-05-14 18:37:49.000000000 +0200
+@@ -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.56 2008/01/13 10:45:02 lirc Exp $
++ * $Id: lirc_dev.c,v 1.58 2008/05/14 16:37:49 lirc Exp $
+  *
+  */
+ 
+@@ -145,7 +145,8 @@
+ #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));
++	lirc_device_destroy(lirc_class,
++			    MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ 
+ 	if (ir->buf != ir->p.rbuf) {
+ 		lirc_buffer_free(ir->buf);
+@@ -400,9 +401,9 @@
+ 			S_IFCHR|S_IRUSR|S_IWUSR,
+ 			DEV_LIRC "/%u", ir->p.minor);
+ #endif
+-	(void) lirc_class_device_create(lirc_class, NULL,
+-					MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
+-					ir->p.dev, "lirc%u", ir->p.minor);
++	(void) lirc_device_create(lirc_class, ir->p.dev,
++				  MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
++				  "lirc%u", ir->p.minor);
+ 
+ 	if (p->sample_rate || p->get_queue) {
+ 		/* try to fire up polling thread */
+@@ -441,7 +442,8 @@
+ 	return minor;
+ 
+ out_sysfs:
+-	class_device_destroy(lirc_class, MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
++	lirc_device_destroy(lirc_class,
++			    MKDEV(IRCTL_DEV_MAJOR, ir->p.minor));
+ #ifdef LIRC_HAVE_DEVFS_24
+ 	devfs_unregister(ir->devfs_handle);
+ #endif
diff --git a/abs/core-testing/lirc_085/kernel-2.6.27.patch b/abs/core-testing/lirc_085/kernel-2.6.27.patch
new file mode 100644
index 0000000..05cf75b
--- /dev/null
+++ b/abs/core-testing/lirc_085/kernel-2.6.27.patch
@@ -0,0 +1,78 @@
+diff -Nur lirc-0.8.3.orig/drivers/lirc_dev/lirc_dev.c lirc-0.8.3/drivers/lirc_dev/lirc_dev.c
+--- lirc-0.8.3.orig/drivers/lirc_dev/lirc_dev.c	2008-01-13 11:45:02.000000000 +0100
++++ lirc-0.8.3/drivers/lirc_dev/lirc_dev.c	2008-10-10 16:29:15.000000000 +0200
+@@ -49,7 +49,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/errno.h>
+ #endif
+-#include <asm/semaphore.h>
++#include <linux/semaphore.h>
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+ #include <linux/wrapper.h>
+ #endif
+diff -Nur lirc-0.8.3.orig/drivers/lirc_i2c/lirc_i2c.c lirc-0.8.3/drivers/lirc_i2c/lirc_i2c.c
+--- lirc-0.8.3.orig/drivers/lirc_i2c/lirc_i2c.c	2008-05-04 15:49:53.000000000 +0200
++++ lirc-0.8.3/drivers/lirc_i2c/lirc_i2c.c	2008-10-10 16:29:00.000000000 +0200
+@@ -54,7 +54,7 @@
+ #include <linux/i2c.h>
+ #include <linux/i2c-algo-bit.h>
+ 
+-#include <asm/semaphore.h>
++#include <linux/semaphore.h>
+ 
+ #include "drivers/kcompat.h"
+ #include "drivers/lirc_dev/lirc_dev.h"
+--- lirc-0.8.3.orig/drivers/kcompat.h	2008/05/14 16:37:49	5.36
++++ lirc-0.8.3.orig/drivers/kcompat.h	2008/09/27 08:16:15	5.37
+@@ -36,7 +36,7 @@
+ 	class_simple_destroy(cls);
+ }
+ 
+-#define lirc_device_create(cs, parent, dev, fmt, args...) \
++#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \
+ 	class_simple_device_add(cs, dev, parent, fmt, ## args)
+ 
+ static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt)
+@@ -48,20 +48,29 @@
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
+ 
+-#define lirc_device_create(cs, parent, dev, fmt, args...) \
++#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \
+ 	class_device_create(cs, dev, parent, fmt, ## args)
+ 
+ #else /* >= 2.6.15 */
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
+ 
+-#define lirc_device_create(cs, parent, dev, fmt, args...) \
++#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \
+ 	class_device_create(cs, NULL, dev, parent, fmt, ## args)
+ 
+ #else /* >= 2.6.26 */
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
++
++#define lirc_device_create(cs, parent, dev, drvdata, fmt, args...) \
++	class_device_create(cs, parent, dev, fmt, ## args)
++
++#else /* >= 2.6.27 */
++
+ #define lirc_device_create device_create
+ 
++#endif /* >= 2.6.27 */
++
+ #endif /* >= 2.6.26 */
+ 
+ #define LIRC_DEVFS_PREFIX
+--- lirc-0.8.3.orig/drivers/lirc_dev/lirc_dev.c	2008/09/06 07:30:16	1.60
++++ lirc-0.8.3.orig/drivers/lirc_dev/lirc_dev.c	2008/09/27 08:16:15	1.61
+@@ -397,7 +397,7 @@
+ 			DEV_LIRC "/%u", ir->p.minor);
+ #endif
+ 	(void) lirc_device_create(lirc_class, ir->p.dev,
+-				  MKDEV(IRCTL_DEV_MAJOR, ir->p.minor),
++				  MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), NULL,
+ 				  "lirc%u", ir->p.minor);
+ 
+ 	if (p->sample_rate || p->get_queue) {
diff --git a/abs/core-testing/lirc_085/lirc.fdi b/abs/core-testing/lirc_085/lirc.fdi
new file mode 100644
index 0000000..6f2443a
--- /dev/null
+++ b/abs/core-testing/lirc_085/lirc.fdi
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+  <device>
+     <!-- This rule prevents the Dvico dual digital4 rev 2
+          remote input device from making your keyboard act wierd. -->
+     <match key="info.product" contains_ncase="IR-receiver inside an USB DVB receiver">
+        <merge key="info.ignore" type="bool">true</merge>
+     </match>
+  </device>
+</deviceinfo>
diff --git a/abs/core-testing/lirc_085/lirc.install b/abs/core-testing/lirc_085/lirc.install
new file mode 100644
index 0000000..53340e5
--- /dev/null
+++ b/abs/core-testing/lirc_085/lirc.install
@@ -0,0 +1,50 @@
+# This is a default template for a post-install scriptlet.  You can
+# remove any functions you don't need (and this header).
+
+# arg 1:  the new package version
+pre_install() {
+  /bin/true
+}
+
+# arg 1:  the new package version
+post_install() {
+  # updating module dependencies
+  echo ">>> Updating module dependencies. Please wait ..."
+  KERNEL_VERSION=2.6.28-LinHES
+  depmod -v $KERNEL_VERSION > /dev/null 2>&1
+  /bin/true
+}
+
+# arg 1:  the new package version
+# arg 2:  the old package version
+pre_upgrade() {
+  /bin/true
+}
+
+# arg 1:  the new package version
+# arg 2:  the old package version
+post_upgrade() {
+  # updating module dependencies
+  echo ">>> Updating module dependencies. Please wait ..."
+  KERNEL_VERSION=2.6.28-LinHES
+  depmod -v $KERNEL_VERSION > /dev/null 2>&1
+  /bin/true
+}
+
+# arg 1:  the old package version
+pre_remove() {
+  /bin/true
+}
+
+# arg 1:  the old package version
+post_remove() {
+  # updating module dependencies
+  echo ">>> Updating module dependencies. Please wait ..."
+  KERNEL_VERSION=2.6.28-LinHES
+  depmod -v $KERNEL_VERSION > /dev/null 2>&1
+  /bin/true
+}
+
+op=$1
+shift
+$op $*
diff --git a/abs/core-testing/lirc_085/lirc_atiusb.patch b/abs/core-testing/lirc_085/lirc_atiusb.patch
new file mode 100644
index 0000000..2f0c61e
--- /dev/null
+++ b/abs/core-testing/lirc_085/lirc_atiusb.patch
@@ -0,0 +1,27 @@
+diff -ruaN lirc-0.8.4.orig/drivers/lirc_atiusb/lirc_atiusb.c lirc-0.8.4/drivers/lirc_atiusb/lirc_atiusb.c
+--- lirc-0.8.4.orig/drivers/lirc_atiusb/lirc_atiusb.c	2008-05-19 08:10:35.000000000 +0000
++++ lirc-0.8.4/drivers/lirc_atiusb/lirc_atiusb.c	2009-02-14 22:35:44.000000000 +0000
+@@ -192,8 +192,9 @@
+ /* init strings */
+ #define USB_OUTLEN		7
+ 
+-static char init1[] = {0x01, 0x00, 0x20, 0x14};
+-static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20};
++static char init1[] = {0x80, 0x05, 0x1b, 0x15, 0x14, 0x20, 0x24, 0x15};
++static char init2[] = {0x83, 0x03};
++static char init3[] = {0x84, 0xd7, 0x020};
+ 
+ struct in_endpt {
+ 	/* inner link in list of endpoints for the remote specified by ir */
+@@ -1183,8 +1184,9 @@
+ 			oep->buf, USB_OUTLEN, usb_remote_send,
+ 			oep, oep->ep->bInterval);
+ 
+-		send_packet(oep, 0x8004, init1);
+-		send_packet(oep, 0x8007, init2);
++               send_packet(oep, 0x8007, init1);
++               send_packet(oep, 0x8002, init2);
++               send_packet(oep, 0x8003, init3);
+ 	}
+ }
+ 
diff --git a/abs/core-testing/lirc_085/lirc_mod_mce.patch b/abs/core-testing/lirc_085/lirc_mod_mce.patch
new file mode 100644
index 0000000..1dc6644
--- /dev/null
+++ b/abs/core-testing/lirc_085/lirc_mod_mce.patch
@@ -0,0 +1,187 @@
+diff -Naru lirc_mod_mce/lirc_mod_mce.c lirc_mod_mce_new/lirc_mod_mce.c
+--- lirc_mod_mce/lirc_mod_mce.c	2008-04-18 02:12:28.000000000 +0930
++++ lirc_mod_mce_new/lirc_mod_mce.c	2009-11-22 18:45:24.000000000 +1030
+@@ -171,17 +171,76 @@
+ #define VENDOR_TATUNG           0x1460
+ #define VENDOR_GATEWAY          0x107b
+ #define VENDOR_SHUTTLE          0x1308
++#define VENDOR_PHILIPS          0x0471
++#define VENDOR_SMK              0x0609
++#define VENDOR_TATUNG           0x1460
++#define VENDOR_GATEWAY          0x107b
++#define VENDOR_SHUTTLE          0x1308
++#define VENDOR_SHUTTLE2         0x051c
++#define VENDOR_MITSUMI          0x03ee
++#define VENDOR_TOPSEED          0x1784
++#define VENDOR_RICAVISION       0x179d
++#define VENDOR_ITRON            0x195d
++#define VENDOR_FIC              0x1509
++#define VENDOR_LG               0x043e
++#define VENDOR_MICROSOFT        0x045e
++#define VENDOR_FORMOSA          0x147a
++#define VENDOR_FINTEK           0x1934
+ #define VENDOR_PINNACLE         0x2304
+ 
+-
+ static struct usb_device_id usb_remote_table [] = {
+-    { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },  /* Philips eHome Infrared Transciever */
+-    { USB_DEVICE(VENDOR_SMK, 0x031d) },      /* SMK/Toshiba G83C0004D410 */
+-    { USB_DEVICE(VENDOR_TATUNG, 0x9150) },   /* Tatung eHome Infrared Transceiver */
+-    { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) },  /* Shuttle eHome Infrared Transceiver */
+-    { USB_DEVICE(VENDOR_GATEWAY, 0x3009) },  /* Gateway eHome Infrared Transceiver */
+-    { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, /* Pinnacle Remote USB RC6 */
+-    { }                                      /* Terminating entry */
++    /* Philips eHome Infrared Transciever */
++    { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
++    /* Philips Infrared Transciever - HP branded */
++    { USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
++    /* Philips SRM5100 */
++    { USB_DEVICE(VENDOR_PHILIPS, 0x060d) },
++    /* SMK/Toshiba G83C0004D410 */
++    { USB_DEVICE(VENDOR_SMK, 0x031d) },
++    /* SMK eHome Infrared Transceiver (Sony VAIO) */
++    { USB_DEVICE(VENDOR_SMK, 0x0322) },
++    /* bundled with Hauppauge PVR-150 */
++    { USB_DEVICE(VENDOR_SMK, 0x0334) },
++    /* Tatung eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_TATUNG, 0x9150) },
++    /* Shuttle eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) },
++    /* Shuttle eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) },
++    /* Gateway eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_GATEWAY, 0x3009) },
++    /* Mitsumi */
++    { USB_DEVICE(VENDOR_MITSUMI, 0x2501) },
++    /* Topseed eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
++    /* Topseed HP eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
++    /* Topseed eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
++    /* Topseed eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
++    /* Ricavision internal Infrared Transceiver */
++    { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
++    /* Itron ione Libra Q-11 */
++    { USB_DEVICE(VENDOR_ITRON, 0x7002) },
++    /* FIC eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_FIC, 0x9242) },
++    /* LG eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_LG, 0x9803) },
++    /* Microsoft MCE Infrared Transceiver */
++    { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) },
++    /* Formosa eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_FORMOSA, 0xe015) },
++    /* Formosa aim / Trust MCE Infrared Receiver */
++    { USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
++    /* Formosa Industrial Computing / Beanbag Emulation Device */
++    { USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
++    /* Fintek eHome Infrared Transceiver */
++    { USB_DEVICE(VENDOR_FINTEK, 0x0602) },
++    /* Pinnacle Remote USB RC6 */
++    { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
++    /* Terminating entry */
++    { }
+ };
+ 
+ static unsigned char usb_kbd_keycode[256] = {
+@@ -252,6 +311,8 @@
+     struct semaphore lock;
+     char name[NAME_BUFSIZE];
+     char phys[NAME_BUFSIZE];
++
++    unsigned int carrier_freq;
+ };
+ 
+ /* init strings */
+@@ -889,6 +950,51 @@
+     }
+ }
+ 
++/* Sets the send carrier frequency */
++static int set_send_carrier(struct irctl *ir, int carrier)
++{
++    	int clk = 10000000;
++	int prescaler = 0, divisor = 0;
++	unsigned char cmdbuf[] = { 0x9F, 0x06, 0x01, 0x80 };
++
++	/* Carrier is changed */
++	if (ir->carrier_freq != carrier) {
++
++		if (carrier <= 0) {
++			ir->carrier_freq = carrier;
++			dprintk(DRIVER_NAME "[%d]: SET_CARRIER disabling "
++				"carrier modulation\n", ir->devnum);
++			request_packet_async(ir, ir->usb_ep_out,
++					     cmdbuf, sizeof(cmdbuf),
++					     PHILUSB_OUTBOUND);
++			return carrier;
++		}
++
++		for (prescaler = 0; prescaler < 4; ++prescaler) {
++			divisor = (clk >> (2 * prescaler)) / carrier;
++			if (divisor <= 0xFF) {
++				ir->carrier_freq = carrier;
++				cmdbuf[2] = prescaler;
++				cmdbuf[3] = divisor;
++				dprintk(DRIVER_NAME "[%d]: SET_CARRIER "
++					"requesting %d Hz\n",
++					ir->devnum, carrier);
++
++				/* Transmit new carrier to mce device */
++				request_packet_async(ir, ir->usb_ep_out,
++						     cmdbuf, sizeof(cmdbuf),
++						     PHILUSB_OUTBOUND);
++				return carrier;
++			}
++		}
++
++		return -EINVAL;
++
++	}
++
++	return carrier;
++}
++
+ static int input_open(struct input_dev *id)
+ {
+     return 0;
+@@ -945,6 +1051,18 @@
+         if(lvalue!=(LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) return -EINVAL;
+         break;
+ 
++    case LIRC_SET_SEND_CARRIER:
++        /* Retrieve lirc_plugin data for the device */
++        ir=lirc_get_pdata(filep);
++        if (!ir && !ir->usb_ep_out) return -EFAULT;
++
++	result = get_user(ivalue, (unsigned int *) arg);
++	if (result)
++	    return result;
++
++	set_send_carrier(ir, ivalue);
++	break;
++
+     default:
+         return -ENOIOCTLCMD;
+     }
+@@ -1047,7 +1165,8 @@
+             plugin->minor = -1;
+             plugin->features = LIRC_CAN_SEND_PULSE |
+                                 LIRC_CAN_SET_TRANSMITTER_MASK |
+-                                LIRC_CAN_REC_MODE2;
++                                LIRC_CAN_REC_MODE2 |
++                                LIRC_CAN_SET_SEND_CARRIER;
+             plugin->data = ir;
+             plugin->rbuf = rbuf;
+             plugin->set_use_inc = &set_use_inc;
+@@ -1108,7 +1227,7 @@
+     input_dev->name = ir->name;
+     input_dev->phys = ir->phys;
+     usb_to_input_id(dev, &input_dev->id);
+-    input_dev->cdev.dev = &dev->dev;
++    input_dev->dev.parent = &dev->dev;
+     input_dev->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
+     input_dev->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
+     input_dev->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X);
-- 
cgit v0.12