File: /usr/src/linux/net/irda/irlmp.c

1     /*********************************************************************
2      *                
3      * Filename:      irlmp.c
4      * Version:       1.0
5      * Description:   IrDA Link Management Protocol (LMP) layer                 
6      * Status:        Stable.
7      * Author:        Dag Brattli <dagb@cs.uit.no>
8      * Created at:    Sun Aug 17 20:54:32 1997
9      * Modified at:   Wed Jan  5 11:26:03 2000
10      * Modified by:   Dag Brattli <dagb@cs.uit.no>
11      * 
12      *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
13      *     All Rights Reserved.
14      *     
15      *     This program is free software; you can redistribute it and/or 
16      *     modify it under the terms of the GNU General Public License as 
17      *     published by the Free Software Foundation; either version 2 of 
18      *     the License, or (at your option) any later version.
19      *
20      *     Neither Dag Brattli nor University of Tromsų admit liability nor
21      *     provide warranty for any of this software. This material is 
22      *     provided "AS-IS" and at no charge.
23      *
24      ********************************************************************/
25     
26     #include <linux/config.h>
27     #include <linux/slab.h>
28     #include <linux/string.h>
29     #include <linux/skbuff.h>
30     #include <linux/types.h>
31     #include <linux/proc_fs.h>
32     #include <linux/init.h>
33     #include <linux/kmod.h>
34     #include <linux/random.h>
35     
36     #include <net/irda/irda.h>
37     #include <net/irda/irmod.h>
38     #include <net/irda/timer.h>
39     #include <net/irda/qos.h>
40     #include <net/irda/irlap.h>
41     #include <net/irda/iriap.h>
42     #include <net/irda/irlmp.h>
43     #include <net/irda/irlmp_frame.h>
44     
45     /* Master structure */
46     struct irlmp_cb *irlmp = NULL;
47     
48     /* These can be altered by the sysctl interface */
49     int  sysctl_discovery         = 0;
50     int  sysctl_discovery_timeout = 3; /* 3 seconds by default */
51     int  sysctl_discovery_slots   = 6; /* 6 slots by default */
52     int  sysctl_lap_keepalive_time = LM_IDLE_TIMEOUT * 1000 / HZ;
53     char sysctl_devname[65];
54     
55     char *lmp_reasons[] = {
56     	"ERROR, NOT USED",
57     	"LM_USER_REQUEST",
58     	"LM_LAP_DISCONNECT",
59     	"LM_CONNECT_FAILURE",
60     	"LM_LAP_RESET",
61     	"LM_INIT_DISCONNECT",
62     	"ERROR, NOT USED",
63     };
64     
65     __u8 *irlmp_hint_to_service(__u8 *hint);
66     #ifdef CONFIG_PROC_FS
67     int irlmp_proc_read(char *buf, char **start, off_t offst, int len);
68     #endif
69     
70     /*
71      * Function irlmp_init (void)
72      *
73      *    Create (allocate) the main IrLMP structure
74      *
75      */
76     int __init irlmp_init(void)
77     {
78     	IRDA_DEBUG(0, __FUNCTION__ "()\n");
79     	/* Initialize the irlmp structure. */
80     	irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
81     	if (irlmp == NULL)
82     		return -ENOMEM;
83     	memset(irlmp, 0, sizeof(struct irlmp_cb));
84     	
85     	irlmp->magic = LMP_MAGIC;
86     	spin_lock_init(&irlmp->log_lock);
87     
88     	irlmp->clients = hashbin_new(HB_GLOBAL);
89     	irlmp->services = hashbin_new(HB_GLOBAL);
90     	irlmp->links = hashbin_new(HB_GLOBAL);
91     	irlmp->unconnected_lsaps = hashbin_new(HB_GLOBAL);
92     	irlmp->cachelog = hashbin_new(HB_GLOBAL);
93     	
94     	irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
95     #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
96     	irlmp->cache.valid = FALSE;
97     #endif
98     	strcpy(sysctl_devname, "Linux");
99     	
100     	/* Do discovery every 3 seconds */
101     	init_timer(&irlmp->discovery_timer);
102        	irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
103     
104     	return 0;
105     }
106     
107     /*
108      * Function irlmp_cleanup (void)
109      *
110      *    Remove IrLMP layer
111      *
112      */
113     void irlmp_cleanup(void) 
114     {
115     	/* Check for main structure */
116     	ASSERT(irlmp != NULL, return;);
117     	ASSERT(irlmp->magic == LMP_MAGIC, return;);
118     
119     	del_timer(&irlmp->discovery_timer);
120     	
121     	hashbin_delete(irlmp->links, (FREE_FUNC) kfree);
122     	hashbin_delete(irlmp->unconnected_lsaps, (FREE_FUNC) kfree);
123     	hashbin_delete(irlmp->clients, (FREE_FUNC) kfree);
124     	hashbin_delete(irlmp->services, (FREE_FUNC) kfree);
125     	hashbin_delete(irlmp->cachelog, (FREE_FUNC) kfree);
126     	
127     	/* De-allocate main structure */
128     	kfree(irlmp);
129     	irlmp = NULL;
130     }
131     
132     /*
133      * Function irlmp_open_lsap (slsap, notify)
134      *
135      *   Register with IrLMP and create a local LSAP,
136      *   returns handle to LSAP.
137      */
138     struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
139     {
140     	struct lsap_cb *self;
141     
142     	ASSERT(notify != NULL, return NULL;);
143     	ASSERT(irlmp != NULL, return NULL;);
144     	ASSERT(irlmp->magic == LMP_MAGIC, return NULL;);
145     
146     	/*  Does the client care which Source LSAP selector it gets?  */
147     	if (slsap_sel == LSAP_ANY) {
148     		slsap_sel = irlmp_find_free_slsap();
149     		if (!slsap_sel)
150     			return NULL;
151     	} else if (irlmp_slsap_inuse(slsap_sel))
152     		return NULL;
153     
154     	/* Allocate new instance of a LSAP connection */
155     	self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
156     	if (self == NULL) {
157     		ERROR(__FUNCTION__ "(), can't allocate memory");
158     		return NULL;
159     	}
160     	memset(self, 0, sizeof(struct lsap_cb));
161     	
162     	self->magic = LMP_LSAP_MAGIC;
163     	self->slsap_sel = slsap_sel;
164     
165     	/* Fix connectionless LSAP's */
166     	if (slsap_sel == LSAP_CONNLESS) {
167     #ifdef CONFIG_IRDA_ULTRA
168     		self->dlsap_sel = LSAP_CONNLESS;
169     		self->pid = pid;
170     #endif /* CONFIG_IRDA_ULTRA */
171     	} else
172     		self->dlsap_sel = LSAP_ANY;
173     	self->connected = FALSE;
174     
175     	init_timer(&self->watchdog_timer);
176     
177     	ASSERT(notify->instance != NULL, return NULL;);
178     	self->notify = *notify;
179     
180     	irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
181     	
182     	/* Insert into queue of unconnected LSAPs */
183     	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, 
184     		       NULL);
185     	
186     	return self;
187     }
188     
189     /*
190      * Function __irlmp_close_lsap (self)
191      *
192      *    Remove an instance of LSAP
193      */
194     static void __irlmp_close_lsap(struct lsap_cb *self)
195     {
196     	IRDA_DEBUG(4, __FUNCTION__ "()\n");
197     
198     	ASSERT(self != NULL, return;);
199     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
200     
201     	/*
202     	 *  Set some of the variables to preset values
203     	 */
204     	self->magic = 0;
205     	del_timer(&self->watchdog_timer); /* Important! */
206     
207     	if (self->conn_skb)
208     		dev_kfree_skb(self->conn_skb);
209     
210     #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
211     	ASSERT(irlmp != NULL, return;);
212     	irlmp->cache.valid = FALSE;
213     #endif
214     	kfree(self);
215     }
216     
217     /*
218      * Function irlmp_close_lsap (self)
219      *
220      *    Close and remove LSAP
221      *
222      */
223     void irlmp_close_lsap(struct lsap_cb *self)
224     {
225     	struct lap_cb *lap;
226     	struct lsap_cb *lsap = NULL;
227     
228     	ASSERT(self != NULL, return;);
229     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
230     
231     	/*
232     	 *  Find out if we should remove this LSAP from a link or from the
233     	 *  list of unconnected lsaps (not associated with a link)
234     	 */
235     	lap = self->lap;
236     	if (lap) {
237     		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
238     		lsap = hashbin_remove(lap->lsaps, (int) self, NULL);
239     	}
240     	/* Check if we found the LSAP! If not then try the unconnected lsaps */
241     	if (!lsap) {
242     		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, 
243     				      NULL);
244     	}
245     	if (!lsap) {
246     		IRDA_DEBUG(0, __FUNCTION__ 
247     		     "(), Looks like somebody has removed me already!\n");
248     		return;
249     	}
250     	__irlmp_close_lsap(self);
251     }
252     
253     /*
254      * Function irlmp_register_irlap (saddr, notify)
255      *
256      *    Register IrLAP layer with IrLMP. There is possible to have multiple
257      *    instances of the IrLAP layer, each connected to different IrDA ports
258      *
259      */
260     void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
261     {
262     	struct lap_cb *lap;
263     
264     	ASSERT(irlmp != NULL, return;);
265     	ASSERT(irlmp->magic == LMP_MAGIC, return;);
266     	ASSERT(notify != NULL, return;);
267     
268     	/*
269     	 *  Allocate new instance of a LSAP connection
270     	 */
271     	lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL);
272     	if (lap == NULL) {
273     		ERROR(__FUNCTION__ "(), unable to kmalloc\n");
274     		return;
275     	}
276     	memset(lap, 0, sizeof(struct lap_cb));
277     	
278     	lap->irlap = irlap;
279     	lap->magic = LMP_LAP_MAGIC;
280     	lap->saddr = saddr;
281     	lap->daddr = DEV_ADDR_ANY;
282     	lap->lsaps = hashbin_new(HB_GLOBAL);
283     
284     	irlmp_next_lap_state(lap, LAP_STANDBY);
285     	
286     	init_timer(&lap->idle_timer);
287     
288     	/*
289     	 *  Insert into queue of LMP links
290     	 */
291     	hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL);
292     
293     	/* 
294     	 *  We set only this variable so IrLAP can tell us on which link the
295     	 *  different events happened on 
296     	 */
297     	irda_notify_init(notify);
298     	notify->instance = lap;
299     }
300     
301     /*
302      * Function irlmp_unregister_irlap (saddr)
303      *
304      *    IrLAP layer has been removed!
305      *
306      */
307     void irlmp_unregister_link(__u32 saddr)
308     {
309     	struct lap_cb *link;
310     
311     	IRDA_DEBUG(4, __FUNCTION__ "()\n");
312     
313     	link = hashbin_remove(irlmp->links, saddr, NULL);
314     	if (link) {
315     		ASSERT(link->magic == LMP_LAP_MAGIC, return;);
316     
317     		/* Remove all discoveries discovered at this link */
318     		irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE);
319     
320     		del_timer(&link->idle_timer);	
321     
322     		link->magic = 0;
323     		kfree(link);
324     	}
325     }
326     
327     /*
328      * Function irlmp_connect_request (handle, dlsap, userdata)
329      *
330      *    Connect with a peer LSAP  
331      *
332      */
333     int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, 
334     			  __u32 saddr, __u32 daddr, 
335     			  struct qos_info *qos, struct sk_buff *userdata) 
336     {
337     	struct sk_buff *skb = NULL;
338     	struct lap_cb *lap;
339     	struct lsap_cb *lsap;
340     	discovery_t *discovery;
341     
342     	ASSERT(self != NULL, return -EBADR;);
343     	ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;);
344     	
345     	IRDA_DEBUG(2, __FUNCTION__ 
346     	      "(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n", 
347     	      self->slsap_sel, dlsap_sel, saddr, daddr);
348     	
349     	if (self->connected) 
350     		return -EISCONN;
351     	
352     	/* Client must supply destination device address */
353     	if (!daddr)
354     		return -EINVAL;
355     	
356     	/* Any userdata? */
357     	if (userdata == NULL) {
358     		skb = dev_alloc_skb(64);
359     		if (!skb)
360     			return -ENOMEM;
361     
362     		skb_reserve(skb, LMP_MAX_HEADER);
363     	} else
364     		skb = userdata;
365     	
366     	/* Make room for MUX control header (3 bytes) */
367     	ASSERT(skb_headroom(skb) >= LMP_CONTROL_HEADER, return -1;);
368     	skb_push(skb, LMP_CONTROL_HEADER);
369     
370     	self->dlsap_sel = dlsap_sel;
371     	
372     	/*  
373     	 * Find the link to where we should try to connect since there may
374     	 * be more than one IrDA port on this machine. If the client has
375     	 * passed us the saddr (and already knows which link to use), then
376     	 * we use that to find the link, if not then we have to look in the
377     	 * discovery log and check if any of the links has discovered a
378     	 * device with the given daddr 
379     	 */
380     	if ((!saddr) || (saddr == DEV_ADDR_ANY)) {
381     		if (daddr != DEV_ADDR_ANY)
382     			discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
383     		else {
384     			IRDA_DEBUG(2, __FUNCTION__ "(), no daddr\n");
385     			discovery = (discovery_t *) 
386     				hashbin_get_first(irlmp->cachelog);
387     		}
388     
389     		if (discovery) {
390     			saddr = discovery->saddr;
391     			daddr = discovery->daddr;
392     		}
393     	}
394     	lap = hashbin_find(irlmp->links, saddr, NULL);	
395     	if (lap == NULL) {
396     		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to find a usable link!\n");
397     		return -EHOSTUNREACH;
398     	}
399     
400     	/* Check if LAP is disconnected or already connected */
401     	if (lap->daddr == DEV_ADDR_ANY)
402     		lap->daddr = daddr;
403     	else if (lap->daddr != daddr) {
404     		struct lsap_cb *any_lsap;
405     
406     		/* Check if some LSAPs are active on this LAP */
407     		any_lsap = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
408     		if (any_lsap == NULL) {
409     			/* No active connection, but LAP hasn't been
410     			 * disconnected yet (waiting for timeout in LAP).
411     			 * Maybe we could give LAP a bit of help in this case.
412     			 */
413     			IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but I'm waiting for LAP to timeout!\n");
414     			return -EAGAIN;
415     		}
416     
417     		/* LAP is already connected to a different node, and LAP
418     		 * can only talk to one node at a time */
419     		IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but link is busy!\n");
420     		return -EBUSY;
421     	}
422     
423     	self->lap = lap;
424     
425     	/* 
426     	 *  Remove LSAP from list of unconnected LSAPs and insert it into the 
427     	 *  list of connected LSAPs for the particular link 
428     	 */
429     	lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, NULL);
430     
431     	ASSERT(lsap != NULL, return -1;);
432     	ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
433     	ASSERT(lsap->lap != NULL, return -1;);
434     	ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;);
435     
436     	hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL);
437     
438     	self->connected = TRUE;
439     	
440     	/*
441     	 *  User supplied qos specifications?
442     	 */
443     	if (qos)
444     		self->qos = *qos;
445     	
446     	irlmp_do_lsap_event(self, LM_CONNECT_REQUEST, skb);
447     
448     	return 0;
449     }
450     
451     /*
452      * Function irlmp_connect_indication (self)
453      *
454      *    Incoming connection
455      *
456      */
457     void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb) 
458     {
459     	int max_seg_size;
460     	int lap_header_size;
461     	int max_header_size;
462     	
463     	ASSERT(self != NULL, return;);
464     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
465     	ASSERT(skb != NULL, return;);
466     	ASSERT(self->lap != NULL, return;);
467     
468     	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
469     		   self->slsap_sel, self->dlsap_sel);
470     	
471     	self->qos = *self->lap->qos;
472     
473     	max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
474     	lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
475     	max_header_size = LMP_HEADER + lap_header_size;
476     
477     	/* Hide LMP_CONTROL_HEADER header from layer above */
478     	skb_pull(skb, LMP_CONTROL_HEADER);
479     	
480     	if (self->notify.connect_indication)
481     		self->notify.connect_indication(self->notify.instance, self, 
482     						&self->qos, max_seg_size, 
483     						max_header_size, skb);
484     }
485     
486     /*
487      * Function irlmp_connect_response (handle, userdata)
488      *
489      *    Service user is accepting connection
490      *
491      */
492     int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata) 
493     {
494     	ASSERT(self != NULL, return -1;);
495     	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
496     	ASSERT(userdata != NULL, return -1;);
497     
498     	self->connected = TRUE;
499     
500     	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
501     		   self->slsap_sel, self->dlsap_sel);
502     
503     	/* Make room for MUX control header (3 bytes) */
504     	ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;);
505     	skb_push(userdata, LMP_CONTROL_HEADER);
506     	
507     	irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
508     
509     	return 0;
510     }
511     
512     /*
513      * Function irlmp_connect_confirm (handle, skb)
514      *
515      *    LSAP connection confirmed peer device!
516      */
517     void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) 
518     {
519     	int max_header_size;
520     	int lap_header_size;
521     	int max_seg_size;
522     
523     	IRDA_DEBUG(3, __FUNCTION__ "()\n");
524     	
525     	ASSERT(skb != NULL, return;);
526     	ASSERT(self != NULL, return;);
527     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);	
528     	ASSERT(self->lap != NULL, return;);
529     
530     	self->qos = *self->lap->qos;
531     
532     	max_seg_size    = self->lap->qos->data_size.value-LMP_HEADER;
533     	lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);	
534     	max_header_size = LMP_HEADER + lap_header_size;
535     
536     	IRDA_DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", 
537     		   max_header_size);
538     
539     	/* Hide LMP_CONTROL_HEADER header from layer above */
540     	skb_pull(skb, LMP_CONTROL_HEADER);
541     
542     	if (self->notify.connect_confirm) {
543     		self->notify.connect_confirm(self->notify.instance, self,
544     					     &self->qos, max_seg_size,
545     					     max_header_size, skb);
546     	}
547     }
548     
549     /*
550      * Function irlmp_dup (orig, instance)
551      *
552      *    Duplicate LSAP, can be used by servers to confirm a connection on a
553      *    new LSAP so it can keep listening on the old one.
554      *
555      */
556     struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) 
557     {
558     	struct lsap_cb *new;
559     
560     	IRDA_DEBUG(1, __FUNCTION__ "()\n");
561     
562     	/* Only allowed to duplicate unconnected LSAP's */
563     	if (!hashbin_find(irlmp->unconnected_lsaps, (int) orig, NULL)) {
564     		IRDA_DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n");
565     		return NULL;
566     	}
567     	new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
568     	if (!new)  {
569     		IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n");
570     		return NULL;
571     	}
572     	/* Dup */
573     	memcpy(new, orig, sizeof(struct lsap_cb));
574     	new->notify.instance = instance;
575     	
576     	init_timer(&new->watchdog_timer);
577     	
578     	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new, 
579     		       NULL);
580     
581     	/* Make sure that we invalidate the cache */
582     #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
583     	irlmp->cache.valid = FALSE;
584     #endif /* CONFIG_IRDA_CACHE_LAST_LSAP */
585     
586     	return new;
587     }
588     
589     /*
590      * Function irlmp_disconnect_request (handle, userdata)
591      *
592      *    The service user is requesting disconnection, this will not remove the 
593      *    LSAP, but only mark it as disconnected
594      */
595     int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) 
596     {
597     	struct lsap_cb *lsap;
598     
599     	ASSERT(self != NULL, return -1;);
600     	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
601     
602     	/* Already disconnected? */
603     	if (!self->connected) {
604     		WARNING(__FUNCTION__ "(), already disconnected!\n");
605     		return -1;
606     	}
607     
608     	ASSERT(userdata != NULL, return -1;);
609     	ASSERT(self->connected == TRUE, return -1;);
610     	
611     	skb_push(userdata, LMP_CONTROL_HEADER);
612     
613     	/* 
614     	 *  Do the event before the other stuff since we must know
615     	 *  which lap layer that the frame should be transmitted on
616     	 */
617     	irlmp_do_lsap_event(self, LM_DISCONNECT_REQUEST, userdata);
618     
619     	/* 
620     	 *  Remove LSAP from list of connected LSAPs for the particular link
621     	 *  and insert it into the list of unconnected LSAPs
622     	 */
623     	ASSERT(self->lap != NULL, return -1;);
624     	ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
625     	ASSERT(self->lap->lsaps != NULL, return -1;);
626     
627     	lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL);
628     
629     	ASSERT(lsap != NULL, return -1;);
630     	ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
631     	ASSERT(lsap == self, return -1;);
632     
633     	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, 
634     		       NULL);
635     	
636     	/* Reset some values */
637     	self->connected = FALSE;
638     	self->dlsap_sel = LSAP_ANY;
639     	self->lap = NULL;
640     	
641     	return 0;
642     }
643     
644     /*
645      * Function irlmp_disconnect_indication (reason, userdata)
646      *
647      *    LSAP is being closed!
648      */
649     void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, 
650     				 struct sk_buff *userdata) 
651     {
652     	struct lsap_cb *lsap;
653     
654     	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]);	
655     	ASSERT(self != NULL, return;);
656     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
657      	ASSERT(self->connected == TRUE, return;); 
658     
659     	IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
660     		   self->slsap_sel, self->dlsap_sel);
661     
662     	self->connected = FALSE;
663     	self->dlsap_sel = LSAP_ANY;
664     
665     #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
666     	irlmp->cache.valid = FALSE;
667     #endif
668     
669     	/* 
670     	 *  Remove association between this LSAP and the link it used 
671     	 */
672     	ASSERT(self->lap != NULL, return;);
673     	ASSERT(self->lap->lsaps != NULL, return;);
674     
675     	lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL);
676     
677     	ASSERT(lsap != NULL, return;);
678     	ASSERT(lsap == self, return;);
679     	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap, 
680     		       NULL);
681     
682     	self->lap = NULL;
683     	
684     	/*
685     	 *  Inform service user
686     	 */
687     	if (self->notify.disconnect_indication)
688     		self->notify.disconnect_indication(self->notify.instance, 
689     						   self, reason, userdata);
690     	else {
691     		IRDA_DEBUG(0, __FUNCTION__ "(), no handler\n");
692     		dev_kfree_skb(userdata);
693     	}
694     }
695     
696     /*
697      * Function irlmp_do_expiry (void)
698      *
699      *    Do a cleanup of the discovery log (remove old entries)
700      *
701      * Note : separate from irlmp_do_discovery() so that we can handle
702      * passive discovery properly.
703      */
704     void irlmp_do_expiry()
705     {
706     	struct lap_cb *lap;
707     
708     	/*
709     	 * Expire discovery on all links which are *not* connected.
710     	 * On links which are connected, we can't do discovery
711     	 * anymore and can't refresh the log, so we freeze the
712     	 * discovery log to keep info about the device we are
713     	 * connected to. - Jean II
714     	 */
715     	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
716     	while (lap != NULL) {
717     		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
718     		
719     		if (lap->lap_state == LAP_STANDBY) {
720     			/* Expire discoveries discovered on this link */
721     			irlmp_expire_discoveries(irlmp->cachelog, lap->saddr,
722     						 FALSE);
723     		}
724     		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
725     	}
726     }
727     
728     /*
729      * Function irlmp_do_discovery (nslots)
730      *
731      *    Do some discovery on all links
732      *
733      * Note : log expiry is done above.
734      */
735     void irlmp_do_discovery(int nslots)
736     {
737     	struct lap_cb *lap;
738     
739     	/* Make sure the value is sane */
740     	if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){
741     		WARNING(__FUNCTION__ 
742     		       "(), invalid value for number of slots!\n");
743     		nslots = sysctl_discovery_slots = 8;
744     	}
745     
746     	/* Construct new discovery info to be used by IrLAP, */
747     	irlmp->discovery_cmd.hints.word = irlmp->hints.word;
748     	
749     	/* 
750     	 *  Set character set for device name (we use ASCII), and 
751     	 *  copy device name. Remember to make room for a \0 at the 
752     	 *  end
753     	 */
754     	irlmp->discovery_cmd.charset = CS_ASCII;
755     	strncpy(irlmp->discovery_cmd.nickname, sysctl_devname, 
756     		NICKNAME_MAX_LEN);
757     	irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.nickname);
758     	irlmp->discovery_cmd.nslots = nslots;
759     	
760     	/*
761     	 * Try to send discovery packets on all links
762     	 */
763     	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
764     	while (lap != NULL) {
765     		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
766     		
767     		if (lap->lap_state == LAP_STANDBY) {
768     			/* Try to discover */
769     			irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST, 
770     					   NULL);
771     		}
772     		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
773     	}
774     }
775     
776     /*
777      * Function irlmp_discovery_request (nslots)
778      *
779      *    Do a discovery of devices in front of the computer
780      *
781      */
782     void irlmp_discovery_request(int nslots)
783     {
784     	/* Check if user wants to override the default */
785     	if (nslots == DISCOVERY_DEFAULT_SLOTS)
786     		nslots = sysctl_discovery_slots;
787     
788     	/* Return current cached discovery log */
789     	irlmp_discovery_confirm(irlmp->cachelog);
790     
791     	/* 
792     	 * Start a single discovery operation if discovery is not already
793              * running 
794     	 */
795     	if (!sysctl_discovery)
796     		irlmp_do_discovery(nslots);
797     	/* Note : we never do expiry here. Expiry will run on the
798     	 * discovery timer regardless of the state of sysctl_discovery
799     	 * Jean II */
800     }
801     
802     /*
803      * Function irlmp_get_discoveries (pn, mask)
804      *
805      *    Return the current discovery log
806      *
807      */
808     struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask)
809     {
810     	/* Return current cached discovery log */
811     	return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask));
812     }
813     
814     #if 0
815     /*
816      * Function irlmp_check_services (discovery)
817      *
818      *    
819      *
820      */
821     void irlmp_check_services(discovery_t *discovery)
822     {
823     	struct irlmp_client *client;
824     	__u8 *service_log;
825     	__u8 service;
826     	int i = 0;
827     
828     	IRDA_DEBUG(1, "IrDA Discovered: %s\n", discovery->info);
829     	IRDA_DEBUG(1, "    Services: ");
830     
831     	service_log = irlmp_hint_to_service(discovery->hints.byte);
832     	if (!service_log)
833     		return;
834     
835     	/*
836     	 *  Check all services on the device
837     	 */
838     	while ((service = service_log[i++]) != S_END) {
839     		IRDA_DEBUG( 4, "service=%02x\n", service);
840     		client = hashbin_find(irlmp->registry, service, NULL);
841     		if (entry && entry->discovery_callback) {
842     			IRDA_DEBUG( 4, "discovery_callback!\n");
843     
844     			entry->discovery_callback(discovery);
845     		} else {
846     			/* Don't notify about the ANY service */
847     			if (service == S_ANY)
848     				continue;
849     			/*  
850     			 * Found no clients for dealing with this service,
851     			 */
852     		}
853     	}
854     	kfree(service_log);
855     }
856     #endif
857     /*
858      * Function irlmp_notify_client (log)
859      *
860      *    Notify all about discovered devices
861      *
862      * Clients registered with IrLMP are :
863      *	o IrComm
864      *	o IrLAN
865      *	o Any socket (in any state - ouch, that may be a lot !)
866      * The client may have defined a callback to be notified in case of
867      * partial/selective discovery based on the hints that it passed to IrLMP.
868      */
869     static inline void
870     irlmp_notify_client(irlmp_client_t *client, hashbin_t *log)
871     {
872     	discovery_t *discovery;
873     
874     	IRDA_DEBUG(3, __FUNCTION__ "()\n");
875     	
876     	/* Check if client wants or not partial/selective log (optimisation) */
877     	if (!client->disco_callback)
878     		return;
879     
880     	/* 
881     	 * Now, check all discovered devices (if any), and notify client 
882     	 * only about the services that the client is interested in 
883     	 */
884     	discovery = (discovery_t *) hashbin_get_first(log);
885     	while (discovery != NULL) {
886     		IRDA_DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr); 
887     		
888     		/* 
889     		 * Any common hint bits? Remember to mask away the extension
890     		 * bits ;-)
891     		 */
892     		if (client->hint_mask & discovery->hints.word & 0x7f7f)
893     			client->disco_callback(discovery, client->priv);
894     
895     		discovery = (discovery_t *) hashbin_get_next(log);
896     	}
897     }
898     
899     /*
900      * Function irlmp_discovery_confirm ( self, log)
901      *
902      *    Some device(s) answered to our discovery request! Check to see which
903      *    device it is, and give indication to the client(s)
904      * 
905      */
906     void irlmp_discovery_confirm(hashbin_t *log) 
907     {
908     	irlmp_client_t *client;
909     	
910     	IRDA_DEBUG(3, __FUNCTION__ "()\n");
911     	
912     	ASSERT(log != NULL, return;);
913     	
914     	if (!(HASHBIN_GET_SIZE(log)))
915     		return;
916     	
917     	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
918     	while (client != NULL) {
919     		/* Check if we should notify client */
920     		irlmp_notify_client(client, log);
921     			
922     		client = (irlmp_client_t *) hashbin_get_next(irlmp->clients);
923     	}
924     }
925     
926     /*
927      * Function irlmp_discovery_expiry (expiry)
928      *
929      *	This device is no longer been discovered, and therefore it is beeing
930      *	purged from the discovery log. Inform all clients who have
931      *	registered for this event...
932      * 
933      *	Note : called exclusively from discovery.c
934      *	Note : as we are currently processing the log, the clients callback
935      *	should *NOT* attempt to touch the log now.
936      */
937     void irlmp_discovery_expiry(discovery_t *expiry) 
938     {
939     	irlmp_client_t *client;
940     	
941     	IRDA_DEBUG(3, __FUNCTION__ "()\n");
942     
943     	ASSERT(expiry != NULL, return;);
944     	
945     	client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
946     	while (client != NULL) {
947     		/* Check if we should notify client */
948     		if ((client->expir_callback) &&
949     		    (client->hint_mask & expiry->hints.word & 0x7f7f))
950     			client->expir_callback(expiry, client->priv);
951     
952     		/* Next client */
953     		client = (irlmp_client_t *) hashbin_get_next(irlmp->clients);
954     	}
955     }
956     
957     /*
958      * Function irlmp_get_discovery_response ()
959      *
960      *    Used by IrLAP to get the discovery info it needs when answering
961      *    discovery requests by other devices.
962      */
963     discovery_t *irlmp_get_discovery_response()
964     {
965     	IRDA_DEBUG(4, __FUNCTION__ "()\n");
966     
967     	ASSERT(irlmp != NULL, return NULL;);
968     
969     	irlmp->discovery_rsp.hints.word = irlmp->hints.word;
970     
971     	/* 
972     	 *  Set character set for device name (we use ASCII), and 
973     	 *  copy device name. Remember to make room for a \0 at the 
974     	 *  end
975     	 */
976     	irlmp->discovery_rsp.charset = CS_ASCII;
977     
978     	strncpy(irlmp->discovery_rsp.nickname, sysctl_devname, 
979     		NICKNAME_MAX_LEN);
980     	irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.nickname);
981     
982     	return &irlmp->discovery_rsp;
983     }
984     
985     /*
986      * Function irlmp_data_request (self, skb)
987      *
988      *    Send some data to peer device
989      *
990      */
991     int irlmp_data_request(struct lsap_cb *self, struct sk_buff *skb) 
992     {
993     	ASSERT(self != NULL, return -1;);
994     	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
995     	
996     	/* Make room for MUX header */
997     	ASSERT(skb_headroom(skb) >= LMP_HEADER, return -1;);
998     	skb_push(skb, LMP_HEADER);
999     	
1000     	return irlmp_do_lsap_event(self, LM_DATA_REQUEST, skb);
1001     }
1002     
1003     /*
1004      * Function irlmp_data_indication (handle, skb)
1005      *
1006      *    Got data from LAP layer so pass it up to upper layer
1007      *
1008      */
1009     void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
1010     {
1011     	/* Hide LMP header from layer above */
1012     	skb_pull(skb, LMP_HEADER);
1013     
1014     	if (self->notify.data_indication)
1015     		self->notify.data_indication(self->notify.instance, self, skb);
1016     	else
1017     		dev_kfree_skb(skb);
1018     }
1019     
1020     /*
1021      * Function irlmp_udata_request (self, skb)
1022      *
1023      *    
1024      *
1025      */
1026     int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb) 
1027     {
1028      	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
1029     
1030     	ASSERT(skb != NULL, return -1;);
1031     	
1032     	/* Make room for MUX header */
1033     	ASSERT(skb_headroom(skb) >= LMP_HEADER, return -1;);
1034     	skb_push(skb, LMP_HEADER);
1035     
1036     	return irlmp_do_lsap_event(self, LM_UDATA_REQUEST, skb);
1037     }
1038     
1039     /*
1040      * Function irlmp_udata_indication (self, skb)
1041      *
1042      *    Send unreliable data (but still within the connection)
1043      *
1044      */
1045     void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) 
1046     {
1047      	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
1048     
1049     	ASSERT(self != NULL, return;);
1050     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1051     	ASSERT(skb != NULL, return;);
1052     
1053     	/* Hide LMP header from layer above */
1054     	skb_pull(skb, LMP_HEADER);
1055     
1056     	if (self->notify.udata_indication)
1057     		self->notify.udata_indication(self->notify.instance, self, 
1058     					      skb);
1059     	else
1060     		dev_kfree_skb(skb);
1061     }
1062     
1063     /*
1064      * Function irlmp_connless_data_request (self, skb)
1065      *
1066      *    
1067      *
1068      */
1069     #ifdef CONFIG_IRDA_ULTRA
1070     int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *skb) 
1071     {
1072     	struct sk_buff *clone_skb;
1073     	struct lap_cb *lap;
1074     
1075      	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
1076     
1077     	ASSERT(skb != NULL, return -1;);
1078     	
1079     	/* Make room for MUX and PID header */
1080     	ASSERT(skb_headroom(skb) >= LMP_HEADER+LMP_PID_HEADER, return -1;);
1081     	
1082     	/* Insert protocol identifier */
1083     	skb_push(skb, LMP_PID_HEADER);
1084     	skb->data[0] = self->pid;
1085     
1086     	/* Connectionless sockets must use 0x70 */
1087     	skb_push(skb, LMP_HEADER);
1088     	skb->data[0] = skb->data[1] = LSAP_CONNLESS;
1089     
1090     	/* Try to send Connectionless  packets out on all links */
1091     	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1092     	while (lap != NULL) {
1093     		ASSERT(lap->magic == LMP_LAP_MAGIC, return -1;);
1094     
1095     		clone_skb = skb_clone(skb, GFP_ATOMIC);
1096     		if (!clone_skb)
1097     			return -ENOMEM;
1098     
1099     		irlap_unitdata_request(lap->irlap, clone_skb);
1100     		
1101     		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1102     	}
1103     	dev_kfree_skb(skb);
1104     
1105     	return 0;
1106     }
1107     #endif /* CONFIG_IRDA_ULTRA */
1108     
1109     /*
1110      * Function irlmp_connless_data_indication (self, skb)
1111      *
1112      *    Receive unreliable data outside any connection. Mostly used by Ultra
1113      *
1114      */
1115     #ifdef CONFIG_IRDA_ULTRA
1116     void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
1117     {
1118      	IRDA_DEBUG(4, __FUNCTION__ "()\n"); 
1119     
1120     	ASSERT(self != NULL, return;);
1121     	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1122     	ASSERT(skb != NULL, return;);
1123     
1124     	/* Hide LMP and PID header from layer above */
1125     	skb_pull(skb, LMP_HEADER+LMP_PID_HEADER);
1126     
1127     	if (self->notify.udata_indication)
1128     		self->notify.udata_indication(self->notify.instance, self,
1129     					      skb);
1130     	else
1131     		dev_kfree_skb(skb);
1132     }
1133     #endif /* CONFIG_IRDA_ULTRA */
1134     
1135     void irlmp_status_request(void) 
1136     {
1137     	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
1138     }
1139     
1140     /*
1141      * Propagate status indication from LAP to LSAPs (via LMP)
1142      * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb,
1143      * and the event is stateless, therefore we can bypass both state machines
1144      * and send the event direct to the LSAP user.
1145      * Jean II
1146      */
1147     void irlmp_status_indication(struct lap_cb *self,
1148     			     LINK_STATUS link, LOCK_STATUS lock) 
1149     {
1150     	struct lsap_cb *next;
1151     	struct lsap_cb *curr;
1152     
1153     	/* Send status_indication to all LSAPs using this link */
1154     	next = (struct lsap_cb *) hashbin_get_first( self->lsaps);
1155     	while (next != NULL ) {
1156     		curr = next;
1157     		next = (struct lsap_cb *) hashbin_get_next(self->lsaps);
1158     
1159     		ASSERT(curr->magic == LMP_LSAP_MAGIC, return;);
1160     		/*
1161     		 *  Inform service user if he has requested it
1162     		 */
1163     		if (curr->notify.status_indication != NULL)
1164     			curr->notify.status_indication(curr->notify.instance, 
1165     						       link, lock);
1166     		else
1167     			IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
1168     	}
1169     }
1170     
1171     /*
1172      * Function irlmp_hint_to_service (hint)
1173      *
1174      *    Returns a list of all servics contained in the given hint bits. This
1175      *    funtion assumes that the hint bits have the size of two bytes only
1176      */
1177     __u8 *irlmp_hint_to_service(__u8 *hint)
1178     {
1179     	__u8 *service;
1180     	int i = 0;
1181     
1182     	/* 
1183     	 * Allocate array to store services in. 16 entries should be safe 
1184     	 * since we currently only support 2 hint bytes
1185     	 */
1186     	service = kmalloc(16, GFP_ATOMIC);
1187     	if (!service) {
1188     		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n");
1189     		return NULL;
1190     	}
1191     
1192     	if (!hint[0]) {
1193     		IRDA_DEBUG(1, "<None>\n");
1194     		kfree(service);
1195     		return NULL;
1196     	}
1197     	if (hint[0] & HINT_PNP)
1198     		IRDA_DEBUG(1, "PnP Compatible ");
1199     	if (hint[0] & HINT_PDA)
1200     		IRDA_DEBUG(1, "PDA/Palmtop ");
1201     	if (hint[0] & HINT_COMPUTER)
1202     		IRDA_DEBUG(1, "Computer ");
1203     	if (hint[0] & HINT_PRINTER) {
1204     		IRDA_DEBUG(1, "Printer ");
1205     		service[i++] = S_PRINTER;
1206     	}
1207     	if (hint[0] & HINT_MODEM)
1208     		IRDA_DEBUG(1, "Modem ");
1209     	if (hint[0] & HINT_FAX)
1210     		IRDA_DEBUG(1, "Fax ");
1211     	if (hint[0] & HINT_LAN) {
1212     		IRDA_DEBUG(1, "LAN Access ");		
1213     		service[i++] = S_LAN;
1214     	}
1215     	/* 
1216     	 *  Test if extension byte exists. This byte will usually be
1217     	 *  there, but this is not really required by the standard.
1218     	 *  (IrLMP p. 29)
1219     	 */
1220     	if (hint[0] & HINT_EXTENSION) {
1221     		if (hint[1] & HINT_TELEPHONY) {
1222     			IRDA_DEBUG(1, "Telephony ");
1223     			service[i++] = S_TELEPHONY;
1224     		} if (hint[1] & HINT_FILE_SERVER)
1225     			IRDA_DEBUG(1, "File Server ");
1226     		
1227     		if (hint[1] & HINT_COMM) {
1228     			IRDA_DEBUG(1, "IrCOMM ");
1229     			service[i++] = S_COMM;
1230     		}
1231     		if (hint[1] & HINT_OBEX) {
1232     			IRDA_DEBUG(1, "IrOBEX ");
1233     			service[i++] = S_OBEX;
1234     		}
1235     	}
1236     	IRDA_DEBUG(1, "\n");
1237     
1238     	/* So that client can be notified about any discovery */
1239     	service[i++] = S_ANY;
1240     
1241     	service[i] = S_END;
1242     	
1243     	return service;
1244     }
1245     
1246     /*
1247      * Function irlmp_service_to_hint (service)
1248      *
1249      *    Converts a service type, to a hint bit
1250      *
1251      *    Returns: a 16 bit hint value, with the service bit set
1252      */
1253     __u16 irlmp_service_to_hint(int service)
1254     {
1255     	__u16_host_order hint;
1256     
1257     	hint.word = 0;
1258     
1259     	switch (service) {
1260     	case S_PNP:
1261     		hint.byte[0] |= HINT_PNP;
1262     		break;
1263     	case S_PDA:
1264     		hint.byte[0] |= HINT_PDA;
1265     		break;
1266     	case S_COMPUTER:
1267     		hint.byte[0] |= HINT_COMPUTER;
1268     		break;
1269     	case S_PRINTER:
1270     		hint.byte[0] |= HINT_PRINTER;
1271     		break;
1272     	case S_MODEM:
1273     		hint.byte[0] |= HINT_PRINTER;
1274     		break;
1275     	case S_LAN:
1276     		hint.byte[0] |= HINT_LAN;
1277     		break;
1278     	case S_COMM:
1279     		hint.byte[0] |= HINT_EXTENSION;
1280     		hint.byte[1] |= HINT_COMM;
1281     		break;
1282     	case S_OBEX:
1283     		hint.byte[0] |= HINT_EXTENSION;
1284     		hint.byte[1] |= HINT_OBEX;
1285     		break;
1286     	case S_TELEPHONY:
1287     		hint.byte[0] |= HINT_EXTENSION;
1288     		hint.byte[1] |= HINT_TELEPHONY;
1289     		break;
1290     	case S_ANY:
1291     		hint.word = 0xffff;
1292     		break;
1293     	default:
1294     		IRDA_DEBUG( 1, __FUNCTION__ "(), Unknown service!\n");
1295     		break;
1296     	}
1297     	return hint.word;
1298     }
1299     
1300     /*
1301      * Function irlmp_register_service (service)
1302      *
1303      *    Register local service with IrLMP
1304      *
1305      */
1306     __u32 irlmp_register_service(__u16 hints)
1307     {
1308     	irlmp_service_t *service;
1309     	__u32 handle;
1310     
1311     	IRDA_DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints);
1312     
1313     	/* Get a unique handle for this service */
1314     	get_random_bytes(&handle, sizeof(handle));
1315     	while (hashbin_find(irlmp->services, handle, NULL) || !handle)
1316     		get_random_bytes(&handle, sizeof(handle));
1317     
1318     	irlmp->hints.word |= hints;
1319     
1320     	/* Make a new registration */
1321      	service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
1322     	if (!service) {
1323     		IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n");
1324     		return 0;
1325     	}
1326     	service->hints = hints;
1327     	hashbin_insert(irlmp->services, (irda_queue_t *) service, handle, NULL);
1328     
1329     	return handle;
1330     }
1331     
1332     /*
1333      * Function irlmp_unregister_service (handle)
1334      *
1335      *    Unregister service with IrLMP. 
1336      *
1337      *    Returns: 0 on success, -1 on error
1338      */
1339     int irlmp_unregister_service(__u32 handle)
1340     {
1341     	irlmp_service_t *service;
1342     		
1343      	IRDA_DEBUG(4, __FUNCTION__ "()\n");
1344     
1345     	if (!handle)
1346     		return -1;
1347      
1348     	service = hashbin_find(irlmp->services, handle, NULL);
1349     	if (!service) {
1350     		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n");
1351     		return -1;
1352     	}
1353     
1354     	service = hashbin_remove(irlmp->services, handle, NULL);
1355     	if (service)
1356     		kfree(service);
1357     
1358     	/* Remove old hint bits */
1359     	irlmp->hints.word = 0;
1360     
1361     	/* Refresh current hint bits */
1362             service = (irlmp_service_t *) hashbin_get_first(irlmp->services);
1363             while (service) {
1364     		irlmp->hints.word |= service->hints;
1365     
1366                     service = (irlmp_service_t *)hashbin_get_next(irlmp->services);
1367             }
1368     	return 0;
1369     }
1370     
1371     /*
1372      * Function irlmp_register_client (hint_mask, callback1, callback2)
1373      *
1374      *    Register a local client with IrLMP
1375      *	First callback is selective discovery (based on hints)
1376      *	Second callback is for selective discovery expiries
1377      *
1378      *    Returns: handle > 0 on success, 0 on error
1379      */
1380     __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
1381     			    DISCOVERY_CALLBACK1 expir_clb, void *priv)
1382     {
1383     	irlmp_client_t *client;
1384     	__u32 handle;
1385     
1386     	IRDA_DEBUG(0, __FUNCTION__ "()\n");
1387     	ASSERT(irlmp != NULL, return 0;);
1388     	
1389     	/* Get a unique handle for this client */
1390     	get_random_bytes(&handle, sizeof(handle));
1391     	while (hashbin_find(irlmp->clients, handle, NULL) || !handle)
1392     		get_random_bytes(&handle, sizeof(handle));
1393     
1394     	/* Make a new registration */
1395      	client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
1396     	if (!client) {
1397     		IRDA_DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n");
1398     		return 0;
1399     	}
1400     
1401     	/* Register the details */
1402     	client->hint_mask = hint_mask;
1403     	client->disco_callback = disco_clb;
1404     	client->expir_callback = expir_clb;
1405     	client->priv = priv;
1406     
1407      	hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL);
1408     
1409     	return handle;
1410     }
1411     
1412     /*
1413      * Function irlmp_update_client (handle, hint_mask, callback1, callback2)
1414      *
1415      *    Updates specified client (handle) with possibly new hint_mask and
1416      *    callback
1417      *
1418      *    Returns: 0 on success, -1 on error
1419      */
1420     int irlmp_update_client(__u32 handle, __u16 hint_mask, 
1421     			DISCOVERY_CALLBACK1 disco_clb, 
1422     			DISCOVERY_CALLBACK1 expir_clb, void *priv)
1423     {
1424     	irlmp_client_t *client;
1425     
1426     	if (!handle)
1427     		return -1;
1428     
1429     	client = hashbin_find(irlmp->clients, handle, NULL);
1430     	if (!client) {
1431     		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
1432     		return -1;
1433     	}
1434     
1435     	client->hint_mask = hint_mask;
1436     	client->disco_callback = disco_clb;
1437     	client->expir_callback = expir_clb;
1438     	client->priv = priv;
1439     	
1440     	return 0;
1441     }
1442     
1443     /*
1444      * Function irlmp_unregister_client (handle)
1445      *
1446      *    Returns: 0 on success, -1 on error
1447      *
1448      */
1449     int irlmp_unregister_client(__u32 handle)
1450     {
1451      	struct irlmp_client *client;
1452      
1453      	IRDA_DEBUG(4, __FUNCTION__ "()\n");
1454     
1455     	if (!handle)
1456     		return -1;
1457      
1458     	client = hashbin_find(irlmp->clients, handle, NULL);
1459     	if (!client) {
1460     		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
1461     		return -1;
1462     	}
1463     
1464     	IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n");
1465     	client = hashbin_remove( irlmp->clients, handle, NULL);
1466     	if (client)
1467     		kfree(client);
1468     	
1469     	return 0;
1470     }
1471     
1472     /*
1473      * Function irlmp_slsap_inuse (slsap)
1474      *
1475      *    Check if the given source LSAP selector is in use
1476      */
1477     int irlmp_slsap_inuse(__u8 slsap_sel)
1478     {
1479     	struct lsap_cb *self;
1480     	struct lap_cb *lap;
1481     
1482     	ASSERT(irlmp != NULL, return TRUE;);
1483     	ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;);
1484     	ASSERT(slsap_sel != LSAP_ANY, return TRUE;);
1485     
1486     	IRDA_DEBUG(4, __FUNCTION__ "()\n");
1487     
1488     #ifdef CONFIG_IRDA_ULTRA
1489     	/* Accept all bindings to the connectionless LSAP */
1490     	if (slsap_sel == LSAP_CONNLESS)
1491     		return FALSE;
1492     #endif /* CONFIG_IRDA_ULTRA */
1493     
1494     	/* Valid values are between 0 and 127 */
1495     	if (slsap_sel > LSAP_MAX)
1496     		return TRUE;
1497     
1498     	/*
1499     	 *  Check if slsap is already in use. To do this we have to loop over
1500     	 *  every IrLAP connection and check every LSAP assosiated with each
1501     	 *  the connection.
1502     	 */
1503     	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1504     	while (lap != NULL) {
1505     		ASSERT(lap->magic == LMP_LAP_MAGIC, return TRUE;);
1506     
1507     		self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1508     		while (self != NULL) {
1509     			ASSERT(self->magic == LMP_LSAP_MAGIC, return TRUE;);
1510     
1511     			if ((self->slsap_sel == slsap_sel)) {
1512     				IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
1513     				      self->slsap_sel); 
1514     				return TRUE;
1515     			}
1516     			self = (struct lsap_cb*) hashbin_get_next(lap->lsaps);
1517     		}
1518     		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1519     	}     
1520     	return FALSE;
1521     }
1522     
1523     /*
1524      * Function irlmp_find_free_slsap ()
1525      *
1526      *    Find a free source LSAP to use. This function is called if the service
1527      *    user has requested a source LSAP equal to LM_ANY
1528      */
1529     __u8 irlmp_find_free_slsap(void) 
1530     {
1531     	__u8 lsap_sel;
1532     	int wrapped = 0;
1533     
1534     	ASSERT(irlmp != NULL, return -1;);
1535     	ASSERT(irlmp->magic == LMP_MAGIC, return -1;);
1536           
1537     	lsap_sel = irlmp->free_lsap_sel++;
1538     	
1539     	/* Check if the new free lsap is really free */
1540     	while (irlmp_slsap_inuse(irlmp->free_lsap_sel)) {
1541     		irlmp->free_lsap_sel++;
1542     
1543     		/* Check if we need to wraparound (0x70-0x7f are reserved) */
1544     		if (irlmp->free_lsap_sel > LSAP_MAX) {
1545     			irlmp->free_lsap_sel = 10;
1546     
1547     			/* Make sure we terminate the loop */
1548     			if (wrapped++)
1549     				return 0;
1550     		}
1551     	}
1552     	IRDA_DEBUG(4, __FUNCTION__ "(), next free lsap_sel=%02x\n", lsap_sel);
1553     	
1554     	return lsap_sel;
1555     }
1556     
1557     /*
1558      * Function irlmp_convert_lap_reason (lap_reason)
1559      *
1560      *    Converts IrLAP disconnect reason codes to IrLMP disconnect reason
1561      *    codes
1562      *
1563      */
1564     LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason)
1565     {
1566     	int reason = LM_LAP_DISCONNECT;
1567     
1568     	switch (lap_reason) {		
1569     	case LAP_DISC_INDICATION: /* Received a disconnect request from peer */
1570     		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_DISC_INDICATION\n");
1571     		reason = LM_USER_REQUEST;
1572     		break;
1573     	case LAP_NO_RESPONSE:    /* To many retransmits without response */
1574     		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_NO_RESPONSE\n");
1575     		reason = LM_LAP_DISCONNECT;
1576     		break;
1577     	case LAP_RESET_INDICATION:
1578     		IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_RESET_INDICATION\n");
1579     		reason = LM_LAP_RESET;
1580     		break;
1581     	case LAP_FOUND_NONE:
1582     	case LAP_MEDIA_BUSY:
1583     	case LAP_PRIMARY_CONFLICT:
1584     		IRDA_DEBUG(1, __FUNCTION__ "(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n");
1585     		reason = LM_CONNECT_FAILURE;
1586     		break;
1587     	default:
1588     		IRDA_DEBUG(1, __FUNCTION__ 
1589     		      "(), Unknow IrLAP disconnect reason %d!\n", lap_reason);
1590     		reason = LM_LAP_DISCONNECT;
1591     		break;
1592     	}
1593     
1594     	return reason;
1595     }	
1596     
1597     __u32 irlmp_get_saddr(struct lsap_cb *self)
1598     {
1599     	ASSERT(self != NULL, return 0;);
1600     	ASSERT(self->lap != NULL, return 0;);
1601     
1602     	return self->lap->saddr;
1603     }
1604     
1605     __u32 irlmp_get_daddr(struct lsap_cb *self)
1606     {
1607     	ASSERT(self != NULL, return 0;);
1608     	ASSERT(self->lap != NULL, return 0;);
1609     	
1610     	return self->lap->daddr;
1611     }
1612     
1613     #ifdef CONFIG_PROC_FS
1614     /*
1615      * Function irlmp_proc_read (buf, start, offset, len, unused)
1616      *
1617      *    Give some info to the /proc file system
1618      *
1619      */
1620     int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
1621     {
1622     	struct lsap_cb *self;
1623     	struct lap_cb *lap;
1624     	unsigned long flags;
1625     
1626     	ASSERT(irlmp != NULL, return 0;);
1627     	
1628     	save_flags( flags);
1629     	cli();
1630     
1631     	len = 0;
1632     	
1633     	len += sprintf( buf+len, "Unconnected LSAPs:\n");
1634     	self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
1635     	while (self != NULL) {
1636     		ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
1637     		len += sprintf(buf+len, "lsap state: %s, ", 
1638     			       irlsap_state[ self->lsap_state]);
1639     		len += sprintf(buf+len, 
1640     			       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1641     			       self->slsap_sel, self->dlsap_sel); 
1642     		len += sprintf(buf+len, "(%s)", self->notify.name);
1643     		len += sprintf(buf+len, "\n");
1644     
1645     		self = (struct lsap_cb *) hashbin_get_next(
1646     			irlmp->unconnected_lsaps);
1647      	} 
1648     
1649     	len += sprintf(buf+len, "\nRegistred Link Layers:\n");
1650     
1651     	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1652     	while (lap != NULL) {
1653     		len += sprintf(buf+len, "lap state: %s, ", 
1654     			       irlmp_state[lap->lap_state]);
1655     
1656     		len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
1657     			       lap->saddr, lap->daddr); 
1658     		len += sprintf(buf+len, "refcount: %d", lap->refcount);
1659     		len += sprintf(buf+len, "\n");
1660     
1661     		len += sprintf(buf+len, "\nConnected LSAPs:\n");
1662     		self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1663     		while (self != NULL) {
1664     			ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
1665     			len += sprintf(buf+len, "lsap state: %s, ", 
1666     				       irlsap_state[ self->lsap_state]);
1667     			len += sprintf(buf+len, 
1668     				       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1669     				       self->slsap_sel, self->dlsap_sel);
1670     			len += sprintf(buf+len, "(%s)", self->notify.name);
1671     			len += sprintf(buf+len, "\n");
1672     			
1673     			self = (struct lsap_cb *) hashbin_get_next( 
1674     				lap->lsaps);
1675     		} 
1676     		len += sprintf(buf+len, "\n");
1677     
1678     		lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1679      	} 
1680     	restore_flags(flags);
1681     	
1682     	return len;
1683     }
1684     
1685     #endif /* PROC_FS */
1686     
1687     
1688     
1689