[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#269134: kernel-image-2.6.8-1-686: include capi fix into next kernel-source-2.6.8



Package: kernel-image-2.6.8-1-686
Version: 2.6.8-2
Severity: wishlist
Tags: patch

I had several CAPI related problems. With kernel-source-2.6.8-5 +
capi-oops patch, CAPI work fine again.  Would be nice to get a
working CAPI subsystem in sarge.

Other users reported success with this patch
too on the linux-avmb1@mlists.in-berlin.de mailing list.
Carsten Paeth wrote on linux-avmb1:
---snip---
Hello.

There are several oops with capi in 2.6 kernels:
- oops in skb_dequeue under heavy data load
- kernel message: "BUG: dst underflow 0: xxxxxxx"
- kernel message: "BUG: dst underflow 0: xxxxxxx at xxxxxxx"
- problems with chan_capi and asterisk and AVM cards

The problem is that the low level send_message function in 
the capi hardware drivers free the skb when an error occured.
This is wrong. This bug is in the kernel since transfering
the handling of msgidqueue from kcapi.c to the low level
hardware drivers.

!!!! The skb should only be consumed when CAPI_NOERROR is returned !!!!

The attached patch fixes all that problems.

best regards,

calle
---snap---

For convinience I append the patch I download from linux2.5 bk
and applied to 2.6.8 kernel-source.

Achim

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/08/27 14:55:01-07:00 armin@melware.de 
#   [PATCH] 2.6 ISDN CAPI: low-level drivers skb free fix
#   
#   CAPI skb freeing fix. On sending, the hardware/low-level
#   driver may free a skb on no error only. The application/core
#   side must take care otherwise.
#   
#   Author: Carsten Paeth, Armin Schindler
# 
# drivers/isdn/capi/capidrv.c
#   2004/08/27 12:27:24-07:00 armin@melware.de +2 -1
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
# drivers/isdn/hardware/avm/b1.c
#   2004/08/27 12:51:03-07:00 armin@melware.de +3 -5
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
# drivers/isdn/hardware/avm/b1dma.c
#   2004/08/27 12:51:03-07:00 armin@melware.de +0 -2
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
# drivers/isdn/hardware/avm/c4.c
#   2004/08/27 12:51:03-07:00 armin@melware.de +0 -2
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
# drivers/isdn/hardware/avm/t1isa.c
#   2004/08/27 12:51:03-07:00 armin@melware.de +3 -4
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
# drivers/isdn/hardware/eicon/capifunc.c
#   2004/08/27 12:57:40-07:00 armin@melware.de +3 -2
#   2.6 ISDN CAPI: low-level drivers skb free fix
# 
diff -Nru a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
--- a/drivers/isdn/capi/capidrv.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/capi/capidrv.c	2004-08-30 14:50:12 -07:00
@@ -512,7 +512,8 @@
 	len = CAPIMSG_LEN(cmsg->buf);
 	skb = alloc_skb(len, GFP_ATOMIC);
 	memcpy(skb_put(skb, len), cmsg->buf, len);
-	capi20_put_message(&global.ap, skb);
+	if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
+		kfree_skb(skb);
 }
 
 /* -------- state machine -------------------------------------------- */
diff -Nru a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
--- a/drivers/isdn/hardware/avm/b1.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/hardware/avm/b1.c	2004-08-30 14:50:13 -07:00
@@ -389,7 +389,7 @@
 					     CAPIMSG_NCCI(skb->data),
 					     CAPIMSG_MSGID(skb->data));
 		if (retval != CAPI_NOERROR) 
-			goto out;
+			return retval;
 
 		dlen = CAPIMSG_DATALEN(skb->data);
 
@@ -399,16 +399,14 @@
 		b1_put_slice(port, skb->data + len, dlen);
 		spin_unlock_irqrestore(&card->lock, flags);
 	} else {
-		retval = CAPI_NOERROR;
-
 	 	spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_MESSAGE);
 		b1_put_slice(port, skb->data, len);
 		spin_unlock_irqrestore(&card->lock, flags);
 	}
- out:
+
 	dev_kfree_skb_any(skb);
-	return retval;
+	return CAPI_NOERROR;
 }
 
 /* ------------------------------------------------------------- */
diff -Nru a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
--- a/drivers/isdn/hardware/avm/b1dma.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/hardware/avm/b1dma.c	2004-08-30 14:50:12 -07:00
@@ -839,8 +839,6 @@
 	}
 	if (retval == CAPI_NOERROR) 
 		b1dma_queue_tx(card, skb);
-	else
-		dev_kfree_skb_any(skb);
 
 	return retval;
 }
diff -Nru a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
--- a/drivers/isdn/hardware/avm/c4.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/hardware/avm/c4.c	2004-08-30 14:50:12 -07:00
@@ -1029,8 +1029,6 @@
 		spin_lock_irqsave(&card->lock, flags);
 		c4_dispatch_tx(card);
 		spin_unlock_irqrestore(&card->lock, flags);
-	} else {
-		dev_kfree_skb_any(skb);
 	}
 	return retval;
 }
diff -Nru a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
--- a/drivers/isdn/hardware/avm/t1isa.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/hardware/avm/t1isa.c	2004-08-30 14:50:12 -07:00
@@ -472,7 +472,7 @@
 					     CAPIMSG_NCCI(skb->data),
 					     CAPIMSG_MSGID(skb->data));
 		if (retval != CAPI_NOERROR) 
-			goto out;
+			return retval;
 
 		dlen = CAPIMSG_DATALEN(skb->data);
 
@@ -482,16 +482,15 @@
 		t1_put_slice(port, skb->data + len, dlen);
 		spin_unlock_irqrestore(&card->lock, flags);
 	} else {
-		retval = CAPI_NOERROR;
 
 		spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_MESSAGE);
 		t1_put_slice(port, skb->data, len);
 		spin_unlock_irqrestore(&card->lock, flags);
 	}
- out:
+
 	dev_kfree_skb_any(skb);
-	return retval;
+	return CAPI_NOERROR;
 }
 /* ------------------------------------------------------------- */
 
diff -Nru a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
--- a/drivers/isdn/hardware/eicon/capifunc.c	2004-08-30 14:50:12 -07:00
+++ b/drivers/isdn/hardware/eicon/capifunc.c	2004-08-30 14:50:12 -07:00
@@ -1,4 +1,4 @@
-/* $Id: capifunc.c,v 1.61.4.2 2004/05/05 16:09:25 armin Exp $
+/* $Id: capifunc.c,v 1.61.4.5 2004/08/27 20:10:12 armin Exp $
  *
  * ISDN interface module for Eicon active cards DIVA.
  * CAPI Interface common functions
@@ -998,7 +998,8 @@
 
       write_end:
 	diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
-	diva_os_free_message_buffer(dmb);
+	if (retval == CAPI_NOERROR)
+		diva_os_free_message_buffer(dmb);
 	return retval;
 }
 

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (100, 'testing'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.8-1-686
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8

Versions of packages kernel-image-2.6.8-1-686 depends on:
ii  coreutils [fileutils]         5.2.1-2    The GNU core utilities
ii  fileutils                     5.2.1-2    The GNU file management utilities 
ii  initrd-tools                  0.1.73     tools to create initrd image for p
ii  module-init-tools             3.1-pre5-6 tools for managing Linux kernel mo

-- no debconf information



Reply to: