patch-2.2.3 linux/net/irda/irlap.c

Next file: linux/net/irda/irlap_comp.c
Previous file: linux/net/irda/irlan/irlan_srv_event.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.2/linux/net/irda/irlap.c linux/net/irda/irlap.c
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      irlap.c
- * Version:       0.8
+ * Version:       0.9
  * Description:   An IrDA LAP driver for Linux
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Sat Jan 16 22:19:27 1999
+ * Modified at:   Sat Feb 20 01:39:58 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
@@ -43,12 +43,23 @@
 #include <net/irda/irlap_comp.h>
 
 hashbin_t *irlap = NULL;
+int sysctl_slot_timeout = SLOT_TIMEOUT;
 
 static void __irlap_close( struct irlap_cb *self);
 
+static char *lap_reasons[] = {
+	"ERROR, NOT USED",
+	"LAP_DISC_INDICATION",
+	"LAP_NO_RESPONSE",
+	"LAP_RESET_INDICATION",
+	"LAP_FOUND_NONE",
+	"LAP_MEDIA_BUSY",
+	"LAP_PRIMARY_CONFLICT",
+	"ERROR, NOT USED",
+};
+
 #ifdef CONFIG_PROC_FS
-int irlap_proc_read( char *buf, char **start, off_t offset, int len, 
-		     int unused);
+int irlap_proc_read( char *, char **, off_t, int, int);
 
 #endif /* CONFIG_PROC_FS */
 
@@ -138,8 +149,6 @@
 
 	irlmp_register_irlap( self, self->saddr, &self->notify);
 	
-	DEBUG( 4, "irlap_open -->\n");
-
 	return self;
 }
 
@@ -166,7 +175,7 @@
 	irlap_flush_all_queues( self);
        
 	self->irdev = NULL;
-	self->magic = ~LAP_MAGIC;
+	self->magic = 0;
 	
 	kfree( self);
 }
@@ -194,7 +203,7 @@
 	/* Be sure that we manage to remove ourself from the hash */
 	lap = hashbin_remove( irlap, self->saddr, NULL);
 	if ( !lap) {
-		DEBUG( 0, __FUNCTION__ "(), Didn't find myself!\n");
+		DEBUG( 1, __FUNCTION__ "(), Didn't find myself!\n");
 		return;
 	}
 	__irlap_close( lap);
@@ -206,17 +215,17 @@
  *    Another device is attempting to make a connection
  *
  */
-void irlap_connect_indication( struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) 
 {
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LAP_MAGIC, return;);
 
-	irlap_init_qos_capabilities( self, NULL); /* No user QoS! */
+	irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
 	
-	irlmp_link_connect_indication( self->notify.instance, &self->qos_tx, 
-				       skb);
+	irlmp_link_connect_indication(self->notify.instance, self->saddr, 
+				      self->daddr, &self->qos_tx, skb);
 }
 
 /*
@@ -247,21 +256,17 @@
 	ASSERT( self->magic == LAP_MAGIC, return;);
 
  	self->daddr = daddr;
-
+	
 	/*
 	 *  If the service user specifies QoS values for this connection, 
 	 *  then use them
 	 */
 	irlap_init_qos_capabilities( self, qos_user);
 	
-	if ( self->state == LAP_NDM) {
+	if ( self->state == LAP_NDM)
 		irlap_do_event( self, CONNECT_REQUEST, NULL, NULL);
-	} else {
-		DEBUG( 0, __FUNCTION__ "() Wrong state!\n");
-		
-		irlap_disconnect_indication( self, LAP_MEDIA_BUSY);
-	}
-	       
+	else
+		self->connect_pending = TRUE;
 }
 
 /*
@@ -302,12 +307,11 @@
 	if ( self->qos_tx.compression.value) {
 		skb = irlap_decompress_frame( self, skb);
 		if ( !skb) {
-			DEBUG( 0, __FUNCTION__ "(), Decompress error!\n");
+			DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
 			return;
 		}
 	}
 #endif
-
 	irlmp_link_data_indication( self->notify.instance, LAP_RELIABLE, skb);
 }
 
@@ -319,7 +323,7 @@
  */
 void irlap_unit_data_indication( struct irlap_cb *self, struct sk_buff *skb)
 {
-	DEBUG( 0, __FUNCTION__ "()\n"); 
+	DEBUG( 1, __FUNCTION__ "()\n"); 
 
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
@@ -333,7 +337,7 @@
 		
 		skb = irlap_decompress_frame( self, skb);
 		if ( !skb) {
-			DEBUG( 0, __FUNCTION__ "(), Decompress error!\n");
+			DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
 			return;
 		}
 	}
@@ -356,14 +360,14 @@
 	ASSERT( self->magic == LAP_MAGIC, return;);
 	ASSERT( skb != NULL, return;);
 
-	DEBUG( 4, "irlap_data_request: tx_list=%d\n", 
+	DEBUG( 4, __FUNCTION__ "(), tx_list=%d\n", 
 		   skb_queue_len( &self->tx_list));
 
 #ifdef CONFIG_IRDA_COMPRESSION
 	if ( self->qos_tx.compression.value) {
 		skb = irlap_compress_frame( self, skb);
 		if ( !skb) {
-			DEBUG( 0, __FUNCTION__ "(), Compress error!\n");
+			DEBUG( 1, __FUNCTION__ "(), Compress error!\n");
 			return;
 		}
 	}
@@ -401,8 +405,7 @@
 		}
 		irlap_do_event( self, SEND_I_CMD, skb, NULL);
 	} else
-		skb_queue_tail( &self->tx_list, skb);
-	
+		skb_queue_tail( &self->tx_list, skb);	
 }
 
 /*
@@ -410,14 +413,26 @@
  *
  *    Request to disconnect connection by service user
  */
-void irlap_disconnect_request( struct irlap_cb *self) 
+void irlap_disconnect_request(struct irlap_cb *self) 
 {
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(3, __FUNCTION__ "()\n");
 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-
-	irlap_do_event( self, DISCONNECT_REQUEST, NULL, NULL);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LAP_MAGIC, return;);
+	
+	switch (self->state) {
+	case LAP_XMIT_P:        /* FALLTROUGH */
+	case LAP_XMIT_S:        /* FALLTROUGH */
+ 	case LAP_CONN:          /* FALLTROUGH */
+ 	case LAP_RESET_WAIT:    /* FALLTROUGH */
+ 	case LAP_RESET_CHECK:   
+		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
+		break;
+	default:
+		DEBUG(0, __FUNCTION__ "(), disconnect pending!\n");
+		self->disconnect_pending = TRUE;
+		break;
+	}
 }
 
 /*
@@ -428,7 +443,7 @@
  */
 void irlap_disconnect_indication( struct irlap_cb *self, LAP_REASON reason) 
 {
-	DEBUG( 4, __FUNCTION__ "()\n"); 
+	DEBUG( 1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]); 
 
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
@@ -442,18 +457,18 @@
 	
 	switch( reason) {
 	case LAP_RESET_INDICATION:
-		DEBUG( 0, "Sending reset request!\n");
+		DEBUG( 1, __FUNCTION__ "(), Sending reset request!\n");
 		irlap_do_event( self, RESET_REQUEST, NULL, NULL);
 		break;
-	case LAP_NO_RESPONSE:		
-	case LAP_DISC_INDICATION:
-	case LAP_FOUND_NONE:
+	case LAP_NO_RESPONSE:	   /* FALLTROUGH */	
+	case LAP_DISC_INDICATION:  /* FALLTROUGH */
+	case LAP_FOUND_NONE:       /* FALLTROUGH */
 	case LAP_MEDIA_BUSY:
 		irlmp_link_disconnect_indication( self->notify.instance, 
 						  self, reason, NULL);
 		break;
 	default:
-		DEBUG( 0, __FUNCTION__ "(), Reason %d not implemented!\n", 
+		DEBUG( 1, __FUNCTION__ "(), Reason %d not implemented!\n", 
 		       reason);
 	}
 }
@@ -471,24 +486,48 @@
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
 	ASSERT( discovery != NULL, return;);
+	
+	DEBUG( 4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
 
+	ASSERT(( discovery->nslots == 1) || ( discovery->nslots == 6) ||
+	       ( discovery->nslots == 8) || ( discovery->nslots == 16), 
+	       return;);
+	
   	/*
 	 *  Discovery is only possible in NDM mode
 	 */ 
 	if ( self->state == LAP_NDM) {
 		ASSERT( self->discovery_log == NULL, return;);
 		self->discovery_log= hashbin_new( HB_LOCAL);
-
-		info.S = 6; /* Number of slots */
+		
+		info.S = discovery->nslots; /* Number of slots */
 		info.s = 0; /* Current slot */
-
+		
 		self->discovery_cmd = discovery;
 		info.discovery = discovery;
 		
+		/* Check if the slot timeout is within limits */
+		if ( sysctl_slot_timeout < 2) {
+			DEBUG( 1, __FUNCTION__ 
+			       "(), to low value for slot timeout!\n");
+			sysctl_slot_timeout = 2;
+		}
+		/* 
+		 * Highest value is actually 8, but we allow higher since
+		 * some devices seems to require it.
+		 */
+		if ( sysctl_slot_timeout > 16) {
+			DEBUG( 1, __FUNCTION__ 
+			       "(), to high value for slot timeout!\n");
+			sysctl_slot_timeout = 16;
+		}
+
+		self->slot_timeout = sysctl_slot_timeout;
+		
 		irlap_do_event( self, DISCOVERY_REQUEST, NULL, &info);
 	} else { 
  		DEBUG( 4, __FUNCTION__ 
- 			"(), discovery only possible in NDM mode\n");
+		       "(), discovery only possible in NDM mode\n");
 		irlap_discovery_confirm( self, NULL);
  	} 
 }
@@ -506,6 +545,14 @@
 	
 	ASSERT( self->notify.instance != NULL, return;);
 	
+	/* 
+	 * Check for successful discovery, since we are then allowed to clear 
+	 * the media busy condition (irlap p.94). This should allow us to make 
+	 * connection attempts much easier.
+	 */
+	if (discovery_log && hashbin_get_size(discovery_log) > 0)
+		irda_device_set_media_busy(self->irdev, FALSE);
+	
 	/* Inform IrLMP */
 	irlmp_link_discovery_confirm( self->notify.instance, discovery_log);
 	
@@ -552,7 +599,6 @@
 	default:
 		break;
 	}
-	/* TODO: layering violation! */
 	irlmp_status_indication( quality_of_link, NO_CHANGE);
 }
 
@@ -564,7 +610,7 @@
  */
 void irlap_reset_indication( struct irlap_cb *self)
 {
-	DEBUG( 0, __FUNCTION__ "()\n");
+	DEBUG( 1, __FUNCTION__ "()\n");
 
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
@@ -583,7 +629,7 @@
  */
 void irlap_reset_confirm(void)
 {
-	DEBUG( 0, __FUNCTION__ "()\n");
+	DEBUG( 1, __FUNCTION__ "()\n");
 }
 
 /*
@@ -672,7 +718,7 @@
 
 	/*  ns as expected?  */
 	if ( ns == self->vr) {
-		DEBUG( 4, "*** irlap_validate_ns_received: expected!\n");
+		DEBUG( 4, __FUNCTION__ "(), expected!\n");
 		return NS_EXPECTED;
 	}
 	/*
@@ -696,7 +742,7 @@
 
 	/*  nr as expected?  */
 	if ( nr == self->vs) {
-		DEBUG( 4, "*** irlap_validate_nr_received: expected!\n");
+		DEBUG( 4, __FUNCTION__ "(), expected!\n");
 		return NR_EXPECTED;
 	}
 
@@ -724,7 +770,7 @@
  */
 void irlap_initiate_connection_state( struct irlap_cb *self) 
 {
-	DEBUG( 4, "irlap_initiate_connection_state()\n");
+	DEBUG( 4, __FUNCTION__ "()\n");
 	
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
@@ -818,26 +864,26 @@
  *    Change the speed of the IrDA port
  *
  */
-void irlap_change_speed( struct irlap_cb *self, int speed)
+void irlap_change_speed(struct irlap_cb *self, int speed)
 {
-	DEBUG( 4, __FUNCTION__ "(), setting speed to %d\n", speed);
+	DEBUG(4, __FUNCTION__ "(), setting speed to %d\n", speed);
 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LAP_MAGIC, return;);
 
-	if ( !self->irdev) {
-		DEBUG( 0, __FUNCTION__ "(), driver missing!\n");
+	if (!self->irdev) {
+		DEBUG( 1, __FUNCTION__ "(), driver missing!\n");
 		return;
 	}
 
-	irda_device_change_speed( self->irdev, speed);
+	irda_device_change_speed(self->irdev, speed);
 
 	self->qos_rx.baud_rate.value = speed;
 	self->qos_tx.baud_rate.value = speed;
 }
 
 #ifdef CONFIG_IRDA_COMPRESSION
-void irlap_init_comp_qos_capabilities( struct irlap_cb *self)
+void irlap_init_comp_qos_capabilities(struct irlap_cb *self)
 {
 	struct irda_compressor *comp;
 	__u8 mask; /* Current bit tested */
@@ -888,8 +934,8 @@
  *    IrLAP itself. Normally, IrLAP will not specify any values, but it can
  *    be used to restrict certain values.
  */
-void irlap_init_qos_capabilities( struct irlap_cb *self, 
-				  struct qos_info *qos_user)
+void irlap_init_qos_capabilities(struct irlap_cb *self,
+				 struct qos_info *qos_user)
 {
 	ASSERT( self != NULL, return;);
 	ASSERT( self->magic == LAP_MAGIC, return;);
@@ -911,8 +957,8 @@
 	 *  allowed to supply these values. We check each parameter since the
 	 *  user may not have set all of them.
 	 */
-	if ( qos_user != NULL) {
-		DEBUG( 0, __FUNCTION__ "(), Found user specified QoS!\n");
+	if (qos_user) {
+		DEBUG( 1, __FUNCTION__ "(), Found user specified QoS!\n");
 
 		if ( qos_user->baud_rate.bits)
 			self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
@@ -966,6 +1012,7 @@
 	self->bofs_count = 11;
 
 	/* Use these until connection has been made */
+	self->slot_timeout = sysctl_slot_timeout;
 	self->final_timeout = FINAL_TIMEOUT;
 	self->poll_timeout = POLL_TIMEOUT;
 	self->wd_timeout = WD_TIMEOUT;
@@ -974,6 +1021,8 @@
 	self->qos_tx.additional_bofs.value = 11;
 
 	irlap_flush_all_queues( self);
+
+	self->disconnect_pending = FALSE;
 }
 
 /*
@@ -982,8 +1031,8 @@
  *    Initialize IrLAP with the negotiated QoS values
  *
  */
-void irlap_apply_connection_parameters( struct irlap_cb *self, 
-					struct qos_info *qos) 
+void irlap_apply_connection_parameters(struct irlap_cb *self, 
+				       struct qos_info *qos) 
 {
 	DEBUG( 4, __FUNCTION__ "()\n");
 	
@@ -1010,15 +1059,13 @@
 	 *  TODO: these values should be calculated from the final timer
          *  as well
 	 */
-	if ( qos->link_disc_time.value == 3)
+	if (qos->link_disc_time.value == 3)
 		self->N1 = 0;
 	else
-		/* self->N1 = 6; */
 		self->N1 = 3000 / qos->max_turn_time.value;
 	
 	DEBUG( 4, "Setting N1 = %d\n", self->N1);
 	
-	/* self->N2 = qos->link_disc_time.value * 2; */
 	self->N2 = qos->link_disc_time.value * 1000 / qos->max_turn_time.value;
 	DEBUG( 4, "Setting N2 = %d\n", self->N2);
 
@@ -1033,7 +1080,7 @@
 
 #ifdef CONFIG_IRDA_COMPRESSION
 	if ( qos->compression.value) {
-		DEBUG( 0, __FUNCTION__ "(), Initializing compression\n");
+		DEBUG( 1, __FUNCTION__ "(), Initializing compression\n");
 		irda_set_compression( self, qos->compression.value);
 
 		irlap_compressor_init( self, 0);
@@ -1065,7 +1112,7 @@
 		ASSERT( self != NULL, return -ENODEV;);
 		ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
 
-		len += sprintf( buf+len, "IrLAP[%d] <-> %s ",
+		len += sprintf( buf+len, "irlap%d <-> %s ",
 				i++, self->irdev->name);
 		len += sprintf( buf+len, "state: %s\n", 
 				irlap_state[ self->state]);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)