diff -u -p -r linux/include/net/irda-d4/af_irda.h linux/include/net/irda/af_irda.h
--- linux/include/net/irda-d4/af_irda.h	Mon Nov  4 14:30:49 2002
+++ linux/include/net/irda/af_irda.h	Wed Jan  8 17:00:47 2003
@@ -52,8 +52,8 @@ struct irda_sock {
 	__u8  max_header_size;
 	struct qos_info qos_tx;
 
-	__u16 mask;           /* Hint bits mask */
-	__u16 hints;          /* Hint bits */
+	__u16_host_order mask;           /* Hint bits mask */
+	__u16_host_order hints;          /* Hint bits */
 
 	void *ckey;           /* IrLMP client handle */
 	void *skey;           /* IrLMP service handle */
@@ -63,7 +63,7 @@ struct irda_sock {
 	struct ias_value *ias_result; /* Result of remote IAS query */
 
 	hashbin_t *cachelog;		/* Result of discovery query */
-	struct discovery_t *cachediscovery;	/* Result of selective discovery query */
+	__u32 cachedaddr;	/* Result of selective discovery query */
 
 	int nslots;           /* Number of slots to use for discovery */
 
diff -u -p -r linux/include/net/irda-d4/discovery.h linux/include/net/irda/discovery.h
--- linux/include/net/irda-d4/discovery.h	Mon Nov  4 14:30:36 2002
+++ linux/include/net/irda/discovery.h	Wed Jan  8 17:00:47 2003
@@ -46,12 +46,20 @@
  *  little endian format. A little endian machine stores MSB of word in
  *  byte[1] and LSB in byte[0]. A big endian machine stores MSB in byte[0] 
  *  and LSB in byte[1].
+ *
+ * This structure is used in the code for things that are endian neutral
+ * but that fit in a word so that we can manipulate them efficiently.
+ * By endian neutral, I mean things that are really an array of bytes,
+ * and always used as such, for example the hint bits. Jean II
  */
 typedef union {
 	__u16 word;
 	__u8  byte[2];
 } __u16_host_order;
 
+/* Same purpose, different application */
+#define u16ho(array) (* ((__u16 *) array))
+
 /* Types of discovery */
 typedef enum {
 	DISCOVERY_LOG,		/* What's in our discovery log */
@@ -62,30 +70,31 @@ typedef enum {
 
 #define NICKNAME_MAX_LEN 21
 
+/* Basic discovery information about a peer */
+typedef struct irda_device_info		discinfo_t;	/* linux/irda.h */
+
 /*
  * The DISCOVERY structure is used for both discovery requests and responses
  */
 typedef struct discovery_t {
-	irda_queue_t q;          /* Must be first! */
+	irda_queue_t	q;		/* Must be first! */
+
+	discinfo_t	data;		/* Basic discovery information */
+	int		name_len;	/* Lenght of nickname */
 
-	__u32      saddr;        /* Which link the device was discovered */
-	__u32      daddr;        /* Remote device address */
-	LAP_REASON condition;    /* More info about the discovery */
-
-	__u16_host_order hints;  /* Discovery hint bits */
-	__u8       charset;      /* Encoding of nickname */
-	char       nickname[22]; /* The name of the device (21 bytes + \0) */
-	int        name_len;     /* Lenght of nickname */
-
-	int        gen_addr_bit; /* Need to generate a new device address? */
-	int        nslots;       /* Number of slots to use when discovering */
-	unsigned long timestamp; /* Time discovered */
-	unsigned long first_timestamp; /* First time discovered */
+	LAP_REASON	condition;	/* More info about the discovery */
+	int		gen_addr_bit;	/* Need to generate a new device
+					 * address? */
+	int		nslots;		/* Number of slots to use when
+					 * discovering */
+	unsigned long	timestamp;	/* Last time discovered */
+	unsigned long	firststamp;	/* First time discovered */
 } discovery_t;
 
 void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery);
 void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log);
 void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force);
-struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 mask);
+struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
+						__u16 mask, int old_entries);
 
 #endif
diff -u -p -r linux/include/net/irda-d4/irlan_client.h linux/include/net/irda/irlan_client.h
--- linux/include/net/irda-d4/irlan_client.h	Mon Nov  4 14:30:47 2002
+++ linux/include/net/irda/irlan_client.h	Wed Jan  8 17:00:47 2003
@@ -34,7 +34,7 @@
 #include <net/irda/irlan_event.h>
 
 void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout);
-void irlan_client_discovery_indication(discovery_t *, DISCOVERY_MODE, void *);
+void irlan_client_discovery_indication(discinfo_t *, DISCOVERY_MODE, void *);
 void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr);
 
 void irlan_client_open_ctrl_tsap( struct irlan_cb *self);
diff -u -p -r linux/include/net/irda-d4/irlmp.h linux/include/net/irda/irlmp.h
--- linux/include/net/irda-d4/irlmp.h	Mon Nov  4 14:30:04 2002
+++ linux/include/net/irda/irlmp.h	Wed Jan  8 17:00:47 2003
@@ -58,7 +58,7 @@
 #define LM_IDLE_TIMEOUT     2*HZ /* 2 seconds for now */
 
 typedef enum {
-	S_PNP,
+	S_PNP = 0,
 	S_PDA,
 	S_COMPUTER,
 	S_PRINTER,
@@ -72,22 +72,24 @@ typedef enum {
 	S_END,
 } SERVICE;
 
-typedef void (*DISCOVERY_CALLBACK1) (discovery_t *, DISCOVERY_MODE, void *);
-typedef void (*DISCOVERY_CALLBACK2) (hashbin_t *, void *);
+/* For selective discovery */
+typedef void (*DISCOVERY_CALLBACK1) (discinfo_t *, DISCOVERY_MODE, void *);
+/* For expiry (the same) */
+typedef void (*DISCOVERY_CALLBACK2) (discinfo_t *, DISCOVERY_MODE, void *);
 
 typedef struct {
 	irda_queue_t queue; /* Must be first */
 
-	__u16 hints; /* Hint bits */
+	__u16_host_order hints; /* Hint bits */
 } irlmp_service_t;
 
 typedef struct {
 	irda_queue_t queue; /* Must be first */
 
-	__u16 hint_mask;
+	__u16_host_order hint_mask;
 
 	DISCOVERY_CALLBACK1 disco_callback;	/* Selective discovery */
-	DISCOVERY_CALLBACK1 expir_callback;	/* Selective expiration */
+	DISCOVERY_CALLBACK2 expir_callback;	/* Selective expiration */
 	void *priv;                /* Used to identify client */
 } irlmp_client_t;
 
@@ -199,11 +201,11 @@ __u16 irlmp_service_to_hint(int service)
 void *irlmp_register_service(__u16 hints);
 int irlmp_unregister_service(void *handle);
 void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
-			    DISCOVERY_CALLBACK1 expir_clb, void *priv);
+			    DISCOVERY_CALLBACK2 expir_clb, void *priv);
 int irlmp_unregister_client(void *handle);
 int irlmp_update_client(void *handle, __u16 hint_mask, 
 			DISCOVERY_CALLBACK1 disco_clb,
-			DISCOVERY_CALLBACK1 expir_clb, void *priv);
+			DISCOVERY_CALLBACK2 expir_clb, void *priv);
 
 void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *);
 void irlmp_unregister_link(__u32 saddr);
@@ -222,11 +224,11 @@ int  irlmp_disconnect_request(struct lsa
 
 void irlmp_discovery_confirm(hashbin_t *discovery_log, DISCOVERY_MODE mode);
 void irlmp_discovery_request(int nslots);
-struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots);
+discinfo_t *irlmp_get_discoveries(int *pn, __u16 mask, int nslots);
 void irlmp_do_expiry(void);
 void irlmp_do_discovery(int nslots);
 discovery_t *irlmp_get_discovery_response(void);
-void irlmp_discovery_expiry(discovery_t *expiry);
+void irlmp_discovery_expiry(discinfo_t *expiry, int number);
 
 int  irlmp_data_request(struct lsap_cb *, struct sk_buff *);
 void irlmp_data_indication(struct lsap_cb *, struct sk_buff *);
diff -u -p -r linux/net/irda-d4/af_irda.c linux/net/irda/af_irda.c
--- linux/net/irda-d4/af_irda.c	Tue Jan  7 17:59:03 2003
+++ linux/net/irda/af_irda.c	Wed Jan  8 17:00:47 2003
@@ -401,11 +401,10 @@ static void irda_getvalue_confirm(int re
  *
  *    Got a selective discovery indication from IrLMP.
  *
- * IrLMP is telling us that this node is matching our hint bit
- * filter. Check if it's a newly discovered node (or if node changed its
- * hint bits), and then wake up any process waiting for answer...
+ * IrLMP is telling us that this node is new and matching our hint bit
+ * filter. Wake up any process waiting for answer...
  */
-static void irda_selective_discovery_indication(discovery_t *discovery,
+static void irda_selective_discovery_indication(discinfo_t *discovery,
 						DISCOVERY_MODE mode,
 						void *priv)
 {
@@ -419,18 +418,8 @@ static void irda_selective_discovery_ind
 		return;
 	}
 
-	/* Check if node is discovered is a new one or an old one.
-	 * We check when how long ago this node was discovered, with a
-	 * coarse timeout (we may miss some discovery events or be delayed).
-	 * Note : by doing this test here, we avoid waking up a process ;-)
-	 */
-	if((jiffies - discovery->first_timestamp) >
-	   (sysctl_discovery_timeout * HZ)) {
-		return;		/* Too old, not interesting -> goodbye */
-	}
-
 	/* Pass parameter to the caller */
-	self->cachediscovery = discovery;
+	self->cachedaddr = discovery->daddr;
 
 	/* Wake up process if its waiting for device to be discovered */
 	wake_up_interruptible(&self->query_wait);
@@ -455,7 +444,7 @@ static void irda_discovery_timeout(u_lon
 
 	/* Nothing for the caller */
 	self->cachelog = NULL;
-	self->cachediscovery = NULL;
+	self->cachedaddr = 0;
 	self->errno = -ETIME;
 
 	/* Wake up process if its still waiting... */
@@ -627,7 +616,7 @@ static int irda_find_lsap_sel(struct ird
  */
 static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
 {
-	struct irda_device_info *discoveries;	/* Copy of the discovery log */
+	discinfo_t *discoveries;	/* Copy of the discovery log */
 	int	number;			/* Number of nodes in the log */
 	int	i;
 	int	err = -ENETUNREACH;
@@ -642,7 +631,8 @@ static int irda_discover_daddr_and_lsap_
 	 * Note : we have to use irlmp_get_discoveries(), as opposed
 	 * to play with the cachelog directly, because while we are
 	 * making our ias query, le log might change... */
-	discoveries = irlmp_get_discoveries(&number, self->mask, self->nslots);
+	discoveries = irlmp_get_discoveries(&number, self->mask.word,
+					    self->nslots);
 	/* Check if the we got some results */
 	if (discoveries == NULL)
 		return -ENETUNREACH;	/* No nodes discovered */
@@ -1137,7 +1127,7 @@ static int irda_create(struct socket *so
 
 	/* Register as a client with IrLMP */
 	self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
-	self->mask = 0xffff;
+	self->mask.word = 0xffff;
 	self->rx_flow = self->tx_flow = FLOW_START;
 	self->nslots = DISCOVERY_DEFAULT_SLOTS;
 	self->daddr = DEV_ADDR_ANY;	/* Until we get connected */
@@ -1999,6 +1989,7 @@ static int irda_setsockopt(struct socket
 		if (optlen < sizeof(int))
 			return -EINVAL;
 
+		/* The input is really a (__u8 hints[2]), easier as an int */
 		if (get_user(opt, (int *)optval))
 			return -EFAULT;
 
@@ -2017,16 +2008,17 @@ static int irda_setsockopt(struct socket
 		if (optlen < sizeof(int))
 			return -EINVAL;
 
+		/* The input is really a (__u8 hints[2]), easier as an int */
 		if (get_user(opt, (int *)optval))
 			return -EFAULT;
 
 		/* Set the new hint mask */
-		self->mask = (__u16) opt;
+		self->mask.word = (__u16) opt;
 		/* Mask out extension bits */
-		self->mask &= 0x7f7f;
+		self->mask.word &= 0x7f7f;
 		/* Check if no bits */
-		if(!self->mask)
-			self->mask = 0xFFFF;
+		if(!self->mask.word)
+			self->mask.word = 0xFFFF;
 
 		break;
 	default:
@@ -2117,7 +2109,7 @@ static int irda_getsockopt(struct socket
 	switch (optname) {
 	case IRLMP_ENUMDEVICES:
 		/* Ask lmp for the current discovery log */
-		discoveries = irlmp_get_discoveries(&list.len, self->mask,
+		discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
 						    self->nslots);
 		/* Check if the we got some results */
 		if (discoveries == NULL)
@@ -2349,7 +2341,7 @@ bed:
 			return -EFAULT;
 
 		/* Tell IrLMP we want to be notified */
-		irlmp_update_client(self->ckey, self->mask,
+		irlmp_update_client(self->ckey, self->mask.word,
 				    irda_selective_discovery_indication,
 				    NULL, (void *) self);
 
@@ -2357,7 +2349,7 @@ bed:
 		irlmp_discovery_request(self->nslots);
 
 		/* Wait until a node is discovered */
-		if (!self->cachediscovery) {
+		if (!self->cachedaddr) {
 			int ret = 0;
 
 			IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __FUNCTION__);
@@ -2372,7 +2364,7 @@ bed:
 
 			/* Wait for IR-LMP to call us back */
 			__wait_event_interruptible(self->query_wait,
-			   (self->cachediscovery!=NULL || self->errno==-ETIME),
+			      (self->cachedaddr != 0 || self->errno == -ETIME),
 						   ret);
 
 			/* If watchdog is still activated, kill it! */
@@ -2389,19 +2381,25 @@ bed:
 				   __FUNCTION__);
 
 		/* Tell IrLMP that we have been notified */
-		irlmp_update_client(self->ckey, self->mask, NULL, NULL, NULL);
+		irlmp_update_client(self->ckey, self->mask.word,
+				    NULL, NULL, NULL);
 
 		/* Check if the we got some results */
-		if (!self->cachediscovery)
+		if (!self->cachedaddr)
 			return -EAGAIN;		/* Didn't find any devices */
+		daddr = self->cachedaddr;
 		/* Cleanup */
-		self->cachediscovery = NULL;
+		self->cachedaddr = 0;
 
-		/* Note : We don't return anything to the user.
-		 * We could return the device that triggered the wake up,
-		 * but it's probably better to force the user to query
-		 * the whole discovery log and let him pick one device...
+		/* We return the daddr of the device that trigger the
+		 * wakeup. As irlmp pass us only the new devices, we
+		 * are sure that it's not an old device.
+		 * If the user want more details, he should query
+		 * the whole discovery log and pick one device...
 		 */
+		if (put_user(daddr, (int *)optval))
+			return -EFAULT;
+
 		break;
 	default:
 		return -ENOPROTOOPT;
diff -u -p -r linux/net/irda-d4/discovery.c linux/net/irda/discovery.c
--- linux/net/irda-d4/discovery.c	Mon Nov  4 14:30:15 2002
+++ linux/net/irda/discovery.c	Wed Jan  8 17:00:47 2003
@@ -59,7 +59,7 @@ void irlmp_add_discovery(hashbin_t *cach
 	unsigned long flags;
 
 	/* Set time of first discovery if node is new (see below) */
-	new->first_timestamp = new->timestamp;
+	new->firststamp = new->timestamp;
 
 	spin_lock_irqsave(&cachelog->hb_spinlock, flags);
 
@@ -76,24 +76,24 @@ void irlmp_add_discovery(hashbin_t *cach
 		/* Be sure to stay one item ahead */
 		discovery = (discovery_t *) hashbin_get_next(cachelog);
 
-		if ((node->saddr == new->saddr) &&
-		    ((node->daddr == new->daddr) || 
-		     (strcmp(node->nickname, new->nickname) == 0)))
+		if ((node->data.saddr == new->data.saddr) &&
+		    ((node->data.daddr == new->data.daddr) || 
+		     (strcmp(node->data.info, new->data.info) == 0)))
 		{
 			/* This discovery is a previous discovery 
 			 * from the same device, so just remove it
 			 */
 			hashbin_remove_this(cachelog, (irda_queue_t *) node);
-			/* Check if hints bits have changed */
-			if(node->hints.word == new->hints.word)
+			/* Check if hints bits are unchanged */
+			if(u16ho(node->data.hints) == u16ho(new->data.hints))
 				/* Set time of first discovery for this node */
-				new->first_timestamp = node->first_timestamp;
+				new->firststamp = node->firststamp;
 			kfree(node);
 		}
 	}
 
 	/* Insert the new and updated version */
-	hashbin_insert(cachelog, (irda_queue_t *) new, new->daddr, NULL);
+	hashbin_insert(cachelog, (irda_queue_t *) new, new->data.daddr, NULL);
 
 	spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
 }
@@ -147,27 +147,50 @@ void irlmp_add_discovery_log(hashbin_t *
  */
 void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
 {
-	discovery_t *discovery, *curr;
-	unsigned long flags;
+	discovery_t *		discovery;
+	discovery_t *		curr;
+	unsigned long		flags;
+	discinfo_t *		buffer = NULL;
+	int			n;		/* Size of the full log */
+	int			i = 0;		/* How many we expired */
 
+	ASSERT(log != NULL, return;);
 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
 	spin_lock_irqsave(&log->hb_spinlock, flags);
 
 	discovery = (discovery_t *) hashbin_get_first(log);
 	while (discovery != NULL) {
-		curr = discovery;
-
 		/* Be sure to be one item ahead */
+		curr = discovery;
 		discovery = (discovery_t *) hashbin_get_next(log);
 
 		/* Test if it's time to expire this discovery */
-		if ((curr->saddr == saddr) &&
+		if ((curr->data.saddr == saddr) &&
 		    (force ||
 		     ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT)))
 		{
-			/* Tell IrLMP and registered clients about it */
-			irlmp_discovery_expiry(curr);
+			/* Create buffer as needed.
+			 * As this function get called a lot and most time
+			 * we don't have anything to put in the log (we are
+			 * quite picky), we can save a lot of overhead
+			 * by not calling kmalloc. Jean II */
+			if(buffer == NULL) {
+				/* Create the client specific buffer */
+				n = HASHBIN_GET_SIZE(log);
+				buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
+				if (buffer == NULL) {
+					spin_unlock_irqrestore(&log->hb_spinlock, flags);
+					return;
+				}
+
+			}
+
+			/* Copy discovery information */
+			memcpy(&(buffer[i]), &(curr->data),
+			       sizeof(discinfo_t));
+			i++;
+
 			/* Remove it from the log */
 			curr = hashbin_remove_this(log, (irda_queue_t *) curr);
 			if (curr)
@@ -175,9 +198,23 @@ void irlmp_expire_discoveries(hashbin_t 
 		}
 	}
 
+	/* Drop the spinlock before calling the higher layers, as
+	 * we can't guarantee they won't call us back and create a
+	 * deadlock. We will work on our own private data, so we
+	 * don't care to be interupted. - Jean II */
 	spin_unlock_irqrestore(&log->hb_spinlock, flags);
+
+	if(buffer == NULL)
+		return;
+
+	/* Tell IrLMP and registered clients about it */
+	irlmp_discovery_expiry(buffer, i);
+
+	/* Free up our buffer */
+	kfree(buffer);
 }
 
+#if 0
 /*
  * Function irlmp_dump_discoveries (log)
  *
@@ -193,13 +230,14 @@ void irlmp_dump_discoveries(hashbin_t *l
 	discovery = (discovery_t *) hashbin_get_first(log);
 	while (discovery != NULL) {
 		IRDA_DEBUG(0, "Discovery:\n");
-		IRDA_DEBUG(0, "  daddr=%08x\n", discovery->daddr);
-		IRDA_DEBUG(0, "  saddr=%08x\n", discovery->saddr); 
-		IRDA_DEBUG(0, "  nickname=%s\n", discovery->nickname);
+		IRDA_DEBUG(0, "  daddr=%08x\n", discovery->data.daddr);
+		IRDA_DEBUG(0, "  saddr=%08x\n", discovery->data.saddr); 
+		IRDA_DEBUG(0, "  nickname=%s\n", discovery->data.info);
 
 		discovery = (discovery_t *) hashbin_get_next(log);
 	}
 }
+#endif
 
 /*
  * Function irlmp_copy_discoveries (log, pn, mask)
@@ -221,43 +259,49 @@ void irlmp_dump_discoveries(hashbin_t *l
  * Note : the client must kfree himself() the log...
  * Jean II
  */
-struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 mask)
+struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
+						__u16 mask, int old_entries)
 {
-	discovery_t *			discovery;
-	unsigned long			flags;
-	struct irda_device_info *	buffer;
-	int				i = 0;
-	int				n;
+	discovery_t *		discovery;
+	unsigned long		flags;
+	discinfo_t *		buffer = NULL;
+	int			j_timeout = (sysctl_discovery_timeout * HZ);
+	int			n;		/* Size of the full log */
+	int			i = 0;		/* How many we picked */
 
 	ASSERT(pn != NULL, return NULL;);
+	ASSERT(log != NULL, return NULL;);
 
-	/* Check if log is empty */
-	if(log == NULL)
-		return NULL;
-
-	/* Save spin lock - spinlock should be discovery specific */
+	/* Save spin lock */
 	spin_lock_irqsave(&log->hb_spinlock, flags);
 
-	/* Create the client specific buffer */
-	n = HASHBIN_GET_SIZE(log);
-	buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
-	if (buffer == NULL) {
-		spin_unlock_irqrestore(&log->hb_spinlock, flags);
-		return NULL;
-	}
-
 	discovery = (discovery_t *) hashbin_get_first(log);
-	while ((discovery != NULL) && (i < n)) {
-		/* Mask out the ones we don't want */
-		if (discovery->hints.word & mask) {
+	while (discovery != NULL) {
+		/* Mask out the ones we don't want :
+		 * We want to match the discovery mask, and to get only
+		 * the most recent one (unless we want old ones) */
+		if ((u16ho(discovery->data.hints) & mask) &&
+		    ((old_entries) ||
+		     ((jiffies - discovery->firststamp) < j_timeout)) ) {
+			/* Create buffer as needed.
+			 * As this function get called a lot and most time
+			 * we don't have anything to put in the log (we are
+			 * quite picky), we can save a lot of overhead
+			 * by not calling kmalloc. Jean II */
+			if(buffer == NULL) {
+				/* Create the client specific buffer */
+				n = HASHBIN_GET_SIZE(log);
+				buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
+				if (buffer == NULL) {
+					spin_unlock_irqrestore(&log->hb_spinlock, flags);
+					return NULL;
+				}
+
+			}
+
 			/* Copy discovery information */
-			buffer[i].saddr = discovery->saddr;
-			buffer[i].daddr = discovery->daddr;
-			buffer[i].charset = discovery->charset;
-			buffer[i].hints[0] = discovery->hints.byte[0];
-			buffer[i].hints[1] = discovery->hints.byte[1];
-			strncpy(buffer[i].info, discovery->nickname,
-				NICKNAME_MAX_LEN);
+			memcpy(&(buffer[i]), &(discovery->data),
+			       sizeof(discinfo_t));
 			i++;
 		}
 		discovery = (discovery_t *) hashbin_get_next(log);
@@ -288,14 +332,14 @@ __u32 irlmp_find_device(hashbin_t *cache
 	d = (discovery_t *) hashbin_get_first(cachelog);
 	while (d != NULL) {
 		IRDA_DEBUG(1, "Discovery:\n");
-		IRDA_DEBUG(1, "  daddr=%08x\n", d->daddr);
-		IRDA_DEBUG(1, "  nickname=%s\n", d->nickname);
-		
-		if (strcmp(name, d->nickname) == 0) {
-			*saddr = d->saddr;
+		IRDA_DEBUG(1, "  daddr=%08x\n", d->data.daddr);
+		IRDA_DEBUG(1, "  nickname=%s\n", d->data.info);
+
+		if (strcmp(name, d->data.info) == 0) {
+			*saddr = d->data.saddr;
 			
 			spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
-			return d->daddr;
+			return d->data.daddr;
 		}
 		d = (discovery_t *) hashbin_get_next(cachelog);
 	}
@@ -328,41 +372,41 @@ int discovery_proc_read(char *buf, char 
 
 	discovery = (discovery_t *) hashbin_get_first(cachelog);
 	while (( discovery != NULL) && (len < length)) {
-		len += sprintf(buf+len, "nickname: %s,", discovery->nickname);
+		len += sprintf(buf+len, "nickname: %s,", discovery->data.info);
 		
 		len += sprintf(buf+len, " hint: 0x%02x%02x", 
-			       discovery->hints.byte[0], 
-			       discovery->hints.byte[1]);
+			       discovery->data.hints[0], 
+			       discovery->data.hints[1]);
 #if 0
-		if ( discovery->hints.byte[0] & HINT_PNP)
+		if ( discovery->data.hints[0] & HINT_PNP)
 			len += sprintf( buf+len, "PnP Compatible ");
-		if ( discovery->hints.byte[0] & HINT_PDA)
+		if ( discovery->data.hints[0] & HINT_PDA)
 			len += sprintf( buf+len, "PDA/Palmtop ");
-		if ( discovery->hints.byte[0] & HINT_COMPUTER)
+		if ( discovery->data.hints[0] & HINT_COMPUTER)
 			len += sprintf( buf+len, "Computer ");
-		if ( discovery->hints.byte[0] & HINT_PRINTER)
+		if ( discovery->data.hints[0] & HINT_PRINTER)
 			len += sprintf( buf+len, "Printer ");
-		if ( discovery->hints.byte[0] & HINT_MODEM)
+		if ( discovery->data.hints[0] & HINT_MODEM)
 			len += sprintf( buf+len, "Modem ");
-		if ( discovery->hints.byte[0] & HINT_FAX)
+		if ( discovery->data.hints[0] & HINT_FAX)
 			len += sprintf( buf+len, "Fax ");
-		if ( discovery->hints.byte[0] & HINT_LAN)
+		if ( discovery->data.hints[0] & HINT_LAN)
 			len += sprintf( buf+len, "LAN Access ");
 		
-		if ( discovery->hints.byte[1] & HINT_TELEPHONY)
+		if ( discovery->data.hints[1] & HINT_TELEPHONY)
 			len += sprintf( buf+len, "Telephony ");
-		if ( discovery->hints.byte[1] & HINT_FILE_SERVER)
+		if ( discovery->data.hints[1] & HINT_FILE_SERVER)
 			len += sprintf( buf+len, "File Server ");       
-		if ( discovery->hints.byte[1] & HINT_COMM)
+		if ( discovery->data.hints[1] & HINT_COMM)
 			len += sprintf( buf+len, "IrCOMM ");
-		if ( discovery->hints.byte[1] & HINT_OBEX)
+		if ( discovery->data.hints[1] & HINT_OBEX)
 			len += sprintf( buf+len, "IrOBEX ");
 #endif		
 		len += sprintf(buf+len, ", saddr: 0x%08x", 
-			       discovery->saddr);
+			       discovery->data.saddr);
 
 		len += sprintf(buf+len, ", daddr: 0x%08x\n", 
-			       discovery->daddr);
+			       discovery->data.daddr);
 		
 		len += sprintf(buf+len, "\n");
 		
diff -u -p -r linux/net/irda-d4/ircomm/ircomm_tty_attach.c linux/net/irda/ircomm/ircomm_tty_attach.c
--- linux/net/irda-d4/ircomm/ircomm_tty_attach.c	Mon Nov  4 14:30:50 2002
+++ linux/net/irda/ircomm/ircomm_tty_attach.c	Wed Jan  8 17:00:47 2003
@@ -46,7 +46,7 @@
 #include <net/irda/ircomm_tty_attach.h>
 
 static void ircomm_tty_ias_register(struct ircomm_tty_cb *self);
-static void ircomm_tty_discovery_indication(discovery_t *discovery,
+static void ircomm_tty_discovery_indication(discinfo_t *discovery,
 					    DISCOVERY_MODE mode,
 					    void *priv);
 static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id, 
@@ -305,7 +305,7 @@ int ircomm_tty_send_initial_parameters(s
  *    device it is, and which services it has.
  *
  */
-static void ircomm_tty_discovery_indication(discovery_t *discovery,
+static void ircomm_tty_discovery_indication(discinfo_t *discovery,
 					    DISCOVERY_MODE mode,
 					    void *priv)
 {
diff -u -p -r linux/net/irda-d4/irlan/irlan_client.c linux/net/irda/irlan/irlan_client.c
--- linux/net/irda-d4/irlan/irlan_client.c	Mon Nov  4 14:30:31 2002
+++ linux/net/irda/irlan/irlan_client.c	Wed Jan  8 17:00:47 2003
@@ -145,7 +145,7 @@ void irlan_client_wakeup(struct irlan_cb
  *    Remote device with IrLAN server support discovered
  *
  */
-void irlan_client_discovery_indication(discovery_t *discovery,
+void irlan_client_discovery_indication(discinfo_t *discovery,
 				       DISCOVERY_MODE mode,
 				       void *priv) 
 {
diff -u -p -r linux/net/irda-d4/irlap_event.c linux/net/irda/irlap_event.c
--- linux/net/irda-d4/irlap_event.c	Mon Nov  4 14:30:33 2002
+++ linux/net/irda/irlap_event.c	Wed Jan  8 17:00:47 2003
@@ -419,7 +419,7 @@ static int irlap_state_ndm(struct irlap_
 								   info->s);
 			if (self->slot == info->s) {
 				discovery_rsp = irlmp_get_discovery_response();
-				discovery_rsp->daddr = info->daddr;
+				discovery_rsp->data.daddr = info->daddr;
 
 				irlap_send_discovery_xid_frame(self, info->S,
 							       self->slot,
@@ -576,7 +576,7 @@ static int irlap_state_query(struct irla
 		ASSERT(info->discovery != NULL, return -1;);
 
 		IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
-			   info->discovery->daddr);
+			   info->discovery->data.daddr);
 
 		if (!self->discovery_log) {
 			WARNING("%s: discovery log is gone! "
@@ -586,7 +586,7 @@ static int irlap_state_query(struct irla
 		}
 		hashbin_insert(self->discovery_log,
 			       (irda_queue_t *) info->discovery,
-			       info->discovery->daddr, NULL);
+			       info->discovery->data.daddr, NULL);
 
 		/* Keep state */
 		/* irlap_next_state(self, LAP_QUERY);  */
@@ -704,7 +704,7 @@ static int irlap_state_reply(struct irla
 			irlap_discovery_indication(self, info->discovery);
 		} else if ((info->s >= self->slot) && (!self->frame_sent)) {
 			discovery_rsp = irlmp_get_discovery_response();
-			discovery_rsp->daddr = info->daddr;
+			discovery_rsp->data.daddr = info->daddr;
 
 			irlap_send_discovery_xid_frame(self, info->S,
 						       self->slot, FALSE,
diff -u -p -r linux/net/irda-d4/irlap_frame.c linux/net/irda/irlap_frame.c
--- linux/net/irda-d4/irlap_frame.c	Tue Jan  7 17:58:39 2003
+++ linux/net/irda/irlap_frame.c	Wed Jan  8 17:00:47 2003
@@ -335,7 +335,7 @@ void irlap_send_discovery_xid_frame(stru
 	if (command)
 		frame->daddr = cpu_to_le32(bcast);
 	else
-		frame->daddr = cpu_to_le32(discovery->daddr);
+		frame->daddr = cpu_to_le32(discovery->data.daddr);
 
 	switch (S) {
 	case 1:
@@ -366,20 +366,20 @@ void irlap_send_discovery_xid_frame(stru
 	if (!command || (frame->slotnr == 0xff)) {
 		int len;
 
-		if (discovery->hints.byte[0] & HINT_EXTENSION) {
+		if (discovery->data.hints[0] & HINT_EXTENSION) {
 			info = skb_put(skb, 2);
-			info[0] = discovery->hints.byte[0];
-			info[1] = discovery->hints.byte[1];
+			info[0] = discovery->data.hints[0];
+			info[1] = discovery->data.hints[1];
 		} else {
 			info = skb_put(skb, 1);
-			info[0] = discovery->hints.byte[0];
+			info[0] = discovery->data.hints[0];
 		}
 		info = skb_put(skb, 1);
-		info[0] = discovery->charset;
+		info[0] = discovery->data.charset;
 
 		len = IRDA_MIN(discovery->name_len, skb_tailroom(skb));
 		info = skb_put(skb, len);
-		memcpy(info, discovery->nickname, len);
+		memcpy(info, discovery->data.info, len);
 	}
 	irlap_queue_xmit(self, skb);
 }
@@ -422,24 +422,25 @@ static void irlap_recv_discovery_xid_rsp
 	}
 	memset(discovery, 0, sizeof(discovery_t));
 
-	discovery->daddr = info->daddr;
-	discovery->saddr = self->saddr;
+	discovery->data.daddr = info->daddr;
+	discovery->data.saddr = self->saddr;
 	discovery->timestamp = jiffies;
 
-	IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__, discovery->daddr);
+	IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
+		   discovery->data.daddr);
 
 	discovery_info = skb_pull(skb, sizeof(struct xid_frame));
 
 	/* Get info returned from peer */
-	discovery->hints.byte[0] = discovery_info[0];
+	discovery->data.hints[0] = discovery_info[0];
 	if (discovery_info[0] & HINT_EXTENSION) {
 		IRDA_DEBUG(4, "EXTENSION\n");
-		discovery->hints.byte[1] = discovery_info[1];
-		discovery->charset = discovery_info[2];
+		discovery->data.hints[1] = discovery_info[1];
+		discovery->data.charset = discovery_info[2];
 		text = (char *) &discovery_info[3];
 	} else {
-		discovery->hints.byte[1] = 0;
-		discovery->charset = discovery_info[1];
+		discovery->data.hints[1] = 0;
+		discovery->data.charset = discovery_info[1];
 		text = (char *) &discovery_info[2];
 	}
 	/*
@@ -447,8 +448,8 @@ static void irlap_recv_discovery_xid_rsp
 	 *  FCS bytes resides.
 	 */
 	skb->data[skb->len] = '\0';
-	strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
-	discovery->name_len = strlen(discovery->nickname);
+	strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
+	discovery->name_len = strlen(discovery->data.info);
 
 	info->discovery = discovery;
 
@@ -523,18 +524,18 @@ static void irlap_recv_discovery_xid_cmd
 			return;
 		}
 
-		discovery->daddr = info->daddr;
-		discovery->saddr = self->saddr;
+		discovery->data.daddr = info->daddr;
+		discovery->data.saddr = self->saddr;
 		discovery->timestamp = jiffies;
 
-		discovery->hints.byte[0] = discovery_info[0];
+		discovery->data.hints[0] = discovery_info[0];
 		if (discovery_info[0] & HINT_EXTENSION) {
-			discovery->hints.byte[1] = discovery_info[1];
-			discovery->charset = discovery_info[2];
+			discovery->data.hints[1] = discovery_info[1];
+			discovery->data.charset = discovery_info[2];
 			text = (char *) &discovery_info[3];
 		} else {
-			discovery->hints.byte[1] = 0;
-			discovery->charset = discovery_info[1];
+			discovery->data.hints[1] = 0;
+			discovery->data.charset = discovery_info[1];
 			text = (char *) &discovery_info[2];
 		}
 		/*
@@ -542,8 +543,8 @@ static void irlap_recv_discovery_xid_cmd
 		 *  FCS bytes resides.
 		 */
 		skb->data[skb->len] = '\0';
-		strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
-		discovery->name_len = strlen(discovery->nickname);
+		strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
+		discovery->name_len = strlen(discovery->data.info);
 
 		info->discovery = discovery;
 	} else
diff -u -p -r linux/net/irda-d4/irlmp.c linux/net/irda/irlmp.c
--- linux/net/irda-d4/irlmp.c	Mon Nov  4 14:30:50 2002
+++ linux/net/irda/irlmp.c	Wed Jan  8 17:00:47 2003
@@ -401,8 +401,8 @@ int irlmp_connect_request(struct lsap_cb
 		}
 
 		if (discovery) {
-			saddr = discovery->saddr;
-			daddr = discovery->daddr;
+			saddr = discovery->data.saddr;
+			daddr = discovery->data.daddr;
 		}
 		spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, flags);
 	}
@@ -793,17 +793,17 @@ void irlmp_do_discovery(int nslots)
 	}
 
 	/* Construct new discovery info to be used by IrLAP, */
-	irlmp->discovery_cmd.hints.word = irlmp->hints.word;
+	u16ho(irlmp->discovery_cmd.data.hints) = irlmp->hints.word;
 
 	/*
 	 *  Set character set for device name (we use ASCII), and
 	 *  copy device name. Remember to make room for a \0 at the
 	 *  end
 	 */
-	irlmp->discovery_cmd.charset = CS_ASCII;
-	strncpy(irlmp->discovery_cmd.nickname, sysctl_devname,
+	irlmp->discovery_cmd.data.charset = CS_ASCII;
+	strncpy(irlmp->discovery_cmd.data.info, sysctl_devname,
 		NICKNAME_MAX_LEN);
-	irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.nickname);
+	irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.data.info);
 	irlmp->discovery_cmd.nslots = nslots;
 
 	/*
@@ -827,10 +827,13 @@ void irlmp_do_discovery(int nslots)
  *
  *    Do a discovery of devices in front of the computer
  *
+ * If the caller has registered a client discovery callback, this
+ * allow him to receive the full content of the discovery log through
+ * this callback (as normally he will receive only new discoveries).
  */
 void irlmp_discovery_request(int nslots)
 {
-	/* Return current cached discovery log */
+	/* Return current cached discovery log (in full) */
 	irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_LOG);
 
 	/*
@@ -854,6 +857,8 @@ void irlmp_discovery_request(int nslots)
  *
  *    Return the current discovery log
  *
+ * If discovery is not enabled, you should call this function again
+ * after 1 or 2 seconds (i.e. after discovery has been done).
  */
 struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
 {
@@ -875,50 +880,9 @@ struct irda_device_info *irlmp_get_disco
 	}
 
 	/* Return current cached discovery log */
-	return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask));
+	return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE));
 }
 
-#if 0
-/*
- * Function irlmp_check_services (discovery)
- */
-void irlmp_check_services(discovery_t *discovery)
-{
-	struct irlmp_client *client;
-	__u8 *service_log;
-	__u8 service;
-	int i = 0;
-
-	IRDA_DEBUG(1, "IrDA Discovered: %s\n", discovery->info);
-	IRDA_DEBUG(1, "    Services: ");
-
-	service_log = irlmp_hint_to_service(discovery->hints.byte);
-	if (!service_log)
-		return;
-
-	/*
-	 *  Check all services on the device
-	 */
-	while ((service = service_log[i++]) != S_END) {
-		IRDA_DEBUG( 4, "service=%02x\n", service);
-		client = hashbin_lock_find(irlmp->registry, service, NULL);
-		if (entry && entry->discovery_callback) {
-			IRDA_DEBUG( 4, "discovery_callback!\n");
-
-			entry->discovery_callback(discovery);
-		} else {
-			/* Don't notify about the ANY service */
-			if (service == S_ANY)
-				continue;
-			/*
-			 * Found no clients for dealing with this service,
-			 */
-		}
-	}
-	kfree(service_log);
-}
-#endif
-
 /*
  * Function irlmp_notify_client (log)
  *
@@ -935,7 +899,9 @@ static inline void
 irlmp_notify_client(irlmp_client_t *client,
 		    hashbin_t *log, DISCOVERY_MODE mode)
 {
-	discovery_t *discovery;
+	discinfo_t *discoveries;	/* Copy of the discovery log */
+	int	number;			/* Number of nodes in the log */
+	int	i;
 
 	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
@@ -944,28 +910,36 @@ irlmp_notify_client(irlmp_client_t *clie
 		return;
 
 	/*
+	 * Locking notes :
+	 * the old code was manipulating the log directly, which was
+	 * very racy. Now, we use copy_discoveries, that protects
+	 * itself while dumping the log for us.
+	 * The overhead of the copy is compensated by the fact that
+	 * we only pass new discoveries in normal mode and don't
+	 * pass the same old entry every 3s to the caller as we used
+	 * to do (virtual function calling is expensive).
+	 * Jean II
+	 */
+
+	/*
 	 * Now, check all discovered devices (if any), and notify client
 	 * only about the services that the client is interested in
-	 * Note : most often, we will get called immediately following
-	 * a discovery, so the log is not going to expire.
-	 * On the other hand, comming here through irlmp_discovery_request()
-	 * is *very* problematic - Jean II
-	 * Can't use hashbin_find_next(), key is not unique. I'm running
-	 * out of options :-( - Jean II
+	 * We also notify only about the new devices unless the caller
+	 * explicity request a dump of the log. Jean II
 	 */
-	discovery = (discovery_t *) hashbin_get_first(log);
-	while (discovery != NULL) {
-		IRDA_DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr);
-
-		/*
-		 * Any common hint bits? Remember to mask away the extension
-		 * bits ;-)
-		 */
-		if (client->hint_mask & discovery->hints.word & 0x7f7f)
-			client->disco_callback(discovery, mode, client->priv);
+	discoveries = irlmp_copy_discoveries(log, &number,
+					     client->hint_mask.word,
+					     (mode == DISCOVERY_LOG));
+	/* Check if the we got some results */
+	if (discoveries == NULL)
+		return;	/* No nodes discovered */
+
+	/* Pass all entries to the listener */
+	for(i = 0; i < number; i++)
+		client->disco_callback(&(discoveries[i]), mode, client->priv);
 
-		discovery = (discovery_t *) hashbin_get_next(log);
-	}
+	/* Free up our buffer */
+	kfree(discoveries);
 }
 
 /*
@@ -987,6 +961,7 @@ void irlmp_discovery_confirm(hashbin_t *
 	if (!(HASHBIN_GET_SIZE(log)))
 		return;
 
+	/* For each client - notify callback may touch client list */
 	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
 	while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
 					 (void *) &client_next) ) {
@@ -1005,26 +980,34 @@ void irlmp_discovery_confirm(hashbin_t *
  *	registered for this event...
  *
  *	Note : called exclusively from discovery.c
- *	Note : as we are currently processing the log, the clients callback
- *	should *NOT* attempt to touch the log now.
+ *	Note : this is no longer called under discovery spinlock, so the
+ *		client can do whatever he wants in the callback.
  */
-void irlmp_discovery_expiry(discovery_t *expiry)
+void irlmp_discovery_expiry(discinfo_t *expiries, int number)
 {
 	irlmp_client_t *client;
 	irlmp_client_t *client_next;
+	int		i;
 
 	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
-	ASSERT(expiry != NULL, return;);
+	ASSERT(expiries != NULL, return;);
 
+	/* For each client - notify callback may touch client list */
 	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
 	while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
 					 (void *) &client_next) ) {
-		/* Check if we should notify client */
-		if ((client->expir_callback) &&
-		    (client->hint_mask & expiry->hints.word & 0x7f7f))
-			client->expir_callback(expiry, EXPIRY_TIMEOUT,
-					       client->priv);
+
+		/* Pass all entries to the listener */
+		for(i = 0; i < number; i++) {
+			/* Check if we should notify client */
+			if ((client->expir_callback) &&
+			    (client->hint_mask.word & u16ho(expiries[i].hints)
+			     & 0x7f7f) )
+				client->expir_callback(&(expiries[i]),
+						       EXPIRY_TIMEOUT,
+						       client->priv);
+		}
 
 		/* Next client */
 		client = client_next;
@@ -1043,18 +1026,18 @@ discovery_t *irlmp_get_discovery_respons
 
 	ASSERT(irlmp != NULL, return NULL;);
 
-	irlmp->discovery_rsp.hints.word = irlmp->hints.word;
+	u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
 
 	/*
 	 *  Set character set for device name (we use ASCII), and
 	 *  copy device name. Remember to make room for a \0 at the
 	 *  end
 	 */
-	irlmp->discovery_rsp.charset = CS_ASCII;
+	irlmp->discovery_rsp.data.charset = CS_ASCII;
 
-	strncpy(irlmp->discovery_rsp.nickname, sysctl_devname,
+	strncpy(irlmp->discovery_rsp.data.info, sysctl_devname,
 		NICKNAME_MAX_LEN);
-	irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.nickname);
+	irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.data.info);
 
 	return &irlmp->discovery_rsp;
 }
@@ -1291,6 +1274,7 @@ void irlmp_flow_indication(struct lap_cb
 	}
 }
 
+#if 0
 /*
  * Function irlmp_hint_to_service (hint)
  *
@@ -1365,6 +1349,21 @@ __u8 *irlmp_hint_to_service(__u8 *hint)
 
 	return service;
 }
+#endif
+
+const __u16 service_hint_mapping[S_END][2] = {
+	{ HINT_PNP,		0 },			/* S_PNP */
+	{ HINT_PDA,		0 },			/* S_PDA */
+	{ HINT_COMPUTER,	0 },			/* S_COMPUTER */
+	{ HINT_PRINTER,		0 },			/* S_PRINTER */
+	{ HINT_MODEM,		0 },			/* S_MODEM */
+	{ HINT_FAX,		0 },			/* S_FAX */
+	{ HINT_LAN,		0 },			/* S_LAN */
+	{ HINT_EXTENSION,	HINT_TELEPHONY },	/* S_TELEPHONY */
+	{ HINT_EXTENSION,	HINT_COMM },		/* S_COMM */
+	{ HINT_EXTENSION,	HINT_OBEX },		/* S_OBEX */
+	{ 0xFF,			0xFF },			/* S_ANY */
+};
 
 /*
  * Function irlmp_service_to_hint (service)
@@ -1377,46 +1376,9 @@ __u16 irlmp_service_to_hint(int service)
 {
 	__u16_host_order hint;
 
-	hint.word = 0;
+	hint.byte[0] = service_hint_mapping[service][0];
+	hint.byte[1] = service_hint_mapping[service][1];
 
-	switch (service) {
-	case S_PNP:
-		hint.byte[0] |= HINT_PNP;
-		break;
-	case S_PDA:
-		hint.byte[0] |= HINT_PDA;
-		break;
-	case S_COMPUTER:
-		hint.byte[0] |= HINT_COMPUTER;
-		break;
-	case S_PRINTER:
-		hint.byte[0] |= HINT_PRINTER;
-		break;
-	case S_MODEM:
-		hint.byte[0] |= HINT_PRINTER;
-		break;
-	case S_LAN:
-		hint.byte[0] |= HINT_LAN;
-		break;
-	case S_COMM:
-		hint.byte[0] |= HINT_EXTENSION;
-		hint.byte[1] |= HINT_COMM;
-		break;
-	case S_OBEX:
-		hint.byte[0] |= HINT_EXTENSION;
-		hint.byte[1] |= HINT_OBEX;
-		break;
-	case S_TELEPHONY:
-		hint.byte[0] |= HINT_EXTENSION;
-		hint.byte[1] |= HINT_TELEPHONY;
-		break;
-	case S_ANY:
-		hint.word = 0xffff;
-		break;
-	default:
-		IRDA_DEBUG( 1, "%s(), Unknown service!\n", __FUNCTION__);
-		break;
-	}
 	return hint.word;
 }
 
@@ -1438,7 +1400,7 @@ void *irlmp_register_service(__u16 hints
 		IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
 		return 0;
 	}
-	service->hints = hints;
+	service->hints.word = hints;
 	hashbin_insert(irlmp->services, (irda_queue_t *) service,
 		       (long) service, NULL);
 
@@ -1481,7 +1443,7 @@ int irlmp_unregister_service(void *handl
 	spin_lock_irqsave(&irlmp->services->hb_spinlock, flags);
         service = (irlmp_service_t *) hashbin_get_first(irlmp->services);
         while (service) {
-		irlmp->hints.word |= service->hints;
+		irlmp->hints.word |= service->hints.word;
 
                 service = (irlmp_service_t *)hashbin_get_next(irlmp->services);
         }
@@ -1499,7 +1461,7 @@ int irlmp_unregister_service(void *handl
  *    Returns: handle > 0 on success, 0 on error
  */
 void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
-			    DISCOVERY_CALLBACK1 expir_clb, void *priv)
+			    DISCOVERY_CALLBACK2 expir_clb, void *priv)
 {
 	irlmp_client_t *client;
 
@@ -1514,7 +1476,7 @@ void *irlmp_register_client(__u16 hint_m
 	}
 
 	/* Register the details */
-	client->hint_mask = hint_mask;
+	client->hint_mask.word = hint_mask;
 	client->disco_callback = disco_clb;
 	client->expir_callback = expir_clb;
 	client->priv = priv;
@@ -1535,7 +1497,7 @@ void *irlmp_register_client(__u16 hint_m
  */
 int irlmp_update_client(void *handle, __u16 hint_mask,
 			DISCOVERY_CALLBACK1 disco_clb,
-			DISCOVERY_CALLBACK1 expir_clb, void *priv)
+			DISCOVERY_CALLBACK2 expir_clb, void *priv)
 {
 	irlmp_client_t *client;
 
@@ -1548,7 +1510,7 @@ int irlmp_update_client(void *handle, __
 		return -1;
 	}
 
-	client->hint_mask = hint_mask;
+	client->hint_mask.word = hint_mask;
 	client->disco_callback = disco_clb;
 	client->expir_callback = expir_clb;
 	client->priv = priv;
diff -u -p -r linux/net/irda-d4/irnet/irnet_irda.c linux/net/irda/irnet/irnet_irda.c
--- linux/net/irda-d4/irnet/irnet_irda.c	Mon Nov  4 14:30:05 2002
+++ linux/net/irda/irnet/irnet_irda.c	Wed Jan  8 17:00:47 2003
@@ -1616,8 +1616,8 @@ irnet_discovervalue_confirm(int		result,
  *
  *    Got a discovery indication from IrLMP, post an event
  *
- * Note : IrLMP take care of matching the hint mask for us, we only
- * check if it is a "new" node...
+ * Note : IrLMP take care of matching the hint mask for us, and also
+ * check if it is a "new" node for us...
  *
  * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
  * nodes, so it's only at connection time that we will know if the
@@ -1633,7 +1633,7 @@ irnet_discovervalue_confirm(int		result,
  * is to messy, so we leave that to user space...
  */
 static void
-irnet_discovery_indication(discovery_t *	discovery,
+irnet_discovery_indication(discinfo_t *		discovery,
 			   DISCOVERY_MODE	mode,
 			   void *		priv)
 {
@@ -1643,21 +1643,12 @@ irnet_discovery_indication(discovery_t *
   DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
 	  "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
 
-  /* Check if node is discovered is a new one or an old one.
-   * We check when how long ago this node was discovered, with a
-   * coarse timeout (we may miss some discovery events or be delayed).
-   */
-  if((jiffies - discovery->first_timestamp) >= (sysctl_discovery_timeout * HZ))
-    {
-      return;		/* Too old, not interesting -> goodbye */
-    }
-
   DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
-	discovery->nickname);
+	discovery->info);
 
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_DISCOVER,
-		   discovery->saddr, discovery->daddr, discovery->nickname);
+		   discovery->saddr, discovery->daddr, discovery->info);
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1672,7 +1663,7 @@ irnet_discovery_indication(discovery_t *
  * check if it is a "new" node...
  */
 static void
-irnet_expiry_indication(discovery_t *	expiry,
+irnet_expiry_indication(discinfo_t *	expiry,
 			DISCOVERY_MODE	mode,
 			void *		priv)
 {
@@ -1683,11 +1674,11 @@ irnet_expiry_indication(discovery_t *	ex
 	  "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
 
   DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
-	expiry->nickname);
+	expiry->info);
 
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_EXPIRE,
-		   expiry->saddr, expiry->daddr, expiry->nickname);
+		   expiry->saddr, expiry->daddr, expiry->info);
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
diff -u -p -r linux/net/irda-d4/irnet/irnet_irda.h linux/net/irda/irnet/irnet_irda.h
--- linux/net/irda-d4/irnet/irnet_irda.h	Mon Nov  4 14:30:07 2002
+++ linux/net/irda/irnet/irnet_irda.h	Wed Jan  8 17:00:47 2003
@@ -150,11 +150,11 @@ static void
 				    void *);
 #ifdef DISCOVERY_EVENTS
 static void
-	irnet_discovery_indication(discovery_t *,
+	irnet_discovery_indication(discinfo_t *,
 				   DISCOVERY_MODE,
 				   void *);
 static void
-	irnet_expiry_indication(discovery_t *,
+	irnet_expiry_indication(discinfo_t *,
 				DISCOVERY_MODE,
 				void *);
 #endif
