patch-2.4.0-test11 linux/net/irda/irlan/irlan_common.c

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

diff -u --recursive --new-file v2.4.0-test10/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
@@ -50,6 +50,14 @@
 #include <net/irda/irlan_eth.h>
 #include <net/irda/irlan_filter.h>
 
+
+/* 
+ * Send gratuitous ARP when connected to a new AP or not. May be a clever
+ * thing to do, but for some reason the machine crashes if you use DHCP. So
+ * lets not use it by default.
+ */
+#undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
+
 /* extern char sysctl_devname[]; */
 
 /*
@@ -62,6 +70,7 @@
 static int eth = 0; /* Use "eth" or "irlan" name for devices */
 static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
 
+#ifdef CONFIG_PROC_FS
 static char *irlan_state[] = {
 	"IRLAN_IDLE",
 	"IRLAN_QUERY",
@@ -88,6 +97,7 @@
 	"802.3",
 	"802.5"
 };
+#endif /* CONFIG_PROC_FS */
 
 static void __irlan_close(struct irlan_cb *self);
 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 
@@ -102,59 +112,6 @@
 #endif /* CONFIG_PROC_FS */
 
 /*
- * Function irlan_watchdog_timer_expired (data)
- *
- *    Something has gone wrong during the connection establishment
- *
- */
-void irlan_watchdog_timer_expired(void *data)
-{
-	struct irmanager_event mgr_event;
-	struct irlan_cb *self;
-	
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-	self = (struct irlan_cb *) data;
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRLAN_MAGIC, return;);
-
-	/* Check if device still configured */
-	if (netif_running(&self->dev)) {
-		IRDA_DEBUG(0, __FUNCTION__ 
-		      "(), notifying irmanager to stop irlan!\n");
-		mgr_event.event = EVENT_IRLAN_STOP;
-		sprintf(mgr_event.devname, "%s", self->dev.name);
-		irmanager_notify(&mgr_event);
-
-		/*
-		 *  We set this to false, so that irlan_dev_close known that
-		 *  notify_irmanager should actually be set to TRUE again 
-		 *  instead of FALSE, since this close has not been initiated
-		 *  by the user.
-		 */
-		self->notify_irmanager = FALSE;
-	} else {
-		IRDA_DEBUG(0, __FUNCTION__ "(), closing instance!\n");
-		/*irlan_close(self);*/
-	}
-}
-
-/*
- * Function irlan_start_watchdog_timer (self, timeout)
- *
- *    
- *
- */
-void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout)
-{
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
-	irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
-			 irlan_watchdog_timer_expired);
-}
-
-/*
  * Function irlan_init (void)
  *
  *    Initialize IrLAN layer
@@ -165,8 +122,7 @@
 	struct irlan_cb *new;
 	__u16 hints;
 
-	IRDA_DEBUG(4, __FUNCTION__"()\n");
-
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 	/* Allocate master structure */
 	irlan = hashbin_new(HB_LOCAL); 
 	if (irlan == NULL) {
@@ -178,22 +134,20 @@
 #endif /* CONFIG_PROC_FS */
 
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
 	hints = irlmp_service_to_hint(S_LAN);
 
 	/* Register with IrLMP as a client */
-	ckey = irlmp_register_client(hints, irlan_client_discovery_indication,
-				     NULL);
+	ckey = irlmp_register_client(hints, &irlan_client_discovery_indication,
+				     NULL, NULL);
 	
 	/* Register with IrLMP as a service */
  	skey = irlmp_register_service(hints);
 
-	/* Start the master IrLAN instance */
- 	new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
+	/* Start the master IrLAN instance (the only one for now) */
+ 	new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY);
 
 	/* The master will only open its (listen) control TSAP */
 	irlan_provider_open_ctrl_tsap(new);
-	new->master = TRUE;
 
 	/* Do some fast discovery! */
 	irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
@@ -206,7 +160,6 @@
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	irlmp_unregister_client(ckey);
-
 	irlmp_unregister_service(skey);
 
 #ifdef CONFIG_PROC_FS
@@ -242,8 +195,6 @@
 		IRDA_DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n");
 		return -1;
 	}
-	self->netdev_registered = TRUE;
-	
 	return 0;
 }
 
@@ -253,7 +204,7 @@
  *    Open new instance of a client/provider, we should only register the 
  *    network device if this instance is ment for a particular client/provider
  */
-struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev)
+struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
 {
 	struct irlan_cb *self;
 
@@ -287,32 +238,28 @@
 	/* Provider access can only be PEER, DIRECT, or HOSTED */
 	self->provider.access_type = access;
 	self->media = MEDIA_802_3;
-
-	self->notify_irmanager = TRUE;
-
+	self->disconnect_reason = LM_USER_REQUEST;
 	init_timer(&self->watchdog_timer);
 	init_timer(&self->client.kick_timer);
+	init_waitqueue_head(&self->open_wait);	
 
-	hashbin_insert(irlan, (queue_t *) self, daddr, NULL);
+	hashbin_insert(irlan, (irda_queue_t *) self, daddr, NULL);
 	
 	skb_queue_head_init(&self->client.txq);
 	
 	irlan_next_client_state(self, IRLAN_IDLE);
 	irlan_next_provider_state(self, IRLAN_IDLE);
 
-	/* Register network device now, or wait until some later time? */
-	if (netdev)
-		irlan_register_netdev(self);
+	irlan_register_netdev(self);
 
 	return self;
 }
 /*
- * Function irlan_close (self)
+ * Function __irlan_close (self)
  *
  *    This function closes and deallocates the IrLAN client instances. Be 
  *    aware that other functions which calles client_close() must call 
  *    hashbin_remove() first!!!
- *
  */
 static void __irlan_close(struct irlan_cb *self)
 {
@@ -333,49 +280,13 @@
 		iriap_close(self->client.iriap);
 
 	/* Remove frames queued on the control channel */
-	while ((skb = skb_dequeue(&self->client.txq))) {
+	while ((skb = skb_dequeue(&self->client.txq)))
 		dev_kfree_skb(skb);
-	}
 
-	if (self->netdev_registered) {
-		unregister_netdev(&self->dev);
-		self->netdev_registered = FALSE;
-	}
+	unregister_netdev(&self->dev);
 	
 	self->magic = 0;
- 	kfree(self);
-}
-
-/*
- * Function irlan_close (self)
- *
- *    Close instance
- *
- */
-void irlan_close(struct irlan_cb *self)
-{
-	struct irlan_cb *entry;
-
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-        ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRLAN_MAGIC, return;);
-
-	/* Check if device is still configured */
-	if (netif_running(&self->dev)) {
-		IRDA_DEBUG(0, __FUNCTION__ 
-		       "(), Device still configured, closing later!\n");
-
-		/* Give it a chance to reconnect */
-		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
-		return;
-	}
-	IRDA_DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
-	entry = hashbin_remove(irlan, self->daddr, NULL);
-
-	ASSERT(entry == self, return;);
-	
-        __irlan_close(self);
+	kfree(self);
 }
 
 /*
@@ -419,7 +330,7 @@
 		irlan_open_unicast_addr(self);
 	}
 	/* Ready to transfer Ethernet frames (at last) */
-	netif_start_queue(&self->dev);
+	netif_start_queue(&self->dev); /* Clear reason */
 }
 
 void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
@@ -454,7 +365,11 @@
 
 	/* Ready to transfer Ethernet frames */
 	netif_start_queue(&self->dev);
+	self->disconnect_reason = 0; /* Clear reason */
+#ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
 	irlan_eth_send_gratuitous_arp(&self->dev);
+#endif
+	wake_up_interruptible(&self->open_wait);
 }
 
 /*
@@ -483,28 +398,34 @@
 
 	IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
 
-	switch(reason) {
+	/* Save reason so we know if we should try to reconnect or not */
+	self->disconnect_reason = reason;
+	
+	switch (reason) {
 	case LM_USER_REQUEST: /* User request */
-		irlan_close(self);
+		IRDA_DEBUG(2, __FUNCTION__ "(), User requested\n");
 		break;
 	case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
-		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unexpected IrLAP disconnect\n");
 		break;
 	case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
-		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP connect failed\n");
 		break;
 	case LM_LAP_RESET:  /* IrLAP reset */
-		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IrLAP reset\n");
 		break;
 	case LM_INIT_DISCONNECT:
-		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IrLMP connect failed\n");
 		break;
 	default:
+		ERROR(__FUNCTION__ "(), Unknown disconnect reason\n");
 		break;
 	}
 	
 	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
 	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
+	
+	wake_up_interruptible(&self->open_wait);
 }
 
 void irlan_open_data_tsap(struct irlan_cb *self)
@@ -553,9 +474,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-	/* 
-	 *  Disconnect and close all open TSAP connections
-	 */
+	/* Disconnect and close all open TSAP connections */
 	if (self->tsap_data) {
 		irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
 		irttp_close_tsap(self->tsap_data);
@@ -573,6 +492,7 @@
 		irttp_close_tsap(self->provider.tsap_ctrl);
 		self->provider.tsap_ctrl = NULL;
 	}
+	self->disconnect_reason = LM_USER_REQUEST;
 }
 
 /*
@@ -595,7 +515,8 @@
 	 */
 	if (!irias_find_object("IrLAN")) {
 		obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
-		irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel);
+		irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
+					 IAS_KERNEL_ATTR);
 		irias_insert_object(obj);
 	} else {
 		new_value = irias_new_integer_value(tsap_sel);
@@ -607,18 +528,23 @@
         if (!irias_find_object("PnP")) {
 		obj = irias_new_object("PnP", IAS_PNP_ID);
 #if 0
-		irias_add_string_attrib(obj, "Name", sysctl_devname);
+		irias_add_string_attrib(obj, "Name", sysctl_devname,
+					IAS_KERNEL_ATTR);
 #else
-		irias_add_string_attrib(obj, "Name", "Linux");
+		irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
 #endif
-		irias_add_string_attrib(obj, "DeviceID", "HWP19F0");
-		irias_add_integer_attrib(obj, "CompCnt", 1);
+		irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
+					IAS_KERNEL_ATTR);
+		irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
 		if (self->provider.access_type == ACCESS_PEER)
-			irias_add_string_attrib(obj, "Comp#01", "PNP8389");
+			irias_add_string_attrib(obj, "Comp#01", "PNP8389",
+						IAS_KERNEL_ATTR);
 		else
-			irias_add_string_attrib(obj, "Comp#01", "PNP8294");
+			irias_add_string_attrib(obj, "Comp#01", "PNP8294",
+						IAS_KERNEL_ATTR);
 
-		irias_add_string_attrib(obj, "Manufacturer", "Linux-IrDA Project");
+		irias_add_string_attrib(obj, "Manufacturer",
+					"Linux-IrDA Project", IAS_KERNEL_ATTR);
 		irias_insert_object(obj);
 	}
 }
@@ -633,7 +559,7 @@
 {
 	struct sk_buff *skb;
 
-	IRDA_DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (irda_lock(&self->client.tx_busy) == FALSE)
 		return -EBUSY;
@@ -652,7 +578,7 @@
 		dev_kfree_skb(skb);
 		return -1;
 	}
-	IRDA_DEBUG(3, __FUNCTION__ "(), sending ...\n");
+	IRDA_DEBUG(2, __FUNCTION__ "(), sending ...\n");
 
 	return irttp_data_request(self->client.tsap_ctrl, skb);
 }
@@ -741,7 +667,6 @@
 
 /* 	self->use_udata = TRUE; */
 
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -810,7 +735,6 @@
  	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
  	irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); 
 	
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -852,7 +776,6 @@
 	else
 		irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 
 
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -892,7 +815,6 @@
 	else
 		irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 
 
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -930,7 +852,6 @@
  	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
  	irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC"); 
 	
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -965,8 +886,6 @@
 	frame[1] = 0x01; /* One parameter */
 	
 	irlan_insert_string_param(skb, "MEDIA", "802.3");
-	
-	/* irttp_data_request(self->client.tsap_ctrl, skb); */
 	irlan_ctrl_data_request(self, skb);
 }
 
@@ -1169,35 +1088,32 @@
 	while (self != NULL) {
 		ASSERT(self->magic == IRLAN_MAGIC, return len;);
 		
-		/* Don't display the master server */
-		if (self->master == 0) {
-			len += sprintf(buf+len, "ifname: %s,\n",
-				       self->dev.name);
-			len += sprintf(buf+len, "client state: %s, ",
-				       irlan_state[ self->client.state]);
-			len += sprintf(buf+len, "provider state: %s,\n",
-				       irlan_state[ self->provider.state]);
-			len += sprintf(buf+len, "saddr: %#08x, ",
-				       self->saddr);
-			len += sprintf(buf+len, "daddr: %#08x\n",
-				       self->daddr);
-			len += sprintf(buf+len, "version: %d.%d,\n",
-				       self->version[1], self->version[0]);
-			len += sprintf(buf+len, "access type: %s\n", 
-				       irlan_access[self->client.access_type]);
-			len += sprintf(buf+len, "media: %s\n", 
-				       irlan_media[self->media]);
-			
-			len += sprintf(buf+len, "local filter:\n");
-			len += sprintf(buf+len, "remote filter: ");
-			len += irlan_print_filter(self->client.filter_type, 
-						  buf+len);
+		len += sprintf(buf+len, "ifname: %s,\n",
+			       self->dev.name);
+		len += sprintf(buf+len, "client state: %s, ",
+			       irlan_state[ self->client.state]);
+		len += sprintf(buf+len, "provider state: %s,\n",
+			       irlan_state[ self->provider.state]);
+		len += sprintf(buf+len, "saddr: %#08x, ",
+			       self->saddr);
+		len += sprintf(buf+len, "daddr: %#08x\n",
+			       self->daddr);
+		len += sprintf(buf+len, "version: %d.%d,\n",
+			       self->version[1], self->version[0]);
+		len += sprintf(buf+len, "access type: %s\n", 
+			       irlan_access[self->client.access_type]);
+		len += sprintf(buf+len, "media: %s\n", 
+			       irlan_media[self->media]);
+		
+		len += sprintf(buf+len, "local filter:\n");
+		len += sprintf(buf+len, "remote filter: ");
+		len += irlan_print_filter(self->client.filter_type, 
+					  buf+len);
 			
-			len += sprintf(buf+len, "tx busy: %s\n", 
-				       netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE");
+		len += sprintf(buf+len, "tx busy: %s\n", 
+			       netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE");
 			
-			len += sprintf(buf+len, "\n");
-		}
+		len += sprintf(buf+len, "\n");
 
 		self = (struct irlan_cb *) hashbin_get_next(irlan);
  	} 
@@ -1272,8 +1188,9 @@
 MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); 
 
 MODULE_PARM(eth, "i");
+MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
 MODULE_PARM(access, "i");
-MODULE_PARM(timeout, "i");
+MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");
 
 /*
  * Function init_module (void)

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