--- drivers/lirc_atiusb/lirc_atiusb.c	2009/03/11 00:21:46	1.85
+++ drivers/lirc_atiusb/lirc_atiusb.c	2010/03/17 14:16:15	1.86
@@ -17,7 +17,7 @@
  *   Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006
  *      reworked the patch for lirc submission
  *
- * $Id: lirc_atiusb.c,v 1.85 2009/03/11 00:21:46 jarodwilson Exp $
+ * $Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $
  */
 
 /*
@@ -67,7 +69,7 @@
 #include "drivers/kcompat.h"
 #include "drivers/lirc_dev/lirc_dev.h"
 
-#define DRIVER_VERSION		"$Revision: 1.85 $"
+#define DRIVER_VERSION		"$Revision: 1.86 $"
 #define DRIVER_AUTHOR		"Paul Miller <pmiller9@users.sourceforge.net>"
 #define DRIVER_DESC		"USB remote driver for LIRC"
 #define DRIVER_NAME		"lirc_atiusb"
@@ -1374,7 +1376,7 @@
 	       DRIVER_VERSION "\n");
 	printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
 	dprintk(DRIVER_NAME ": debug mode enabled: "
-		"$Id: lirc_atiusb.c,v 1.85 2009/03/11 00:21:46 jarodwilson Exp $\n");
+		"$Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $\n");
 
 	repeat_jiffies = repeat*HZ/100;
 
--- drivers/lirc_atiusb/lirc_atiusb.c	2010/03/17 14:16:15	1.86
+++ drivers/lirc_atiusb/lirc_atiusb.c	2010/07/24 14:35:58	1.87
@@ -17,7 +17,7 @@
  *   Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006
  *      reworked the patch for lirc submission
  *
- * $Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $
+ * $Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $
  */
 
 /*
@@ -69,7 +69,7 @@
 #include "drivers/kcompat.h"
 #include "drivers/lirc_dev/lirc_dev.h"
 
-#define DRIVER_VERSION		"$Revision: 1.86 $"
+#define DRIVER_VERSION		"$Revision: 1.87 $"
 #define DRIVER_AUTHOR		"Paul Miller <pmiller9@users.sourceforge.net>"
 #define DRIVER_DESC		"USB remote driver for LIRC"
 #define DRIVER_NAME		"lirc_atiusb"
@@ -824,7 +824,11 @@
 				ir->devnum);
 	case 3:
 #ifdef KERNEL_2_5
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
+		usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma);
+#else
 		usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma);
+#endif
 #else
 		kfree(iep->buf);
 #endif
@@ -869,7 +873,11 @@
 	iep->len = len;
 
 #ifdef KERNEL_2_5
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
+	iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma);
+#else
 	iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma);
+#endif
 #else
 	iep->buf = kmalloc(len, GFP_KERNEL);
 #endif
@@ -931,8 +939,13 @@
 		}
 	case 3:
 #ifdef KERNEL_2_5
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
+		usb_free_coherent(oep->ir->usbdev, USB_OUTLEN,
+				  oep->buf, oep->dma);
+#else
 		usb_buffer_free(oep->ir->usbdev, USB_OUTLEN,
 				oep->buf, oep->dma);
+#endif
 #else
 		kfree(oep->buf);
 #endif
@@ -965,8 +978,13 @@
 		init_waitqueue_head(&oep->wait);
 
 #ifdef KERNEL_2_5
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
+		oep->buf = usb_alloc_coherent(dev, USB_OUTLEN,
+					      GFP_ATOMIC, &oep->dma);
+#else
 		oep->buf = usb_buffer_alloc(dev, USB_OUTLEN,
 					    GFP_ATOMIC, &oep->dma);
+#endif
 #else
 		oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL);
 #endif
@@ -1376,7 +1394,7 @@
 	       DRIVER_VERSION "\n");
 	printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
 	dprintk(DRIVER_NAME ": debug mode enabled: "
-		"$Id: lirc_atiusb.c,v 1.86 2010/03/17 14:16:15 jarodwilson Exp $\n");
+		"$Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $\n");
 
 	repeat_jiffies = repeat*HZ/100;

--- drivers/lirc_atiusb/lirc_atiusb.c	2010/07/24 14:35:58	1.87
+++ drivers/lirc_atiusb/lirc_atiusb.c	2010/07/25 16:43:33	1.88
@@ -17,7 +17,7 @@
  *   Vassilis Virvilis <vasvir@iit.demokritos.gr> 2006
  *      reworked the patch for lirc submission
  *
- * $Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $
+ * $Id: lirc_atiusb.c,v 1.88 2010/07/25 16:43:33 jarodwilson Exp $
  */
 
 /*
@@ -69,7 +69,7 @@
 #include "drivers/kcompat.h"
 #include "drivers/lirc_dev/lirc_dev.h"
 
-#define DRIVER_VERSION		"$Revision: 1.87 $"
+#define DRIVER_VERSION		"$Revision: 1.88 $"
 #define DRIVER_AUTHOR		"Paul Miller <pmiller9@users.sourceforge.net>"
 #define DRIVER_DESC		"USB remote driver for LIRC"
 #define DRIVER_NAME		"lirc_atiusb"
@@ -824,12 +824,8 @@
 				ir->devnum);
 	case 3:
 #ifdef KERNEL_2_5
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
 		usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma);
 #else
-		usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma);
-#endif
-#else
 		kfree(iep->buf);
 #endif
 		iep->buf = 0;
@@ -873,12 +869,8 @@
 	iep->len = len;
 
 #ifdef KERNEL_2_5
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
 	iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma);
 #else
-	iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma);
-#endif
-#else
 	iep->buf = kmalloc(len, GFP_KERNEL);
 #endif
 	if (!iep->buf) {
@@ -939,14 +931,9 @@
 		}
 	case 3:
 #ifdef KERNEL_2_5
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
 		usb_free_coherent(oep->ir->usbdev, USB_OUTLEN,
 				  oep->buf, oep->dma);
 #else
-		usb_buffer_free(oep->ir->usbdev, USB_OUTLEN,
-				oep->buf, oep->dma);
-#endif
-#else
 		kfree(oep->buf);
 #endif
 		oep->buf = 0;
@@ -978,14 +965,9 @@
 		init_waitqueue_head(&oep->wait);
 
 #ifdef KERNEL_2_5
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)
 		oep->buf = usb_alloc_coherent(dev, USB_OUTLEN,
 					      GFP_ATOMIC, &oep->dma);
 #else
-		oep->buf = usb_buffer_alloc(dev, USB_OUTLEN,
-					    GFP_ATOMIC, &oep->dma);
-#endif
-#else
 		oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL);
 #endif
 		if (!oep->buf)
@@ -1394,7 +1376,7 @@
 	       DRIVER_VERSION "\n");
 	printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
 	dprintk(DRIVER_NAME ": debug mode enabled: "
-		"$Id: lirc_atiusb.c,v 1.87 2010/07/24 14:35:58 jarodwilson Exp $\n");
+		"$Id: lirc_atiusb.c,v 1.88 2010/07/25 16:43:33 jarodwilson Exp $\n");
 
 	repeat_jiffies = repeat*HZ/100;
 
--- drivers/kcompat.h	2009/08/02 11:15:28	5.45
+++ drivers/kcompat.h	2010/07/27 05:43:21	5.50
@@ -1,4 +1,4 @@
-/*      $Id: kcompat.h,v 5.45 2009/08/02 11:15:28 lirc Exp $      */
+/*      $Id: kcompat.h,v 5.50 2010/07/27 05:43:21 jarodwilson Exp $      */
 
 #ifndef _KCOMPAT_H
 #define _KCOMPAT_H
@@ -9,6 +9,11 @@
 #define __func__ __FUNCTION__
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
+#define usb_alloc_coherent usb_buffer_alloc
+#define usb_free_coherent usb_buffer_free
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
 #define LIRC_THIS_MODULE(x) x,
 #else /* >= 2.6.16 */
@@ -364,6 +369,11 @@
 #endif /* kernel < 2.6.11 */
 #endif /* kernel >= 2.6.0 */
 
+/*************************** pm_wakeup.h ******************************/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
+static inline void device_set_wakeup_capable(struct device *dev, int val) {}
+#endif /* kernel < 2.6.27 */
+
 /*************************** interrupt.h ******************************/
 /* added in 2.6.18, old defines removed in 2.6.24 */
 #ifndef IRQF_DISABLED
@@ -378,6 +388,9 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
 #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
 #endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
+#define __SPIN_LOCK_UNLOCKED(x) SPIN_LOCK_UNLOCKED;
+#endif
 
 /***************************** slab.h *********************************/
 /* added in 2.6.14 */
@@ -405,4 +418,14 @@
 #define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
 #endif
 
+/****************************** kernel.h **********************************/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
+#define DIV_ROUND_CLOSEST(x, divisor)(                  \
+{                                                       \
+        typeof(divisor) __divisor = divisor;            \
+        (((x) + ((__divisor) / 2)) / (__divisor));      \
+}                                                       \
+)
+#endif
+
 #endif /* _KCOMPAT_H */
--- drivers/lirc_igorplugusb/lirc_igorplugusb.c	2009/11/09 18:59:21	1.35
+++ drivers/lirc_igorplugusb/lirc_igorplugusb.c	2010/07/25 16:43:33	1.38
@@ -450,7 +452,7 @@
 	}
 
 #if defined(KERNEL_2_5)
-	ir->buf_in = usb_buffer_alloc(dev,
+	ir->buf_in = usb_alloc_coherent(dev,
 			      DEVICE_BUFLEN+DEVICE_HEADERLEN,
 			      GFP_ATOMIC, &ir->dma_in);
 #else
@@ -486,7 +488,7 @@
 	switch (mem_failure) {
 	case 9:
 #if defined(KERNEL_2_5)
-		usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN,
+		usb_free_coherent(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN,
 			ir->buf_in, ir->dma_in);
 #else
 		kfree(ir->buf_in);
@@ -566,7 +568,7 @@
 
 
 #if defined(KERNEL_2_5)
-	usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
+	usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
 #else
 	kfree(ir->buf_in);
 #endif
--- drivers/lirc_mceusb/lirc_mceusb.c	2010/03/17 14:16:16	1.54
+++ drivers/lirc_mceusb/lirc_mceusb.c	2010/07/25 16:43:33	1.70
@@ -80,6 +80,7 @@
 #define DRIVER_NAME	"lirc_mceusb"
 
 #define USB_BUFLEN	32	/* USB reception buffer length */
+#define USB_CTRL_MSG_SZ	2	/* Size of usb ctrl msg on gen1 hw */
 #define LIRCBUF_SIZE	256	/* LIRC work buffer length */
 
 /* MCE constants */
@@ -95,7 +96,7 @@
 #define MCE_PULSE_BIT	0x80 /* Pulse bit, MSB set == PULSE else SPACE */
 #define MCE_PULSE_MASK	0x7F /* Pulse mask */
 #define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */
-#define MCE_PACKET_LENGTH_MASK  0x7F /* Pulse mask */
+#define MCE_PACKET_LENGTH_MASK  0x7F /* Packet length mask */
 
 
 /* module parameters */
@@ -116,8 +117,8 @@
 #define RECV_FLAG_IN_PROGRESS	3
 #define RECV_FLAG_COMPLETE	4
 
-#define MCEUSB_INBOUND		1
-#define MCEUSB_OUTBOUND		2
+#define MCEUSB_RX		1
+#define MCEUSB_TX		2
 
 #define VENDOR_PHILIPS		0x0471
 #define VENDOR_SMK		0x0609
@@ -211,6 +212,8 @@
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03a) },
 	/* Formosa Industrial Computing AIM IR605/A */
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
+	/* Formosa Industrial Computing AIM IR605/A */
+	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
 	/* Fintek eHome Infrared Transceiver */
 	{ USB_DEVICE(VENDOR_FINTEK, 0x0602) },
 	/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
@@ -233,8 +236,9 @@
 	{ }
 };
 
-static struct usb_device_id pinnacle_list[] = {
+static struct usb_device_id gen3_list[] = {
 	{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
+	{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
 	{}
 };
 
@@ -282,10 +286,9 @@
 	unsigned char is_pulse;
 	struct {
 		u32 connected:1;
-		u32 pinnacle:1;
 		u32 transmitter_mask_inverted:1;
 		u32 microsoft_gen1:1;
-		u32 reserved:28;
+		u32 reserved:29;
 	} flags;
 
 	unsigned char transmitter_mask;
@@ -295,16 +298,44 @@
 	int send_flags;
 	wait_queue_head_t wait_out;
 
-	struct mutex lock;
+	struct mutex dev_lock;
 };
 
-/* init strings */
-static char init1[] = {0x00, 0xff, 0xaa, 0xff, 0x0b};
-static char init2[] = {0xff, 0x18};
-
-static char pin_init1[] = { 0x9f, 0x07};
-static char pin_init2[] = { 0x9f, 0x13};
-static char pin_init3[] = { 0x9f, 0x0d};
+/*
+ * MCE Device Command Strings
+ * Device command responses vary from device to device...
+ * - DEVICE_RESET resets the hardware to its default state
+ * - GET_REVISION fetches the hardware/software revision, common
+ *   replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42
+ * - GET_CARRIER_FREQ gets the carrier mode and frequency of the
+ *   device, with replies in the form of 9f 06 MM FF, where MM is 0-3,
+ *   meaning clk of 10000000, 2500000, 625000 or 156250, and FF is
+ *   ((clk / frequency) - 1)
+ * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us,
+ *   response in the form of 9f 0c msb lsb
+ * - GET_TX_BITMASK fetches the transmitter bitmask, replies in
+ *   the form of 9f 08 bm, where bm is the bitmask
+ * - GET_RX_SENSOR fetches the RX sensor setting -- long-range
+ *   general use one or short-range learning one, in the form of
+ *   9f 14 ss, where ss is either 01 for long-range or 02 for short
+ * - SET_CARRIER_FREQ sets a new carrier mode and frequency
+ * - SET_TX_BITMASK sets the transmitter bitmask
+ * - SET_RX_TIMEOUT sets the receiver timeout
+ * - SET_RX_SENSOR sets which receiver sensor to use
+ */
+static char DEVICE_RESET[]	= {0x00, 0xff, 0xaa};
+static char GET_REVISION[]	= {0xff, 0x0b};
+static char GET_UNKNOWN[]	= {0xff, 0x18};
+static char GET_UNKNOWN2[]	= {0x9f, 0x05};
+static char GET_CARRIER_FREQ[]	= {0x9f, 0x07};
+static char GET_RX_TIMEOUT[]	= {0x9f, 0x0d};
+static char GET_TX_BITMASK[]	= {0x9f, 0x13};
+static char GET_RX_SENSOR[]	= {0x9f, 0x15};
+/* sub in desired values in lower byte or bytes for full command */
+//static char SET_CARRIER_FREQ[]	= {0x9f, 0x06, 0x00, 0x00};
+//static char SET_TX_BITMASK[]	= {0x9f, 0x08, 0x00};
+//static char SET_RX_TIMEOUT[]	= {0x9f, 0x0c, 0x00, 0x00};
+//static char SET_RX_SENSOR[]	= {0x9f, 0x14, 0x00};
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
 static unsigned long usecs_to_jiffies(const unsigned int u)
@@ -320,22 +351,126 @@
 #endif
 }
 #endif
-static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, int len)
+static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
+				 int len, bool out)
 {
 	char codes[USB_BUFLEN * 3 + 1];
+	char inout[9];
 	int i;
+	u8 cmd, subcmd, data1, data2;
+	int idx = 0;
 
-	if (len <= 0)
-		return;
+	if (ir->flags.microsoft_gen1 && !out)
+		idx = 2;
 
-	if (ir->flags.microsoft_gen1 && len <= 2)
+	if (len <= idx)
 		return;
 
 	for (i = 0; i < len && i < USB_BUFLEN; i++)
 		snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF);
 
-	printk(KERN_INFO "" DRIVER_NAME "[%d]: data received %s (length=%d)\n",
-		ir->devnum, codes, len);
+	printk(KERN_INFO "" DRIVER_NAME "[%d]: %sx data: %s (length=%d)\n",
+		ir->devnum, (out ? "t" : "r"), codes, len);
+
+	if (out)
+		strcpy(inout, "Request\0");
+	else
+		strcpy(inout, "Got\0");
+
+	cmd    = buf[idx] & 0xff;
+	subcmd = buf[idx + 1] & 0xff;
+	data1  = buf[idx + 2] & 0xff;
+	data2  = buf[idx + 3] & 0xff;
+
+	switch (cmd) {
+	case 0x00:
+		if (subcmd == 0xff && data1 == 0xaa)
+			printk(KERN_INFO "Device reset requested\n");
+		else
+			printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n",
+				cmd, subcmd);
+		break;
+	case 0xff:
+		switch (subcmd) {
+		case 0x0b:
+			if (len == 2)
+				printk(KERN_INFO "Get hw/sw rev?\n");
+			else
+				printk(KERN_INFO "hw/sw rev 0x%02x 0x%02x "
+					"0x%02x 0x%02x\n", data1, data2,
+					buf[4], buf[5]);
+			break;
+		case 0xaa:
+			printk(KERN_INFO "Device reset requested\n");
+			break;
+		case 0xfe:
+			printk(KERN_INFO "Previous command not supported\n");
+			break;
+		case 0x18:
+		case 0x1b:
+		default:
+			printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n",
+				cmd, subcmd);
+			break;
+		}
+		break;
+	case 0x9f:
+		switch (subcmd) {
+		case 0x03:
+			printk(KERN_INFO "Ping\n");
+			break;
+		case 0x04:
+			printk(KERN_INFO "Resp to 9f 05 of 0x%02x 0x%02x\n",
+				data1, data2);
+			break;
+		case 0x06:
+			printk(KERN_INFO "%s carrier mode and freq of 0x%02x 0x%02x\n",
+				inout, data1, data2);
+			break;
+		case 0x07:
+			printk(KERN_INFO "Get carrier mode and freq\n");
+			break;
+		case 0x08:
+			printk(KERN_INFO "%s transmit blaster mask of 0x%02x\n",
+				inout, data1);
+			break;
+		case 0x0c:
+			/* value is in units of 50us, so x*50/100 or x/2 ms */
+			printk(KERN_INFO "%s receive timeout of %d ms\n",
+				inout, ((data1 << 8) | data2) / 2);
+			break;
+		case 0x0d:
+			printk(KERN_INFO "Get receive timeout\n");
+			break;
+		case 0x13:
+			printk(KERN_INFO "Get transmit blaster mask\n");
+			break;
+		case 0x14:
+			printk(KERN_INFO "%s %s-range receive sensor in use\n",
+				inout, data1 == 0x02 ? "short" : "long");
+			break;
+		case 0x15:
+			if (len == 2)
+				printk(KERN_INFO "Get receive sensor\n");
+			else
+				printk(KERN_INFO "Received pulse count is %d\n",
+					((data1 << 8) | data2));
+			break;
+		case 0xfe:
+			printk(KERN_INFO "Error! Hardware is likely wedged...\n");
+			break;
+		case 0x05:
+		case 0x09:
+		case 0x0f:
+		default:
+			printk(KERN_INFO "Unknown command 0x%02x 0x%02x\n",
+				cmd, subcmd);
+			break;
+		}
+		break;
+	default:
+		break;
+	}
 }
 
 static void usb_async_callback(struct urb *urb, struct pt_regs *regs)
@@ -355,54 +490,48 @@
 			ir->devnum, urb->status, len);
 
 		if (debug)
-			mceusb_dev_printdata(ir, urb->transfer_buffer, len);
+			mceusb_dev_printdata(ir, urb->transfer_buffer, len, true);
 	}
 
 }
 
 /* request incoming or send outgoing usb packet - used to initialize remote */
-static void request_packet_async(struct mceusb_dev *ir,
-				 struct usb_endpoint_descriptor *ep,
-				 unsigned char *data, int size, int urb_type)
+static void mce_request_packet(struct mceusb_dev *ir,
+			       struct usb_endpoint_descriptor *ep,
+			       unsigned char *data, int size, int urb_type)
 {
 	int res;
 	struct urb *async_urb;
 	unsigned char *async_buf;
 
-	if (urb_type) {
+	if (urb_type == MCEUSB_TX) {
 		async_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (unlikely(!async_urb))
+		if (unlikely(!async_urb)) {
+			printk(KERN_ERR "Error, couldn't allocate urb!\n");
 			return;
+		}
 
-		async_buf = kmalloc(size, GFP_KERNEL);
+		async_buf = kzalloc(size, GFP_KERNEL);
 		if (!async_buf) {
+			printk(KERN_ERR "Error, couldn't allocate buf!\n");
 			usb_free_urb(async_urb);
 			return;
 		}
 
-		if (urb_type == MCEUSB_OUTBOUND) {
-			/* outbound data */
-			usb_fill_int_urb(async_urb, ir->usbdev,
-				usb_sndintpipe(ir->usbdev,
-					ep->bEndpointAddress),
-				async_buf, size,
-				(usb_complete_t) usb_async_callback,
-				ir, ep->bInterval);
-			memcpy(async_buf, data, size);
-		} else {
-			/* inbound data */
-			usb_fill_int_urb(async_urb, ir->usbdev,
-				usb_rcvintpipe(ir->usbdev,
-					ep->bEndpointAddress),
-				async_buf, size,
-				(usb_complete_t) usb_async_callback,
-				ir, ep->bInterval);
-		}
-		async_urb->transfer_flags = URB_ASYNC_UNLINK;
-	} else {
+		/* outbound data */
+		usb_fill_int_urb(async_urb, ir->usbdev,
+			usb_sndintpipe(ir->usbdev, ep->bEndpointAddress),
+			async_buf, size, (usb_complete_t) usb_async_callback,
+			ir, ep->bInterval);
+		memcpy(async_buf, data, size);
+
+	} else if (urb_type == MCEUSB_RX) {
 		/* standard request */
 		async_urb = ir->urb_in;
 		ir->send_flags = RECV_FLAG_IN_PROGRESS;
+	} else {
+		printk(KERN_ERR "Error! Unknown urb type %d\n", urb_type);
+		return;
 	}
 
 	dprintk(DRIVER_NAME "[%d]: receive request called (size=%#x)\n",
@@ -421,6 +550,16 @@
 		ir->devnum, res);
 }
 
+static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
+{
+	mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX);
+}
+
+static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
+{
+	mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX);
+}
+
 static int unregister_from_lirc(struct mceusb_dev *ir)
 {
 	struct lirc_driver *d = ir->d;
@@ -496,9 +635,9 @@
 	dprintk(DRIVER_NAME "[%d]: mceusb IR device closed\n", ir->devnum);
 
 	if (ir->flags.connected) {
-		mutex_lock(&ir->lock);
+		mutex_lock(&ir->dev_lock);
 		ir->flags.connected = 0;
-		mutex_unlock(&ir->lock);
+		mutex_unlock(&ir->dev_lock);
 	}
 	MOD_DEC_USE_COUNT;
 }
@@ -616,7 +755,7 @@
 	buf_len = urb->actual_length;
 
 	if (debug)
-		mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len);
+		mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false);
 
 	if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
 		ir->send_flags = SEND_FLAG_COMPLETE;
@@ -715,8 +854,7 @@
 	cmdbuf[cmdcount++] = 0x80;
 
 	/* Transmit the command to the mce device */
-	request_packet_async(ir, ir->usb_ep_out, cmdbuf,
-			     cmdcount, MCEUSB_OUTBOUND);
+	mce_async_out(ir, cmdbuf, cmdcount);
 
 	/*
 	 * The lircd gap calculation expects the write function to
@@ -762,9 +900,7 @@
 			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),
-					     MCEUSB_OUTBOUND);
+			mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
 			return carrier;
 		}
 
@@ -779,9 +915,7 @@
 					ir->devnum, carrier);
 
 				/* Transmit new carrier to mce device */
-				request_packet_async(ir, ir->usb_ep_out,
-						     cmdbuf, sizeof(cmdbuf),
-						     MCEUSB_OUTBOUND);
+				mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
 				return carrier;
 			}
 		}
@@ -799,7 +933,6 @@
 {
 	int result;
 	unsigned int ivalue;
-	unsigned long lvalue;
 	struct mceusb_dev *ir = NULL;
 
 	/* Retrieve lirc_driver data for the device */
@@ -828,26 +961,6 @@
 		dprintk(DRIVER_NAME ": SET_TRANSMITTERS mask=%d\n", ivalue);
 		break;
 
-	case LIRC_GET_SEND_MODE:
-
-		result = put_user(LIRC_SEND2MODE(LIRC_CAN_SEND_PULSE &
-						 LIRC_CAN_SEND_MASK),
-				  (unsigned long *) arg);
-
-		if (result)
-			return result;
-		break;
-
-	case LIRC_SET_SEND_MODE:
-
-		result = get_user(lvalue, (unsigned long *) arg);
-
-		if (result)
-			return result;
-		if (lvalue != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK))
-			return -EINVAL;
-		break;
-
 	case LIRC_SET_SEND_CARRIER:
 
 		result = get_user(ivalue, (unsigned int *) arg);
@@ -870,45 +983,25 @@
 	.ioctl	= mceusb_lirc_ioctl,
 };
 
-static int mceusb_gen1_init(struct mceusb_dev *ir)
+static void mceusb_gen1_init(struct mceusb_dev *ir)
 {
-	int i, ret;
-	char junk[64], data[8];
-	int partial = 0;
-
-	/*
-	 * Clear off the first few messages. These look like calibration
-	 * or test data, I can't really tell. This also flushes in case
-	 * we have random ir data queued up.
-	 */
-	for (i = 0; i < 40; i++)
-		usb_bulk_msg(ir->usbdev,
-			usb_rcvbulkpipe(ir->usbdev,
-				ir->usb_ep_in->bEndpointAddress),
-			junk, 64, &partial, HZ * 10);
-
-	ir->is_pulse = 1;
-
-	memset(data, 0, 8);
-
-	/* Get Status */
-	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
-			      USB_REQ_GET_STATUS, USB_DIR_IN,
-			      0, 0, data, 2, HZ * 3);
-
-	/*    ret = usb_get_status( ir->usbdev, 0, 0, data ); */
-	dprintk("%s - ret = %d status = 0x%x 0x%x\n", __func__,
-		ret, data[0], data[1]);
+	int ret;
+	int maxp = ir->len_in;
+	char *data;
+
+	data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL);
+	if (!data) {
+		printk(KERN_ERR "%s: memory allocation failed!\n", __func__);
+		return;
+	}
 
 	/*
 	 * This is a strange one. They issue a set address to the device
 	 * on the receive control pipe and expect a certain value pair back
 	 */
-	memset(data, 0, 8);
-
 	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 			      USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
-			      data, 2, HZ * 3);
+			      data, USB_CTRL_MSG_SZ, HZ * 3);
 	dprintk("%s - ret = %d, devnum = %d\n",
 		__func__, ret, ir->usbdev->devnum);
 	dprintk("%s - data[0] = %d, data[1] = %d\n",
@@ -933,12 +1026,62 @@
 			      0x0000, 0x0100, NULL, 0, HZ * 3);
 	dprintk("%s - retC = %d\n", __func__, ret);
 
-	return ret;
+	/* device reset */
+	mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* get hw/sw revision? */
+	mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
+	mce_sync_in(ir, NULL, maxp);
+
+	kfree(data);
+
+	return;
 
 };
 
-static int mceusb_dev_probe(struct usb_interface *intf,
-				const struct usb_device_id *id)
+static void mceusb_gen2_init(struct mceusb_dev *ir)
+{
+	int maxp = ir->len_in;
+
+	/* device reset */
+	mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* get hw/sw revision? */
+	mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* unknown what the next two actually return... */
+	mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
+	mce_sync_in(ir, NULL, maxp);
+	mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
+	mce_sync_in(ir, NULL, maxp);
+}
+
+static void mceusb_get_parameters(struct mceusb_dev *ir)
+{
+	int maxp = ir->len_in;
+
+	/* get the carrier and frequency */
+	mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* get the transmitter bitmask */
+	mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* get receiver timeout value */
+	mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
+	mce_sync_in(ir, NULL, maxp);
+
+	/* get receiver sensor setting */
+	mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
+	mce_sync_in(ir, NULL, maxp);
+}
+
+static int __devinit mceusb_dev_probe(struct usb_interface *intf,
+				      const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_host_interface *idesc;
@@ -954,19 +1097,15 @@
 	int i;
 	char buf[63], name[128] = "";
 	int mem_failure = 0;
-	int is_pinnacle;
-	int is_microsoft_gen1;
+	bool is_gen3;
+	bool is_microsoft_gen1;
 
 	dprintk(DRIVER_NAME ": %s called\n", __func__);
 
-	usb_reset_device(dev);
-
 	config = dev->actconfig;
-
 	idesc = intf->cur_altsetting;
 
-	is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0;
-
+	is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
 	is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
 
 	/* step through the endpoints to find first bulk in and out endpoint */
@@ -985,14 +1124,7 @@
 				"found\n");
 			ep_in = ep;
 			ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
-			if (is_pinnacle)
-				/*
-				 * setting seems to 1 seem to cause issues with
-				 * Pinnacle timing out on transfer.
-				 */
-				ep_in->bInterval = ep->bInterval;
-			else
-				ep_in->bInterval = 1;
+			ep_in->bInterval = 1;
 		}
 
 		if ((ep_out == NULL)
@@ -1007,14 +1139,7 @@
 				"found\n");
 			ep_out = ep;
 			ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
-			if (is_pinnacle)
-				/*
-				 * setting seems to 1 seem to cause issues with
-				 * Pinnacle timing out on transfer.
-				 */
-				ep_out->bInterval = ep->bInterval;
-			else
-				ep_out->bInterval = 1;
+			ep_out->bInterval = 1;
 		}
 	}
 	if (ep_in == NULL || ep_out == NULL) {
@@ -1029,39 +1154,27 @@
 
 	mem_failure = 0;
 	ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL);
-	if (!ir) {
-		mem_failure = 1;
-		goto mem_failure_switch;
-	}
+	if (!ir)
+		goto mem_alloc_fail;
 
 	driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
-	if (!driver) {
-		mem_failure = 2;
-		goto mem_failure_switch;
-	}
+	if (!driver)
+		goto mem_alloc_fail;
 
-	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-	if (!rbuf) {
-		mem_failure = 3;
-		goto mem_failure_switch;
-	}
-
-	if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE)) {
-		mem_failure = 4;
-		goto mem_failure_switch;
-	}
-
-	ir->buf_in = usb_buffer_alloc(dev, maxp, GFP_ATOMIC, &ir->dma_in);
-	if (!ir->buf_in) {
-		mem_failure = 5;
-		goto mem_failure_switch;
-	}
+	rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+	if (!rbuf)
+		goto mem_alloc_fail;
+
+	if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE))
+		goto mem_alloc_fail;
+
+	ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in);
+	if (!ir->buf_in)
+		goto buf_in_alloc_fail;
 
 	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ir->urb_in) {
-		mem_failure = 7;
-		goto mem_failure_switch;
-	}
+	if (!ir->urb_in)
+		goto urb_in_alloc_fail;
 
 	strcpy(driver->name, DRIVER_NAME " ");
 	driver->minor = -1;
@@ -1078,33 +1191,12 @@
 	driver->dev   = &intf->dev;
 	driver->owner = THIS_MODULE;
 
-	mutex_init(&ir->lock);
+	mutex_init(&ir->dev_lock);
 	init_waitqueue_head(&ir->wait_out);
 
 	minor = lirc_register_driver(driver);
 	if (minor < 0)
-		mem_failure = 9;
-
-mem_failure_switch:
-
-	switch (mem_failure) {
-	case 9:
-		usb_free_urb(ir->urb_in);
-	case 7:
-		usb_buffer_free(dev, maxp, ir->buf_in, ir->dma_in);
-	case 5:
-		lirc_buffer_free(rbuf);
-	case 4:
-		kfree(rbuf);
-	case 3:
-		kfree(driver);
-	case 2:
-		kfree(ir);
-	case 1:
-		printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
-			devnum, mem_failure);
-		return -ENOMEM;
-	}
+		goto lirc_register_fail;
 
 	driver->minor = minor;
 	ir->d = driver;
@@ -1113,7 +1205,6 @@
 	ir->len_in = maxp;
 	ir->overflow_len = 0;
 	ir->flags.connected = 0;
-	ir->flags.pinnacle = is_pinnacle;
 	ir->flags.microsoft_gen1 = is_microsoft_gen1;
 	ir->flags.transmitter_mask_inverted =
 		usb_match_id(intf, transmitter_mask_list) ? 0 : 1;
@@ -1121,8 +1212,6 @@
 	ir->lircdata = PULSE_MASK;
 	ir->is_pulse = 0;
 
-	/* ir->flags.transmitter_mask_inverted must be set */
-	set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK);
 	/* Saving usb interface data for use by the transmitter routine */
 	ir->usb_ep_in = ep_in;
 	ir->usb_ep_out = ep_out;
@@ -1139,73 +1228,49 @@
 	printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
 	       dev->bus->busnum, devnum);
 
-	/* inbound data */
+	/* flush buffers on the device */
+	mce_sync_in(ir, NULL, maxp);
+	mce_sync_in(ir, NULL, maxp);
+
+	/* wire up inbound data handler */
 	usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
 		maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval);
 	ir->urb_in->transfer_dma = ir->dma_in;
 	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* initialize device */
-	if (ir->flags.pinnacle) {
-		int usbret;
-
-		/*
-		 * I have no idea why but this reset seems to be crucial to
-		 * getting the device to do outbound IO correctly - without
-		 * this the device seems to hang, ignoring all input - although
-		 * IR signals are correctly sent from the device, no input is
-		 * interpreted by the device and the host never does the
-		 * completion routine
-		 */
-
-		usbret = usb_reset_configuration(dev);
-		printk(DRIVER_NAME "[%d]: usb reset config ret %x\n",
-		       devnum, usbret);
-
-		/*
-		 * its possible we really should wait for a return
-		 * for each of these...
-		 */
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_out, pin_init1, sizeof(pin_init1),
-				     MCEUSB_OUTBOUND);
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_out, pin_init2, sizeof(pin_init2),
-				     MCEUSB_OUTBOUND);
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_out, pin_init3, sizeof(pin_init3),
-				     MCEUSB_OUTBOUND);
-	} else if (ir->flags.microsoft_gen1) {
-		/* original ms mce device requires some additional setup */
+	if (ir->flags.microsoft_gen1)
 		mceusb_gen1_init(ir);
-	} else {
+	else if (!is_gen3)
+		mceusb_gen2_init(ir);
 
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_out, init1,
-				     sizeof(init1), MCEUSB_OUTBOUND);
-		request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
-		request_packet_async(ir, ep_out, init2,
-				     sizeof(init2), MCEUSB_OUTBOUND);
-	}
+	mceusb_get_parameters(ir);
 
-	/*
-	 * if we don't issue the correct number of receives (MCEUSB_INBOUND)
-	 * for each outbound, then the first few ir pulses will be interpreted
-	 * by the usb_async_callback routine - we should ensure we have the
-	 * right amount OR less - as the meusb_dev_recv routine will handle
-	 * the control packets OK - they start with 0x9f - but the async
-	 * callback doesn't handle ir pulse packets
-	 */
-	request_packet_async(ir, ep_in, NULL, maxp, 0);
+	/* ir->flags.transmitter_mask_inverted must be set */
+	set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK);
 
 	usb_set_intfdata(intf, ir);
 
 	return 0;
+
+	/* Error-handling path */
+lirc_register_fail:
+	usb_free_urb(ir->urb_in);
+urb_in_alloc_fail:
+	usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
+buf_in_alloc_fail:
+	lirc_buffer_free(rbuf);
+mem_alloc_fail:
+	kfree(rbuf);
+	kfree(driver);
+	kfree(ir);
+	printk(KERN_ERR "out of memory (code=%d)\n", mem_failure);
+
+	return -ENOMEM;
 }
 
 
-static void mceusb_dev_disconnect(struct usb_interface *intf)
+static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct mceusb_dev *ir = usb_get_intfdata(intf);
@@ -1218,11 +1283,11 @@
 	ir->usbdev = NULL;
 	wake_up_all(&ir->wait_out);
 
-	mutex_lock(&ir->lock);
+	mutex_lock(&ir->dev_lock);
 	usb_kill_urb(ir->urb_in);
 	usb_free_urb(ir->urb_in);
-	usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
-	mutex_unlock(&ir->lock);
+	usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
+	mutex_unlock(&ir->dev_lock);
 
 	unregister_from_lirc(ir);
 }
--- drivers/lirc_streamzap/lirc_streamzap.c	2010/03/17 14:16:16	1.48
+++ drivers/lirc_streanzap/lirc_streamzap.c	2010/07/25 16:43:33	1.54
@@ -1,4 +1,4 @@
-/*      $Id: lirc_streamzap.c,v 1.48 2009/03/15 09:34:00 lirc Exp $      */
+/*      $Id: lirc_streamzap.c,v 1.54 2010/07/25 16:43:33 jarodwilson Exp $      */
 /*
  * Streamzap Remote Control driver
  *
@@ -54,7 +56,7 @@
 #include "drivers/kcompat.h"
 #include "drivers/lirc_dev/lirc_dev.h"
 
-#define DRIVER_VERSION	"$Revision: 1.48 $"
+#define DRIVER_VERSION	"$Revision: 1.54 $"
 #define DRIVER_NAME	"lirc_streamzap"
 #define DRIVER_DESC	"Streamzap Remote Control driver"
 
@@ -83,10 +85,11 @@
 
 #define STREAMZAP_PULSE_MASK 0xf0
 #define STREAMZAP_SPACE_MASK 0x0f
+#define STREAMZAP_TIMEOUT    0xff
 #define STREAMZAP_RESOLUTION 256
 
 /* number of samples buffered */
-#define STREAMZAP_BUFFER_SIZE 128
+#define STREAMZAP_BUFFER_SIZE 256
 
 enum StreamzapDecoderState {
 	PulseSpace,
@@ -154,6 +157,7 @@
 	struct timer_list	flush_timer;
 	int			flush;
 	int			in_use;
+	int			timeout_enabled;
 };
 
 
@@ -317,12 +321,14 @@
 
 		deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec;
 		if (deltv > 15) {
-			tmp = PULSE_MASK; /* really long time */
+			/* really long time */
+			tmp = LIRC_SPACE(LIRC_VALUE_MASK);
 		} else {
 			tmp = (lirc_t) (deltv*1000000+
 					sz->signal_start.tv_usec -
 					sz->signal_last.tv_usec);
 			tmp -= sz->sum;
+			tmp = LIRC_SPACE(tmp);
 		}
 		dprintk("ls %u", sz->driver.minor, tmp);
 		push(sz, (char *)&tmp);
@@ -334,7 +340,7 @@
 	pulse = ((lirc_t) value)*STREAMZAP_RESOLUTION;
 	pulse += STREAMZAP_RESOLUTION/2;
 	sz->sum += pulse;
-	pulse |= PULSE_BIT;
+	pulse =  LIRC_PULSE(pulse);
 
 	dprintk("p %u", sz->driver.minor, pulse&PULSE_MASK);
 	push(sz, (char *)&pulse);
@@ -354,6 +360,7 @@
 	space = ((lirc_t) value)*STREAMZAP_RESOLUTION;
 	space += STREAMZAP_RESOLUTION/2;
 	sz->sum += space;
+	space = LIRC_SPACE(space);
 	dprintk("s %u", sz->driver.minor, space);
 	push(sz, (char *)&space);
 }
@@ -426,9 +433,16 @@
 				sz->decoder_state = IgnorePulse;
 				break;
 			case FullSpace:
-				if (sz->buf_in[i] == 0xff) {
+				if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
 					sz->idle = 1;
 					stop_timer(sz);
+					if (sz->timeout_enabled) {
+						lirc_t timeout =
+							LIRC_TIMEOUT
+							(STREAMZAP_TIMEOUT *
+							 STREAMZAP_RESOLUTION);
+						push(sz, (char *)&timeout);
+					}
 					flush_delay_buffer(sz);
 				} else
 					push_full_space(sz, sz->buf_in[i]);
@@ -546,8 +560,8 @@
 
 	sz->buf_in_len = sz->endpoint->wMaxPacketSize;
 #ifdef KERNEL_2_5
-	sz->buf_in = usb_buffer_alloc(sz->udev, sz->buf_in_len,
-				      GFP_ATOMIC, &sz->dma_in);
+	sz->buf_in = usb_alloc_coherent(sz->udev, sz->buf_in_len,
+					GFP_ATOMIC, &sz->dma_in);
 #else
 	sz->buf_in = kmalloc(sz->buf_in_len, GFP_KERNEL);
 #endif
@@ -579,8 +593,12 @@
 	sz->driver.minor = -1;
 	sz->driver.sample_rate = 0;
 	sz->driver.code_length = sizeof(lirc_t) * 8;
-	sz->driver.features = LIRC_CAN_REC_MODE2 | LIRC_CAN_GET_REC_RESOLUTION;
+	sz->driver.features = LIRC_CAN_REC_MODE2 |
+		LIRC_CAN_GET_REC_RESOLUTION |
+		LIRC_CAN_SET_REC_TIMEOUT;
 	sz->driver.data = sz;
+	sz->driver.min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
+	sz->driver.max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
 	sz->driver.rbuf = &sz->lirc_buf;
 	sz->driver.set_use_inc = &streamzap_use_inc;
 	sz->driver.set_use_dec = &streamzap_use_dec;
@@ -657,7 +675,7 @@
 	if (sz) {
 		usb_free_urb(sz->urb_in);
 #ifdef KERNEL_2_5
-		usb_buffer_free(udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
+		usb_free_coherent(udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
 #else
 		if (sz->buf_in) {
 			kfree(sz->buf_in);
@@ -691,6 +709,8 @@
 	sz->flush = 1;
 	add_timer(&sz->flush_timer);
 
+	sz->timeout_enabled = 0;
+
 	sz->urb_in->dev = sz->udev;
 #ifdef KERNEL_2_5
 	if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
@@ -733,18 +753,35 @@
 static int streamzap_ioctl(struct inode *node, struct file *filep,
 			   unsigned int cmd, unsigned long arg)
 {
-	int result;
+	int result = 0;
+	lirc_t val;
+	unsigned int flag = 0;
+	struct usb_streamzap *sz = lirc_get_pdata(filep);
 
 	switch (cmd) {
 	case LIRC_GET_REC_RESOLUTION:
 		result = put_user(STREAMZAP_RESOLUTION, (unsigned int *) arg);
-		if (result)
-			return result;
+		break;
+	case LIRC_SET_REC_TIMEOUT:
+		result = get_user(val, (lirc_t *)arg);
+		if (result == 0) {
+			if (val != STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION)
+				result = -EINVAL;
+		}
+		break;
+	case LIRC_SET_REC_TIMEOUT_REPORTS:
+		result = get_user(flag, (unsigned int *)arg);
+		if (result == 0) {
+			if (flag != 0)
+				sz->timeout_enabled = 1;
+			else
+				sz->timeout_enabled = 0;
+		}
 		break;
 	default:
 		return -ENOIOCTLCMD;
 	}
-	return 0;
+	return result;
 }
 
 /**
@@ -788,7 +825,7 @@
 	usb_free_urb(sz->urb_in);
 
 #ifdef KERNEL_2_5
-	usb_buffer_free(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
+	usb_free_coherent(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
 #else
 	kfree(sz->buf_in);
 #endif
--- drivers/lirc.h	2009/08/29 07:52:41	5.19
+++ drivers/lirc.h	2010/05/13 15:45:48	5.27
@@ -1,4 +1,4 @@
-/*      $Id: lirc.h,v 5.19 2009/08/29 07:52:41 lirc Exp $      */
+/*      $Id: lirc.h,v 5.27 2010/05/13 15:45:48 lirc Exp $      */
 
 #ifndef _LINUX_LIRC_H
 #define _LINUX_LIRC_H
@@ -12,8 +12,31 @@
 #include <sys/ioctl.h>
 #endif
 
-#define PULSE_BIT  0x01000000
-#define PULSE_MASK 0x00FFFFFF
+/* <obsolete> */
+#define PULSE_BIT       0x01000000
+#define PULSE_MASK      0x00FFFFFF
+/* </obsolete> */
+
+#define LIRC_MODE2_SPACE     0x00000000
+#define LIRC_MODE2_PULSE     0x01000000
+#define LIRC_MODE2_FREQUENCY 0x02000000
+#define LIRC_MODE2_TIMEOUT   0x03000000
+
+#define LIRC_VALUE_MASK      0x00FFFFFF
+#define LIRC_MODE2_MASK      0xFF000000
+
+#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
+#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
+#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
+#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
+
+#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK)
+#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK)
+
+#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE)
+#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
+#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
+#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
 
 typedef int lirc_t;
 
@@ -27,17 +50,17 @@
 #define LIRC_MODE_RAW                  0x00000001
 #define LIRC_MODE_PULSE                0x00000002
 #define LIRC_MODE_MODE2                0x00000004
-#define LIRC_MODE_CODE                 0x00000008
+/* obsolete: #define LIRC_MODE_CODE                 0x00000008 */
 #define LIRC_MODE_LIRCCODE             0x00000010
-#define LIRC_MODE_STRING               0x00000020
+/* obsolete: #define LIRC_MODE_STRING               0x00000020 */
 
 
 #define LIRC_CAN_SEND_RAW              LIRC_MODE2SEND(LIRC_MODE_RAW)
 #define LIRC_CAN_SEND_PULSE            LIRC_MODE2SEND(LIRC_MODE_PULSE)
 #define LIRC_CAN_SEND_MODE2            LIRC_MODE2SEND(LIRC_MODE_MODE2)
-#define LIRC_CAN_SEND_CODE             LIRC_MODE2SEND(LIRC_MODE_CODE)
+/* obsolete: #define LIRC_CAN_SEND_CODE             LIRC_MODE2SEND(LIRC_MODE_CODE) */
 #define LIRC_CAN_SEND_LIRCCODE         LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
-#define LIRC_CAN_SEND_STRING           LIRC_MODE2SEND(LIRC_MODE_STRING)
+/* obsolete: #define LIRC_CAN_SEND_STRING           LIRC_MODE2SEND(LIRC_MODE_STRING) */
 
 #define LIRC_CAN_SEND_MASK             0x0000003f
 
@@ -48,9 +71,9 @@
 #define LIRC_CAN_REC_RAW               LIRC_MODE2REC(LIRC_MODE_RAW)
 #define LIRC_CAN_REC_PULSE             LIRC_MODE2REC(LIRC_MODE_PULSE)
 #define LIRC_CAN_REC_MODE2             LIRC_MODE2REC(LIRC_MODE_MODE2)
-#define LIRC_CAN_REC_CODE              LIRC_MODE2REC(LIRC_MODE_CODE)
+/* obsolete: #define LIRC_CAN_REC_CODE              LIRC_MODE2REC(LIRC_MODE_CODE) */
 #define LIRC_CAN_REC_LIRCCODE          LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
-#define LIRC_CAN_REC_STRING            LIRC_MODE2REC(LIRC_MODE_STRING)
+/* obsolete: #define LIRC_CAN_REC_STRING            LIRC_MODE2REC(LIRC_MODE_STRING) */
 
 #define LIRC_CAN_REC_MASK              LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
 
@@ -60,6 +83,10 @@
 #define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
 #define LIRC_CAN_SET_REC_CARRIER_RANGE    0x80000000
 #define LIRC_CAN_GET_REC_RESOLUTION       0x20000000
+#define LIRC_CAN_SET_REC_TIMEOUT          0x10000000
+#define LIRC_CAN_SET_REC_FILTER           0x08000000
+
+#define LIRC_CAN_MEASURE_CARRIER          0x02000000
 
 #define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
 #define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
@@ -78,10 +105,23 @@
 #define LIRC_GET_REC_DUTY_CYCLE        _IOR('i', 0x00000006, unsigned int)
 #define LIRC_GET_REC_RESOLUTION        _IOR('i', 0x00000007, unsigned int)
 
+#define LIRC_GET_MIN_TIMEOUT           _IOR('i', 0x00000008, lirc_t)
+#define LIRC_GET_MAX_TIMEOUT           _IOR('i', 0x00000009, lirc_t)
+
+#define LIRC_GET_MIN_FILTER_PULSE      _IOR('i', 0x0000000a, lirc_t)
+#define LIRC_GET_MAX_FILTER_PULSE      _IOR('i', 0x0000000b, lirc_t)
+#define LIRC_GET_MIN_FILTER_SPACE      _IOR('i', 0x0000000c, lirc_t)
+#define LIRC_GET_MAX_FILTER_SPACE      _IOR('i', 0x0000000d, lirc_t)
+
 /* code length in bits, currently only for LIRC_MODE_LIRCCODE */
 #define LIRC_GET_LENGTH                _IOR('i', 0x0000000f, unsigned long)
 
+/* all values set should be reset by the driver when the device is
+   reopened */
+
+/* obsolete: drivers only support one mode */
 #define LIRC_SET_SEND_MODE             _IOW('i', 0x00000011, unsigned long)
+/* obsolete: drivers only support one mode */
 #define LIRC_SET_REC_MODE              _IOW('i', 0x00000012, unsigned long)
 /* Note: these can reset the according pulse_width */
 #define LIRC_SET_SEND_CARRIER          _IOW('i', 0x00000013, unsigned int)
@@ -90,6 +130,26 @@
 #define LIRC_SET_REC_DUTY_CYCLE        _IOW('i', 0x00000016, unsigned int)
 #define LIRC_SET_TRANSMITTER_MASK      _IOW('i', 0x00000017, unsigned int)
 
+/* a value of 0 disables all hardware timeouts and data should be
+   reported as soon as possible */
+#define LIRC_SET_REC_TIMEOUT           _IOW('i', 0x00000018, lirc_t)
+/* 1 enables, 0 disables timeout reports in MODE2 */
+#define LIRC_SET_REC_TIMEOUT_REPORTS   _IOW('i', 0x00000019, unsigned int)
+
+/* pulses shorter than this are filtered out by hardware (software
+   emulation in lirc_dev/lircd?) */
+#define LIRC_SET_REC_FILTER_PULSE      _IOW('i', 0x0000001a, lirc_t)
+/* spaces shorter than this are filtered out by hardware (software
+   emulation in lirc_dev/lircd?) */
+#define LIRC_SET_REC_FILTER_SPACE      _IOW('i', 0x0000001b, lirc_t)
+/* if filter cannot be set independently for pulse/space, this should
+   be used */
+#define LIRC_SET_REC_FILTER            _IOW('i', 0x0000001c, lirc_t)
+
+/* if enabled from the next key press on the driver will send
+   LIRC_MODE2_FREQUENCY packets */
+#define LIRC_SET_MEASURE_CARRIER_MODE  _IOW('i', 0x0000001d, unsigned int)
+
 /*
  * to set a range use
  * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
@@ -102,4 +162,7 @@
 
 #define LIRC_NOTIFY_DECODE             _IO('i', 0x00000020)
 
+#define LIRC_SETUP_START               _IO('i', 0x00000021)
+#define LIRC_SETUP_END                 _IO('i', 0x00000022)
+
 #endif
--- drivers/lirc_dev/lirc_dev.c	2009/08/31 16:57:55	1.96
+++ drivers/lirc_dev/lirc_dev.c	2010/05/13 15:45:48	1.105
@@ -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.96 2009/08/31 16:57:55 lirc Exp $
+ * $Id: lirc_dev.c,v 1.105 2010/05/13 15:45:48 lirc Exp $
  *
  */
 
@@ -367,8 +369,7 @@
 	ir->chunk_size = ir->buf->chunk_size;
 
 	if (d->features == 0)
-		d->features = (d->code_length > 8) ?
-			LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE;
+		d->features = LIRC_CAN_REC_LIRCCODE;
 
 	ir->d = *d;
 	ir->d.minor = minor;
@@ -541,7 +542,7 @@
 static int irctl_open(struct inode *inode, struct file *file)
 {
 	struct irctl *ir;
-	int retval;
+	int retval = 0;
 
 	if (iminor(inode) >= MAX_IRCTL_DEVICES || !irctls[iminor(inode)]) {
 		dprintk("lirc_dev [%d]: open result = -ENODEV\n",
@@ -591,6 +592,8 @@
 		if (ir->task)
 			wake_up_process(ir->task);
 #endif
+	} else {
+		retval = -ENODEV;
 	}
  error:
 	if (ir)
@@ -692,6 +695,23 @@
 	case LIRC_GET_FEATURES:
 		result = put_user(ir->d.features, (unsigned long *)arg);
 		break;
+	case LIRC_GET_LENGTH:
+		result = put_user(ir->d.code_length, (unsigned long *) arg);
+		break;
+	case LIRC_GET_MIN_TIMEOUT:
+		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
+		    ir->d.min_timeout == 0)
+			return -ENOSYS;
+
+		result = put_user(ir->d.min_timeout, (lirc_t *) arg);
+		break;
+	case LIRC_GET_MAX_TIMEOUT:
+		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
+		    ir->d.max_timeout == 0)
+			return -ENOSYS;
+
+		result = put_user(ir->d.max_timeout, (lirc_t *) arg);
+		break;
 	case LIRC_GET_REC_MODE:
 		if (!(ir->d.features & LIRC_CAN_REC_MASK))
 			return -ENOSYS;
@@ -700,6 +720,16 @@
 				  (ir->d.features & LIRC_CAN_REC_MASK),
 				  (unsigned long *)arg);
 		break;
+	case LIRC_GET_SEND_MODE:
+		if (!(ir->d.features & LIRC_CAN_SEND_MASK))
+			return -ENOSYS;
+
+		result = put_user(LIRC_SEND2MODE
+				  (ir->d.features & LIRC_CAN_SEND_MASK),
+				  (unsigned long *)arg);
+		break;
+
+	/*obsolete */
 	case LIRC_SET_REC_MODE:
 		if (!(ir->d.features & LIRC_CAN_REC_MASK))
 			return -ENOSYS;
@@ -707,18 +737,30 @@
 		result = get_user(mode, (unsigned long *)arg);
 		if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
 			result = -EINVAL;
-		/*
-		 * FIXME: We should actually set the mode somehow but
-		 * for now, lirc_serial doesn't support mode changing either
-		 */
 		break;
-	case LIRC_GET_LENGTH:
-		result = put_user(ir->d.code_length, (unsigned long *) arg);
+	case LIRC_SET_SEND_MODE:
+		if (!(ir->d.features & LIRC_CAN_SEND_MASK))
+			return -ENOSYS;
+
+		result = get_user(mode, (unsigned long *)arg);
+		if (!result && !(LIRC_MODE2SEND(mode) & ir->d.features))
+			result = -EINVAL;
 		break;
 	default:
 		result = -EINVAL;
 	}
 
+	switch (cmd) {
+	case LIRC_SET_REC_MODE:
+	case LIRC_SET_SEND_MODE:
+		printk(KERN_NOTICE LOGHEAD "userspace uses outdated ioctl "
+			"please update your lirc installation\n",
+			ir->d.name, ir->d.minor);
+		break;
+	default:
+		break;
+	}
+
 	dprintk(LOGHEAD "ioctl result = %d\n",
 		ir->d.name, ir->d.minor, result);
 
@@ -791,16 +833,31 @@
 	case LIRC_GET_SEND_DUTY_CYCLE:
 	case LIRC_GET_REC_DUTY_CYCLE:
 	case LIRC_GET_REC_RESOLUTION:
+	case LIRC_GET_MIN_TIMEOUT:
+	case LIRC_GET_MAX_TIMEOUT:
+	case LIRC_GET_MIN_FILTER_PULSE:
+	case LIRC_GET_MAX_FILTER_PULSE:
+	case LIRC_GET_MIN_FILTER_SPACE:
+	case LIRC_GET_MAX_FILTER_SPACE:
 	case LIRC_SET_SEND_CARRIER:
 	case LIRC_SET_REC_CARRIER:
 	case LIRC_SET_SEND_DUTY_CYCLE:
 	case LIRC_SET_REC_DUTY_CYCLE:
 	case LIRC_SET_TRANSMITTER_MASK:
+	case LIRC_SET_REC_TIMEOUT:
+	case LIRC_SET_REC_TIMEOUT_REPORTS:
+	case LIRC_SET_REC_FILTER_PULSE:
+	case LIRC_SET_REC_FILTER_SPACE:
+	case LIRC_SET_REC_FILTER:
+	case LIRC_SET_MEASURE_CARRIER_MODE:
 	case LIRC_SET_REC_DUTY_CYCLE_RANGE:
 	case LIRC_SET_REC_CARRIER_RANGE:
+	case LIRC_NOTIFY_DECODE:
+	case LIRC_SETUP_START:
+	case LIRC_SETUP_END:
 		/*
-		 * These commands expect (unsigned int *)arg
-		 * so no problems here. Just handle the locking.
+		 * These commands expect (unsigned int *) or (lirc_t *)
+		 * arg so no problems here. Just handle the locking.
 		 */
 		lock_kernel();
 		cmd = cmd32;
--- drivers/lirc_dev/lirc_dev.h	2009/12/28 15:21:17	1.38
+++ drivers/lirc_dev/lirc_dev.h	2010/04/25 08:33:52	1.41
@@ -4,7 +4,7 @@
  * (L) by Artur Lipowski <alipowski@interia.pl>
  *        This code is licensed under GNU GPL
  *
- * $Id: lirc_dev.h,v 1.38 2009/12/28 15:21:17 jarodwilson Exp $
+ * $Id: lirc_dev.h,v 1.41 2010/04/25 08:33:52 lirc Exp $
  *
  */
 
@@ -28,6 +28,8 @@
 #include <linux/kfifo.h>
 #endif
 
+#include "drivers/lirc.h"
+
 struct lirc_buffer {
 	wait_queue_head_t wait_poll;
 	spinlock_t fifo_lock;
@@ -68,13 +70,13 @@
 #endif
 static inline void lirc_buffer_clear(struct lirc_buffer *buf)
 {
-	unsigned long flags;
-
 #ifdef LIRC_HAVE_KFIFO
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
 	if (buf->fifo)
 		kfifo_reset(buf->fifo);
 #else
+	unsigned long flags;
+
 	if (buf->fifo_initialized) {
 		spin_lock_irqsave(&buf->fifo_lock, flags);
 		kfifo_reset(&buf->fifo);
@@ -82,6 +84,8 @@
 	}
 #endif
 #else
+	unsigned long flags;
+
 	lirc_buffer_lock(buf, &flags);
 	_lirc_buffer_clear(buf);
 	lirc_buffer_unlock(buf, &flags);
@@ -331,6 +335,8 @@
 	int sample_rate;
 	unsigned long features;
 	void *data;
+	lirc_t min_timeout;
+	lirc_t max_timeout;
 	int (*add_to_buf) (void *data, struct lirc_buffer *buf);
 #ifndef LIRC_REMOVE_DURING_EXPORT
 	wait_queue_head_t* (*get_queue) (void *data);
@@ -338,7 +344,7 @@
 	struct lirc_buffer *rbuf;
 	int (*set_use_inc) (void *data);
 	void (*set_use_dec) (void *data);
-	struct file_operations *fops;
+	const struct file_operations *fops;
 	struct device *dev;
 	struct module *owner;
 };