Only in /common/lip_katm/: CVS
diff -dur lip_katm/Makefile /common/lip_katm/Makefile
--- lip_katm/Makefile	2007-04-22 11:59:11.000000000 -0400
+++ /common/lip_katm/Makefile	2007-06-04 14:31:49.000000000 -0400
@@ -65,3 +65,4 @@
 	rm -f *.o
 	rm -f tmp/*.o
 	rm -f mod/*.o
+	rm -f *.*~
diff -dur lip_katm/Makefile.Linux /common/lip_katm/Makefile.Linux
--- lip_katm/Makefile.Linux	2007-04-22 11:59:11.000000000 -0400
+++ /common/lip_katm/Makefile.Linux	2007-06-04 14:31:49.000000000 -0400
@@ -65,3 +65,4 @@
 	rm -f *.o
 	rm -f tmp/*.o
 	rm -f mod/*.o
+	rm -f *.*~
Only in /common/lip_katm/mod: CVS
Only in /common/lip_katm/tmp: CVS
diff -dur lip_katm/wanpipe_katm.h /common/lip_katm/wanpipe_katm.h
--- lip_katm/wanpipe_katm.h	2007-04-22 11:59:11.000000000 -0400
+++ /common/lip_katm/wanpipe_katm.h	2007-04-23 14:36:09.000000000 -0400
@@ -75,6 +75,7 @@
 	/******************************
 	* Stuff used by all channels *
      ******************************/
+    unsigned long	critical;
     struct atm_dev	*dev;        		/* Points back at device */
     int			chanid;     		/* Channel ID used by CPM */
     unchar		aal;        		/* ATM_AAL0 or ATM_AAL5 */
@@ -108,6 +109,7 @@
     void *sar_vcc;
     
     wan_skb_queue_t			tx_queue;
+    wait_queue_head_t 			tx_wait;
     
     WAN_LIST_ENTRY(wp_katm_channel)	list_entry;
     atomic_t			refcnt;
Only in lip_katm: wanpipe_katm.h~
diff -dur lip_katm/wanpipe_katm_iface.c /common/lip_katm/wanpipe_katm_iface.c
--- lip_katm/wanpipe_katm_iface.c	2007-04-24 19:14:40.000000000 -0400
+++ /common/lip_katm/wanpipe_katm_iface.c	2007-06-03 12:11:39.000000000 -0400
@@ -21,7 +21,7 @@
 
 #include "wanpipe_katm.h"
 static int wp_katm_data_indication(wp_katm_t *prot, void *skb);
- 
+  
 static const struct atmdev_ops ops = {
 	.open		= wan_lip_katm_open,
 	.close		= wan_lip_katm_close,
@@ -456,29 +456,32 @@
 	}
 	
 	if (wan_test_bit(0,&atm_link->critical) ) {
-		DEBUG_EVENT("%s: KATM BH Down\n",
-					atm_link->name);
+		//DEBUG_EVENT("KATM BH Down\n");
 		return -1;
 	}
+		
 	
 	if (wan_test_and_set_bit(1,&atm_link->critical)) {
+		//DEBUG_EVENT("%s: KATM Busy\n");
 		return -1;
 	}
 	
+	//DEBUG_EVENT("KATM BH\n");
+	
 	WP_READ_LOCK(&atm_link->dev_list_lock,flags);
 	
 	atm_dev=WAN_LIST_FIRST(&atm_link->list_head_ifdev);
 	if (!atm_dev){
 		goto wpkatm_bh_transmit_exit;
 	}
-	
+
 	for (;;) {
 		if (--timeout_cnt == 0){
 			DEBUG_EVENT("%s: ATMDEV Priority TxBH Time squeeze\n",atm_link->name);
 			break;
 		}
 
-		if (!wan_test_bit(ATM_VF_READY,&atm_dev->vcc->flags)) {
+		if (wan_test_bit(0,&atm_dev->critical)) {
 			break;
 		}
 		
@@ -491,8 +494,14 @@
 			break;
 		}
 	}
+		
+	if (wan_skb_queue_len(&atm_dev->tx_queue)) {
+		moretx=1;
+	}
+
 	
 	timeout_cnt=5000;
+	atm_dev=NULL;
 
 	if ((atm_dev=atm_link->cur_tx) == NULL){
 
@@ -512,7 +521,7 @@
 			goto wpkatm_bh_transmit_exit;
 		}
 
-		if (!wan_test_bit(ATM_VF_READY,&atm_dev->vcc->flags)) {
+		if (wan_test_bit(0,&atm_dev->critical)) {
 			goto wpkatm_bh_transmit_skip;
 		}
 		
@@ -526,6 +535,8 @@
 		
 		if (wan_skb_queue_len(&atm_dev->tx_queue)) {
 			moretx=1;
+		} else {
+			wake_up(&atm_dev->tx_wait);
 		}
 		
 wpkatm_bh_transmit_skip:
Only in lip_katm: wanpipe_katm_iface.c~
Binary files lip_katm/wanpipe_katm_iface.o and /common/lip_katm/wanpipe_katm_iface.o differ
Only in /common/lip_katm/: .wanpipe_katm_iface.o.cmd
diff -dur lip_katm/wanpipe_katm_sub.c /common/lip_katm/wanpipe_katm_sub.c
--- lip_katm/wanpipe_katm_sub.c	2007-04-24 19:14:40.000000000 -0400
+++ /common/lip_katm/wanpipe_katm_sub.c	2007-06-08 00:38:32.000000000 -0400
@@ -2,6 +2,12 @@
 /* IMPLEMENT PRIVATE FUNCTIONS USED BY THE PROTOCOL */
 #include "wanpipe_katm.h"
 
+#if 0
+#define WP_ATM_DEBUG 1
+#warning "ATM DEBUG ENABLED"
+#else
+#undef WP_ATM_DEBUG 
+#endif
 
 int
 wan_lip_katm_setsockopt(struct atm_vcc *vcc, int level, int optname,
@@ -34,6 +40,34 @@
 
 */
 
+static void wan_lip_katm_close_wait(wp_katm_channel_t *chan) 
+{
+	DECLARE_WAITQUEUE(wait,current);
+
+	add_wait_queue(&chan->tx_wait,&wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	for (;;) {
+	
+		if (wan_skb_queue_len(&chan->tx_queue) == 0) {
+			break;
+		}
+		
+		DEBUG_EVENT("%d:%d: TX left = %i\n",
+			chan->vpi,chan->vci,wan_skb_queue_len(&chan->tx_queue));
+		
+		if (signal_pending(current)) {
+			DEBUG_EVENT("%d:%d: TX left = %i: Signal wakupe!\n",
+				chan->vpi,chan->vci,wan_skb_queue_len(&chan->tx_queue));
+                        break;
+                }
+
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&chan->tx_wait,&wait);
+}
+
 void wan_lip_katm_close(struct atm_vcc *vcc)
 {
 	unsigned char tx_tclass = vcc->qos.txtp.traffic_class;
@@ -45,7 +79,7 @@
 		return;
 	}
 	
-	wpabs_debug_event("%s: %s %d\n", chan->name,__FUNCTION__,__LINE__);
+	
 	
 	wpabs_clear_bit(ATM_VF_READY,&vcc->flags);
 	
@@ -60,8 +94,16 @@
 		/* Also clean up any buffers that might bave been alloced for TX*/
     	}
 	
+	wan_lip_katm_close_wait(chan);
+	
+	wpabs_debug_event("%d:%d:  %s %d Txq=%i\n", 
+			chan->vpi,chan->vci,__FUNCTION__,__LINE__,
+			wan_skb_queue_len(&chan->tx_queue));
+	
 	chan->atm_link=NULL;
-
+	
+	wan_set_bit(0,&chan->critical);
+	
 	wp_atm_close_chan(chan->sar_vcc);
 	
 	wp_unregister_atm_chan(chan->sar_vcc);
@@ -69,10 +111,11 @@
 	
 	wpkatm_remove_vccdev(atm_link,chan);
 	
-	if(vcc->dev_data) //insurance against locking up
-		kfree(vcc->dev_data); //Free the chan struct we created in Open
-	vcc->dev_data = NULL;
+	wan_skb_queue_purge(&chan->tx_queue);
 	
+	vcc->dev_data = NULL;
+	kfree(chan);
+
 	wpabs_clear_bit(ATM_VF_ADDR,&vcc->flags);
 }
 
@@ -116,6 +159,7 @@
 	atm_cfg.vpi=chan->vpi;
 	atm_cfg.vci=chan->vci;
 	
+	
 	chan->sar_vcc = wp_register_atm_chan(chan, 
 					     atm_link->sar_dev, 
 					     atm_link->name,
@@ -190,8 +234,9 @@
 	chan->vcc = vcc;
 	
 	chan->atm_link = atm_link;
+	wpabs_skb_queue_init(&chan->tx_queue);
+	init_waitqueue_head(&chan->tx_wait);
 	
-
 	/* ToDo: Need to assign all the values for chan here */
 
 	vcc->dev_data = chan; /* save channel structure */
@@ -209,7 +254,7 @@
 	}
 
 	wpkatm_insert_vccdev(atm_link,chan);
-	
+
 	/* Tells the stack that this VC is ready for Tx/Rx */
 	wpabs_set_bit(ATM_VF_READY,&vcc->flags);
 
@@ -219,6 +264,8 @@
 
 
 
+int gcnt=0;
+
 int wan_lip_katm_send(struct atm_vcc *vcc,struct sk_buff *skb)
 {
 	wp_katm_t *atm_link=vcc->dev->dev_data; //Get Hardware device pointer
@@ -245,13 +292,16 @@
 #endif
 	
 	if (!atm_link) {
+		wpabs_debug_event("%s:%d (%d:%d) No atm link\n",
+				__FUNCTION__,__LINE__,chan->vpi,chan->vci);
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
-		return 0;
+		return -1;
 	}
 	
 	if (!skb) {
-		wpabs_debug_event("!skb in eni_send ?\n");
+		wpabs_debug_event("%s:%d (%d:%d) !skb in eni_send ?\n",
+				__FUNCTION__,__LINE__,chan->vpi,chan->vci);
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
 		return -EINVAL;
@@ -271,14 +321,42 @@
 
 	nskb=skb_clone(skb,GFP_KERNEL);
 	if (!nskb) {
+		 wpabs_debug_event("%s:%d (%d:%d) Error no memory !\n",
+                                __FUNCTION__,__LINE__,chan->vpi,chan->vci);
+
 		if (vcc->pop) vcc->pop(vcc,skb);
                 else dev_kfree_skb(skb);
                 return -ENOMEM;
 	}
 
+#ifdef WP_ATM_DEBUG	
+#if 0
+	if (chan->vpi == 0 && chan->vci==5) {
+	++gcnt;
+	if (gcnt > 5) {
+		 wpabs_debug_event("%s:%d (%d:%d) Blocking !\n",
+                                __FUNCTION__,__LINE__,chan->vpi,chan->vci);
+
+		if (gcnt > 100) {
+			gcnt=0;
+		}
+	
+		if (vcc->pop) vcc->pop(vcc,skb);
+                else dev_kfree_skb(skb);
+                return -1;
+	}
+	}
+#endif
+#endif
+
 	err = wp_atm_tx(chan->sar_vcc,nskb,0);
 
 	if (err) {
+		if (chan->vpi == 0 && chan->vci==5) {
+		wpabs_debug_test("%s:%d (%d:%d) ATM Tx Failed qlen=%i\n",
+				__FUNCTION__,__LINE__,chan->vpi,chan->vci,
+				wan_skb_queue_len(&chan->tx_queue));
+		}
 		wpabs_skb_free(nskb);
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
@@ -287,6 +365,13 @@
 		
 		return -1;
 	}
+	
+#ifdef WP_ATM_DEBUG	
+	if (chan->vpi == 0 && chan->vci==5) {
+	wpabs_debug_event("%s:%d (%d:%d) ATM Tx \n",
+				__FUNCTION__,__LINE__,chan->vpi,chan->vci);
+	}
+#endif
 		
 	if (vcc->pop) vcc->pop(vcc,skb);
 	else dev_kfree_skb(skb);
@@ -309,8 +394,12 @@
 		return 0;
 	}
 	
-//	wpabs_debug_event("%s: %s VPI:VCI=%d:%d Line:%d\n",
-//               chan->name, __FUNCTION__, chan->vpi, chan->vci, __LINE__);
+#ifdef WP_ATM_DEBUG	
+	if (vcc->vpi == 0 && vcc->vci==5) {
+	wpabs_debug_event("%s:%d (%d:%d) ATM Rx \n",
+				__FUNCTION__,__LINE__,chan->vpi,chan->vci);
+	}
+#endif
 
 	
 	if (vcc->qos.aal == ATM_AAL0) {
@@ -333,11 +422,29 @@
 	if (!atm_link) {
 		return 0;
 	}
-	
-	atm_link->reg.prot_set_state(atm_link->link_dev,
+
+	if (atm_link->link_dev) {	
+		atm_link->reg.prot_set_state(atm_link->link_dev,
 				     state,
 				     data,
 				     len);
+
+	} else {
+		wpabs_debug_event("%s: %s %d: Error no link!\n",
+                        atm_link->name,__FUNCTION__,__LINE__);
+	}
+
+
+	if (atm_link->dev) {
+		atm_link->reg.chan_set_state(atm_link->dev,
+                                     state,
+                                     data,
+                                     len);
+	} else {
+		wpabs_debug_event("%s: %s %d: Error no link dev!\n",
+			atm_link->name,__FUNCTION__,__LINE__);
+
+	}
 	
 	wpabs_debug_event("%s: %s %d\n",
 			atm_link->name,__FUNCTION__,__LINE__);
@@ -392,7 +499,7 @@
 		}    
 	}
 
-	if (wan_skb_queue_len(&chan->tx_queue) >= KATM_MAX_Q){
+	if (wan_skb_queue_len(&chan->tx_queue) > KATM_MAX_Q){
 		DEBUG_EVENT("%s: %s() Error  Tx queue full\n",
 				chan->name,__FUNCTION__);
 		return 1;
@@ -424,12 +531,26 @@
 }
 
 
+
 void wpkatm_insert_vccdev(wp_katm_t *atm_link, wp_katm_channel_t *atm_chan)
 {
 	unsigned long flags;
+	wp_katm_channel_t *tmp;
 
 	WP_WRITE_LOCK(&atm_link->dev_list_lock,flags);
-	WAN_LIST_INSERT_HEAD(&atm_link->list_head_ifdev,atm_chan,list_entry);
+
+        WAN_LIST_FOREACH(tmp, &atm_link->list_head_ifdev, list_entry){
+                if (!WAN_LIST_NEXT(tmp, list_entry)){
+                        break;
+                }
+        }
+        if (tmp){
+                WAN_LIST_INSERT_AFTER(tmp, atm_chan, list_entry);
+        }else{
+                WAN_LIST_INSERT_HEAD(&atm_link->list_head_ifdev, atm_chan, list_entry);
+
+        }
+
 	WAN_DEV_HOLD(atm_chan);
 	atm_link->dev_cnt++;
 	WP_WRITE_UNLOCK(&atm_link->dev_list_lock,flags);
@@ -450,7 +571,3 @@
 	return;
 }
 
-
-
-
-
Only in lip_katm: wanpipe_katm_sub.c~
Binary files lip_katm/wanpipe_katm_sub.o and /common/lip_katm/wanpipe_katm_sub.o differ
Only in /common/lip_katm/: .wanpipe_katm_sub.o.cmd
