diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 0070aea5d3979b9d21440ff3ed6a8b1ad26d7a36..78ec79d7bb6e1dd1d44c16d5590dcd52a5d61b3c 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -2960,14 +2960,21 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
 #ifdef ZAPATA_PRI
 			if (p->call) {
 				if (p->pri && p->pri->pri) {
-					pri_hangup(p->pri->pri, p->call, -1);
-					pri_destroycall(p->pri->pri, p->call);
+					if (!pri_grab(p, p->pri)) {
+						pri_hangup(p->pri->pri, p->call, -1);
+						pri_destroycall(p->pri->pri, p->call);
+						pri_rel(p->pri);
+					} else
+						ast_log(LOG_WARNING, "Failed to grab PRI!\n");
 				} else
 					ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
 			}
 			if (p->owner)
 				p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 			p->call = NULL;
+			if (p->bearer)
+				p->bearer->inalarm = 1;
+			else
 #endif
 			p->inalarm = 1;
 			res = get_alarms(p);
@@ -3211,6 +3218,11 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
 			break;
 		case ZT_EVENT_NOALARM:
 			p->inalarm = 0;
+#ifdef ZAPATA_PRI
+			/* Extremely unlikely but just in case */
+			if (p->bearer)
+				p->bearer->inalarm = 1;
+#endif				
 			ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
 			manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
 								"Channel: %d\r\n", p->channel);
@@ -5134,6 +5146,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
 			res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
 			zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
 			break;
+		case SIG_GR303FXOKS:
 		case SIG_FXOKS:
 			zt_disable_ec(i);
 			/* Diddle the battery for the zhone */
@@ -5202,11 +5215,7 @@ static void *do_monitor(void *data)
 		count = 0;
 		i = iflist;
 		while(i) {
-			if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio) 
-#ifdef ZAPATA_PRI
-				&& !i->pri
-#endif
-				) {
+			if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
 				if (!i->owner && !i->subs[SUB_REAL].owner) {
 					/* This needs to be watched, as it lacks an owner */
 					pfds[count].fd = i->subs[SUB_REAL].zfd;
@@ -5292,7 +5301,10 @@ static void *do_monitor(void *data)
 				pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
 				if (pollres & POLLIN) {
 					if (i->owner || i->subs[SUB_REAL].owner) {
-						ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
+#ifdef ZAPATA_PRI
+						if (!i->pri)
+#endif						
+							ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
 						i = i->next;
 						continue;
 					}
@@ -5349,7 +5361,10 @@ static void *do_monitor(void *data)
 #endif				
 				{
 					if (i->owner || i->subs[SUB_REAL].owner) {
-						ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
+#ifdef ZAPATA_PRI
+						if (!i->pri)
+#endif						
+							ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
 						i = i->next;
 						continue;
 					}
@@ -6073,6 +6088,33 @@ static struct zt_pvt *chandup(struct zt_pvt *src)
 }
 	
 
+#ifdef ZAPATA_PRI
+static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
+{
+	int x;
+	if (backwards)
+		x = pri->numchans;
+	else
+		x = 0;
+	for (;;) {
+		if (backwards && (x < 0))
+			break;
+		if (!backwards && (x >= pri->numchans))
+			break;
+		if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
+			ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
+				pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
+			return x;
+		}
+		if (backwards)
+			x--;
+		else
+			x++;
+	}
+	return -1;
+}
+#endif
+
 static struct ast_channel *zt_request(char *type, int format, void *data)
 {
 	int oldformat;
@@ -6203,12 +6245,7 @@ static struct ast_channel *zt_request(char *type, int format, void *data)
 			if (pri && (p->subs[SUB_REAL].zfd < 0)) {
 				/* Gotta find an actual channel to use for this
 				   CRV if this isn't a callwait */
-				for (x=0;x<pri->numchans;x++) {
-					if (!pri->pvts[x]->owner) {
-						bearer = x;
-						break;
-					}
-				}
+				bearer = pri_find_empty_chan(pri, 0);
 				if (bearer < 0) {
 					ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
 					break;
@@ -6292,16 +6329,6 @@ static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
 }
 
 
-static int pri_find_empty_chan(struct zt_pri *pri)
-{
-	int x;
-	for (x=pri->numchans;x>=0;x--) {
-		if (pri->pvts[x] && !pri->pvts[x]->owner)
-			return x;
-	}
-	return 0;
-}
-
 static int pri_find_principle(struct zt_pri *pri, int channel)
 {
 	int x;
@@ -6757,7 +6784,7 @@ static void *pri_dchannel(void *vpri)
 			case PRI_EVENT_RING:
 				crv = NULL;
 				if (e->ring.channel == -1)
-					chanpos = pri_find_empty_chan(pri);
+					chanpos = pri_find_empty_chan(pri, 1);
 				else
 					chanpos = pri_find_principle(pri, e->ring.channel);
 				/* if no channel specified find one empty */
@@ -6780,7 +6807,7 @@ static void *pri_dchannel(void *vpri)
 					}
 				}
 				if ((chanpos < 0) && (e->ring.flexible))
-					chanpos = pri_find_empty_chan(pri);
+					chanpos = pri_find_empty_chan(pri, 1);
 				if (chanpos > -1) {
 					if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
 						crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));