diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 2b1ea8a193a2f47625839fc68f8a2834691b29de..54d8b43574cc63a0851150b93fe8c79ffdf3a557 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -5196,10 +5196,11 @@ static struct ast_frame  *dahdi_read(struct ast_channel *ast)
 	int index;
 	void *readbuf;
 	struct ast_frame *f;
-	
 
-	ast_mutex_lock(&p->lock);
-	
+	while (ast_mutex_trylock(&p->lock)) {
+		CHANNEL_DEADLOCK_AVOIDANCE(ast);
+	}
+
 	index = dahdi_get_index(ast, p, 0);
 	
 	/* Hang up if we don't really exist */
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index 516c4627fddb14c2f1ec93cdc470e232956dd379..3f261c6a37faef094d28631fa0b9dba91fa00686 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -261,6 +261,20 @@ int ast_find_lock_info(void *lock_addr, const char **filename, int *lineno, cons
  * used during deadlock avoidance, to preserve the original location where
  * a lock was originally acquired.
  */
+#define CHANNEL_DEADLOCK_AVOIDANCE(chan) \
+	do { \
+		const char *__filename, *__func, *__mutex_name; \
+		int __lineno; \
+		int __res = ast_find_lock_info(&chan->lock_dont_use, &__filename, &__lineno, &__func, &__mutex_name); \
+		ast_channel_unlock(chan); \
+		usleep(1); \
+		if (__res < 0) { /* Shouldn't ever happen, but just in case... */ \
+			ast_channel_lock(chan); \
+		} else { \
+			__ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, &chan->lock_dont_use); \
+		} \
+	} while (0)
+
 #define DEADLOCK_AVOIDANCE(lock) \
 	do { \
 		const char *__filename, *__func, *__mutex_name; \
@@ -1405,6 +1419,11 @@ static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
 
 #else /* !DEBUG_THREADS */
 
+#define	CHANNEL_DEADLOCK_AVOIDANCE(chan) \
+	ast_channel_lock(chan); \
+	usleep(1); \
+	ast_channel_unlock(chan);
+
 #define	DEADLOCK_AVOIDANCE(lock) \
 	ast_mutex_lock(lock); \
 	usleep(1); \