diff --git a/Makefile b/Makefile
index 4ff600fb96d216d24eee4d9ef64ecafb01dee3b2..0d225a07de62c1137d3039b7d099aec877fd0906 100755
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,8 @@ ifeq (${OSARCH},OpenBSD)
 CFLAGS+=-pthread
 endif
 
+CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi)
+
 LIBEDIT=editline/libedit.a
 
 ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; fi)
diff --git a/apps/app_voicemail2.c b/apps/app_voicemail2.c
index 3d5fb6d6eb8f6c31d2aa6caa2c02de2d74ba0f36..f2bb8549e58a35aae0882fc3b882705b31d233ab 100755
--- a/apps/app_voicemail2.c
+++ b/apps/app_voicemail2.c
@@ -678,6 +678,8 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
 	for (x=0;x<fmtcnt;x++) {
 		if (!others[x])
 			break;
+		ast_stream_rewind(others[x], 1000);
+		ast_truncstream(others[x]);
 		ast_closestream(others[x]);
 	}
 	if (outmsg) {
@@ -705,7 +707,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 	FILE *txt;
 	int res = 0;
 	int msgnum;
-	int maxmessage=0;
 	char date[256];
 	char dir[256];
 	char fn[256];
@@ -846,7 +847,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 					fclose(txt);
 				} else
 					ast_log(LOG_WARNING, "Error opening text file for output\n");
-				res = play_and_record(chan, NULL, fn, maxmessage, fmt);
+				res = play_and_record(chan, NULL, fn, vmmaxmessage, fmt);
 				if (res > 0)
 					res = 0;
 				txt = fopen(txtfile, "a");
diff --git a/channel.c b/channel.c
index 3640dd11cb93ba467f816131fcc0ce8114520b2a..0a9363a8fb899006f95b6779666db598759eabcc 100755
--- a/channel.c
+++ b/channel.c
@@ -34,6 +34,10 @@
 #include <asterisk/linkedlists.h>
 #include <asterisk/indications.h>
 #include <asterisk/monitor.h>
+#ifdef ZAPTEL_OPTIMIZATIONS
+#include <sys/ioctl.h>
+#include <linux/zaptel.h>
+#endif
 
 
 static int shutting_down = 0;
@@ -296,8 +300,15 @@ struct ast_channel *ast_channel_alloc(int needqueue)
 						fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
 					} else
 						pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
+#ifdef ZAPTEL_OPTIMIZATIONS
+					tmp->timingfd = open("/dev/zap/timer", O_RDWR);
+#else
+					tmp->timingfd = -1;					
+#endif
 					/* Always watch the alertpipe */
 					tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
+					/* And timing pipe */
+					tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
 					strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
 					tmp->pvt = pvt;
 					/* Initial state */
@@ -921,6 +932,17 @@ char ast_waitfordigit(struct ast_channel *c, int ms)
 	return result;
 }
 
+int ast_settimeout(struct ast_channel *c, int ms)
+{
+	int res = -1;
+#ifdef ZAPTEL_OPTIMIZATIONS
+	if (c->timingfd > -1) {
+		ms *= 8;
+		res = ioctl(c->timingfd, ZT_TIMERCONFIG, &ms);
+	}
+#endif	
+	return res;
+}
 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl)
 {
 	struct ast_frame *f;
@@ -994,7 +1016,18 @@ struct ast_frame *ast_read(struct ast_channel *chan)
 	if (chan->pvt->alertpipe[0] > -1) {
 		read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
 	}
-
+#ifdef ZAPTEL_OPTIMIZATIONS
+	if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
+		chan->exception = 0;
+		blah = -1;
+		ioctl(chan->timingfd, ZT_TIMERACK, &blah);
+		blah = 0;
+		ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
+		f =  &null_frame;
+		pthread_mutex_unlock(&chan->lock);
+		return f;
+	}
+#endif
 	/* Check for pending read queue */
 	if (chan->pvt->readq) {
 		f = chan->pvt->readq;
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index f77da478c09bf89f9857e5e30b8171c50084d4dc..c9d2dc3212202b92a6ac34d2d1e51efa981cc049 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -3452,13 +3452,13 @@ static int timing_read(int *id, int fd, short events, void *cbdata)
 	struct iax2_peer *peer;
 	int processed = 0;
 	int totalcalls = 0;
-	int x = -1;
+	int x = 1;
 	if (iaxtrunkdebug)
 		ast_verbose("Beginning trunk processing\n");
 	if (events & AST_IO_PRI) {
 #ifdef ZT_TIMERACK
 		/* Great, this is a timing interface, just call the ioctl */
-		if (ioctl(fd, ZT_TIMERACK, x)) 
+		if (ioctl(fd, ZT_TIMERACK, &x)) 
 			ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
 		res = 0;
 #endif		
diff --git a/file.c b/file.c
index 466b8aa5aaa26a883512d970ef26490c1975b82c..4ad7fa974a7d62a620dbe1c177a8b76dbeecbeef 100755
--- a/file.c
+++ b/file.c
@@ -615,12 +615,13 @@ char ast_waitstream(struct ast_channel *c, char *breakon)
 			ast_closestream(c->stream);
 			break;
 		}
+		/* Setup timeout if supported */
+		ast_settimeout(c, res);
 		res = ast_waitfor(c, res);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
 			return res;
-		} else
-		if (res > 0) {
+		} else if (res > 0) {
 			fr = ast_read(c);
 			if (!fr) {
 #if 0
@@ -652,8 +653,8 @@ char ast_waitstream(struct ast_channel *c, char *breakon)
 			}
 			/* Ignore */
 			ast_frfree(fr);
-		} else
-			ast_sched_runq(c->sched);
+		}
+		ast_sched_runq(c->sched);
 	
 		
 	}
@@ -670,6 +671,7 @@ char ast_waitstream_fr(struct ast_channel *c, char *breakon, char *forward, char
 			ast_closestream(c->stream);
 			break;
 		}
+		ast_settimeout(c, res);
 		res = ast_waitfor(c, res);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
@@ -733,6 +735,7 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int
 			ast_closestream(c->stream);
 			break;
 		}
+		ast_settimeout(c, ms);
 		rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
 		if (!rchan && (outfd < 0) && (ms)) {
 			ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
@@ -776,8 +779,8 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int
 			}
 			/* Ignore */
 			ast_frfree(fr);
-		} else
-			ast_sched_runq(c->sched);
+		}
+		ast_sched_runq(c->sched);
 	
 		
 	}
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index c67dd58c4c1fc5db8e66a630535419f37a0bfbe1..97f8af91f00f312b94e4f49bf4fe5be960bca2f2 100755
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -112,6 +112,9 @@ struct ast_channel {
 	struct ast_filestream *stream;		
 	/*! Original writer format */
 	int oldwriteformat;			
+	
+	/*! Timing fd */
+	int timingfd;
 
 
 	/*! State of line -- Don't write directly, use ast_setstate */
@@ -669,6 +672,10 @@ int ast_autoservice_start(struct ast_channel *chan);
 /*! Stop servicing a channel for us...  Returns -1 on error or if channel has been hungup */
 int ast_autoservice_stop(struct ast_channel *chan);
 
+/* If built with zaptel optimizations, force a scheduled expiration on the
+   timer fd */
+int ast_settimeout(struct ast_channel *c, int ms);
+
 /* Misc. functions below */
 
 //! Waits for activity on a group of channels