More cleaning ...
[linux-2.6/linux-mips.git] / net / irda / irlmp.c
blobb6d41fc2772fb4db348f75502613f13ae4b7600e
1 /*********************************************************************
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>
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
25 ********************************************************************/
27 #include <linux/config.h>
28 #include <linux/slab.h>
29 #include <linux/string.h>
30 #include <linux/skbuff.h>
31 #include <linux/types.h>
32 #include <linux/proc_fs.h>
33 #include <linux/init.h>
34 #include <linux/kmod.h>
35 #include <linux/random.h>
37 #include <net/irda/irda.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>
45 /* Master structure */
46 struct irlmp_cb *irlmp = NULL;
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];
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",
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
71 * Function irlmp_init (void)
73 * Create (allocate) the main IrLMP structure
76 int __init irlmp_init(void)
78 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
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));
85 irlmp->magic = LMP_MAGIC;
87 irlmp->clients = hashbin_new(HB_LOCK);
88 irlmp->services = hashbin_new(HB_LOCK);
89 irlmp->links = hashbin_new(HB_LOCK);
90 irlmp->unconnected_lsaps = hashbin_new(HB_LOCK);
91 irlmp->cachelog = hashbin_new(HB_NOLOCK);
92 spin_lock_init(&irlmp->cachelog->hb_spinlock);
94 irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
95 strcpy(sysctl_devname, "Linux");
97 /* Do discovery every 3 seconds */
98 init_timer(&irlmp->discovery_timer);
99 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
101 return 0;
105 * Function irlmp_cleanup (void)
107 * Remove IrLMP layer
110 void __exit irlmp_cleanup(void)
112 /* Check for main structure */
113 ASSERT(irlmp != NULL, return;);
114 ASSERT(irlmp->magic == LMP_MAGIC, return;);
116 del_timer(&irlmp->discovery_timer);
118 hashbin_delete(irlmp->links, (FREE_FUNC) kfree);
119 hashbin_delete(irlmp->unconnected_lsaps, (FREE_FUNC) kfree);
120 hashbin_delete(irlmp->clients, (FREE_FUNC) kfree);
121 hashbin_delete(irlmp->services, (FREE_FUNC) kfree);
122 hashbin_delete(irlmp->cachelog, (FREE_FUNC) kfree);
124 /* De-allocate main structure */
125 kfree(irlmp);
126 irlmp = NULL;
130 * Function irlmp_open_lsap (slsap, notify)
132 * Register with IrLMP and create a local LSAP,
133 * returns handle to LSAP.
135 struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
137 struct lsap_cb *self;
139 ASSERT(notify != NULL, return NULL;);
140 ASSERT(irlmp != NULL, return NULL;);
141 ASSERT(irlmp->magic == LMP_MAGIC, return NULL;);
143 /* Does the client care which Source LSAP selector it gets? */
144 if (slsap_sel == LSAP_ANY) {
145 slsap_sel = irlmp_find_free_slsap();
146 if (!slsap_sel)
147 return NULL;
148 } else if (irlmp_slsap_inuse(slsap_sel))
149 return NULL;
151 /* Allocate new instance of a LSAP connection */
152 self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
153 if (self == NULL) {
154 ERROR("%s: can't allocate memory", __FUNCTION__);
155 return NULL;
157 memset(self, 0, sizeof(struct lsap_cb));
159 self->magic = LMP_LSAP_MAGIC;
160 self->slsap_sel = slsap_sel;
162 /* Fix connectionless LSAP's */
163 if (slsap_sel == LSAP_CONNLESS) {
164 #ifdef CONFIG_IRDA_ULTRA
165 self->dlsap_sel = LSAP_CONNLESS;
166 self->pid = pid;
167 #endif /* CONFIG_IRDA_ULTRA */
168 } else
169 self->dlsap_sel = LSAP_ANY;
170 /* self->connected = FALSE; -> already NULL via memset() */
172 init_timer(&self->watchdog_timer);
174 ASSERT(notify->instance != NULL, return NULL;);
175 self->notify = *notify;
177 self->lsap_state = LSAP_DISCONNECTED;
179 /* Insert into queue of unconnected LSAPs */
180 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
181 (long) self, NULL);
183 return self;
187 * Function __irlmp_close_lsap (self)
189 * Remove an instance of LSAP
191 static void __irlmp_close_lsap(struct lsap_cb *self)
193 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
195 ASSERT(self != NULL, return;);
196 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
199 * Set some of the variables to preset values
201 self->magic = 0;
202 del_timer(&self->watchdog_timer); /* Important! */
204 if (self->conn_skb)
205 dev_kfree_skb(self->conn_skb);
207 kfree(self);
211 * Function irlmp_close_lsap (self)
213 * Close and remove LSAP
216 void irlmp_close_lsap(struct lsap_cb *self)
218 struct lap_cb *lap;
219 struct lsap_cb *lsap = NULL;
221 ASSERT(self != NULL, return;);
222 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
225 * Find out if we should remove this LSAP from a link or from the
226 * list of unconnected lsaps (not associated with a link)
228 lap = self->lap;
229 if (lap) {
230 ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
231 /* We might close a LSAP before it has completed the
232 * connection setup. In those case, higher layers won't
233 * send a proper disconnect request. Harmless, except
234 * that we will forget to close LAP... - Jean II */
235 if(self->lsap_state != LSAP_DISCONNECTED) {
236 self->lsap_state = LSAP_DISCONNECTED;
237 irlmp_do_lap_event(self->lap,
238 LM_LAP_DISCONNECT_REQUEST, NULL);
240 /* Now, remove from the link */
241 lsap = hashbin_remove(lap->lsaps, (long) self, NULL);
242 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
243 lap->cache.valid = FALSE;
244 #endif
246 self->lap = NULL;
247 /* Check if we found the LSAP! If not then try the unconnected lsaps */
248 if (!lsap) {
249 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
250 NULL);
252 if (!lsap) {
253 IRDA_DEBUG(0,
254 "%s(), Looks like somebody has removed me already!\n",
255 __FUNCTION__);
256 return;
258 __irlmp_close_lsap(self);
262 * Function irlmp_register_irlap (saddr, notify)
264 * Register IrLAP layer with IrLMP. There is possible to have multiple
265 * instances of the IrLAP layer, each connected to different IrDA ports
268 void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
270 struct lap_cb *lap;
272 ASSERT(irlmp != NULL, return;);
273 ASSERT(irlmp->magic == LMP_MAGIC, return;);
274 ASSERT(notify != NULL, return;);
277 * Allocate new instance of a LSAP connection
279 lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL);
280 if (lap == NULL) {
281 ERROR("%s: unable to kmalloc\n", __FUNCTION__);
282 return;
284 memset(lap, 0, sizeof(struct lap_cb));
286 lap->irlap = irlap;
287 lap->magic = LMP_LAP_MAGIC;
288 lap->saddr = saddr;
289 lap->daddr = DEV_ADDR_ANY;
290 lap->lsaps = hashbin_new(HB_LOCK);
291 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
292 lap->cache.valid = FALSE;
293 #endif
295 lap->lap_state = LAP_STANDBY;
297 init_timer(&lap->idle_timer);
300 * Insert into queue of LMP links
302 hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL);
305 * We set only this variable so IrLAP can tell us on which link the
306 * different events happened on
308 irda_notify_init(notify);
309 notify->instance = lap;
313 * Function irlmp_unregister_irlap (saddr)
315 * IrLAP layer has been removed!
318 void irlmp_unregister_link(__u32 saddr)
320 struct lap_cb *link;
322 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
324 link = hashbin_remove(irlmp->links, saddr, NULL);
325 if (link) {
326 ASSERT(link->magic == LMP_LAP_MAGIC, return;);
328 /* Remove all discoveries discovered at this link */
329 irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE);
331 del_timer(&link->idle_timer);
333 link->magic = 0;
334 kfree(link);
339 * Function irlmp_connect_request (handle, dlsap, userdata)
341 * Connect with a peer LSAP
344 int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
345 __u32 saddr, __u32 daddr,
346 struct qos_info *qos, struct sk_buff *userdata)
348 struct sk_buff *tx_skb = userdata;
349 struct lap_cb *lap;
350 struct lsap_cb *lsap;
351 int ret;
353 ASSERT(self != NULL, return -EBADR;);
354 ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;);
356 IRDA_DEBUG(2,
357 "%s(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n",
358 __FUNCTION__, self->slsap_sel, dlsap_sel, saddr, daddr);
360 if (test_bit(0, &self->connected)) {
361 ret = -EISCONN;
362 goto err;
365 /* Client must supply destination device address */
366 if (!daddr) {
367 ret = -EINVAL;
368 goto err;
371 /* Any userdata? */
372 if (tx_skb == NULL) {
373 tx_skb = dev_alloc_skb(64);
374 if (!tx_skb)
375 return -ENOMEM;
377 skb_reserve(tx_skb, LMP_MAX_HEADER);
380 /* Make room for MUX control header (3 bytes) */
381 ASSERT(skb_headroom(tx_skb) >= LMP_CONTROL_HEADER, return -1;);
382 skb_push(tx_skb, LMP_CONTROL_HEADER);
384 self->dlsap_sel = dlsap_sel;
387 * Find the link to where we should try to connect since there may
388 * be more than one IrDA port on this machine. If the client has
389 * passed us the saddr (and already knows which link to use), then
390 * we use that to find the link, if not then we have to look in the
391 * discovery log and check if any of the links has discovered a
392 * device with the given daddr
394 if ((!saddr) || (saddr == DEV_ADDR_ANY)) {
395 discovery_t *discovery;
396 unsigned long flags;
398 spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, flags);
399 if (daddr != DEV_ADDR_ANY)
400 discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
401 else {
402 IRDA_DEBUG(2, "%s(), no daddr\n", __FUNCTION__);
403 discovery = (discovery_t *)
404 hashbin_get_first(irlmp->cachelog);
407 if (discovery) {
408 saddr = discovery->data.saddr;
409 daddr = discovery->data.daddr;
411 spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, flags);
413 lap = hashbin_lock_find(irlmp->links, saddr, NULL);
414 if (lap == NULL) {
415 IRDA_DEBUG(1, "%s(), Unable to find a usable link!\n", __FUNCTION__);
416 ret = -EHOSTUNREACH;
417 goto err;
420 /* Check if LAP is disconnected or already connected */
421 if (lap->daddr == DEV_ADDR_ANY)
422 lap->daddr = daddr;
423 else if (lap->daddr != daddr) {
424 /* Check if some LSAPs are active on this LAP */
425 if (HASHBIN_GET_SIZE(lap->lsaps) == 0) {
426 /* No active connection, but LAP hasn't been
427 * disconnected yet (waiting for timeout in LAP).
428 * Maybe we could give LAP a bit of help in this case.
430 IRDA_DEBUG(0, "%s(), sorry, but I'm waiting for LAP to timeout!\n", __FUNCTION__);
431 ret = -EAGAIN;
432 goto err;
435 /* LAP is already connected to a different node, and LAP
436 * can only talk to one node at a time */
437 IRDA_DEBUG(0, "%s(), sorry, but link is busy!\n", __FUNCTION__);
438 ret = -EBUSY;
439 goto err;
442 self->lap = lap;
445 * Remove LSAP from list of unconnected LSAPs and insert it into the
446 * list of connected LSAPs for the particular link
448 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self, NULL);
450 ASSERT(lsap != NULL, return -1;);
451 ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
452 ASSERT(lsap->lap != NULL, return -1;);
453 ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;);
455 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (long) self,
456 NULL);
458 set_bit(0, &self->connected); /* TRUE */
461 * User supplied qos specifications?
463 if (qos)
464 self->qos = *qos;
466 irlmp_do_lsap_event(self, LM_CONNECT_REQUEST, tx_skb);
468 /* Drop reference count - see irlap_data_request(). */
469 dev_kfree_skb(tx_skb);
471 return 0;
473 err:
474 /* Cleanup */
475 if(tx_skb)
476 dev_kfree_skb(tx_skb);
477 return ret;
481 * Function irlmp_connect_indication (self)
483 * Incoming connection
486 void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb)
488 int max_seg_size;
489 int lap_header_size;
490 int max_header_size;
492 ASSERT(self != NULL, return;);
493 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
494 ASSERT(skb != NULL, return;);
495 ASSERT(self->lap != NULL, return;);
497 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
498 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
500 /* Note : self->lap is set in irlmp_link_data_indication(),
501 * (case CONNECT_CMD:) because we have no way to set it here.
502 * Similarly, self->dlsap_sel is usually set in irlmp_find_lsap().
503 * Jean II */
505 self->qos = *self->lap->qos;
507 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
508 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
509 max_header_size = LMP_HEADER + lap_header_size;
511 /* Hide LMP_CONTROL_HEADER header from layer above */
512 skb_pull(skb, LMP_CONTROL_HEADER);
514 if (self->notify.connect_indication) {
515 /* Don't forget to refcount it - see irlap_driver_rcv(). */
516 skb_get(skb);
517 self->notify.connect_indication(self->notify.instance, self,
518 &self->qos, max_seg_size,
519 max_header_size, skb);
524 * Function irlmp_connect_response (handle, userdata)
526 * Service user is accepting connection
529 int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata)
531 ASSERT(self != NULL, return -1;);
532 ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
533 ASSERT(userdata != NULL, return -1;);
535 set_bit(0, &self->connected); /* TRUE */
537 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
538 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
540 /* Make room for MUX control header (3 bytes) */
541 ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;);
542 skb_push(userdata, LMP_CONTROL_HEADER);
544 irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
546 /* Drop reference count - see irlap_data_request(). */
547 dev_kfree_skb(userdata);
549 return 0;
553 * Function irlmp_connect_confirm (handle, skb)
555 * LSAP connection confirmed peer device!
557 void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
559 int max_header_size;
560 int lap_header_size;
561 int max_seg_size;
563 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
565 ASSERT(skb != NULL, return;);
566 ASSERT(self != NULL, return;);
567 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
568 ASSERT(self->lap != NULL, return;);
570 self->qos = *self->lap->qos;
572 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
573 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
574 max_header_size = LMP_HEADER + lap_header_size;
576 IRDA_DEBUG(2, "%s(), max_header_size=%d\n",
577 __FUNCTION__, max_header_size);
579 /* Hide LMP_CONTROL_HEADER header from layer above */
580 skb_pull(skb, LMP_CONTROL_HEADER);
582 if (self->notify.connect_confirm) {
583 /* Don't forget to refcount it - see irlap_driver_rcv() */
584 skb_get(skb);
585 self->notify.connect_confirm(self->notify.instance, self,
586 &self->qos, max_seg_size,
587 max_header_size, skb);
592 * Function irlmp_dup (orig, instance)
594 * Duplicate LSAP, can be used by servers to confirm a connection on a
595 * new LSAP so it can keep listening on the old one.
598 struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
600 struct lsap_cb *new;
601 unsigned long flags;
603 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
605 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
607 /* Only allowed to duplicate unconnected LSAP's */
608 if (!hashbin_find(irlmp->unconnected_lsaps, (long) orig, NULL)) {
609 IRDA_DEBUG(0, "%s(), unable to find LSAP\n", __FUNCTION__);
610 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
611 flags);
612 return NULL;
614 /* Allocate a new instance */
615 new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
616 if (!new) {
617 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
618 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
619 flags);
620 return NULL;
622 /* Dup */
623 memcpy(new, orig, sizeof(struct lsap_cb));
624 /* new->lap = orig->lap; => done in the memcpy() */
625 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
626 new->conn_skb = NULL;
628 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
630 /* Not everything is the same */
631 new->notify.instance = instance;
633 init_timer(&new->watchdog_timer);
635 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new,
636 (long) new, NULL);
638 /* Make sure that we invalidate the cache */
639 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
640 new->lap->cache.valid = FALSE;
641 #endif /* CONFIG_IRDA_CACHE_LAST_LSAP */
643 return new;
647 * Function irlmp_disconnect_request (handle, userdata)
649 * The service user is requesting disconnection, this will not remove the
650 * LSAP, but only mark it as disconnected
652 int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
654 struct lsap_cb *lsap;
656 ASSERT(self != NULL, return -1;);
657 ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
658 ASSERT(userdata != NULL, return -1;);
660 /* Already disconnected ?
661 * There is a race condition between irlmp_disconnect_indication()
662 * and us that might mess up the hashbins below. This fixes it.
663 * Jean II */
664 if (! test_and_clear_bit(0, &self->connected)) {
665 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
666 dev_kfree_skb(userdata);
667 return -1;
670 skb_push(userdata, LMP_CONTROL_HEADER);
673 * Do the event before the other stuff since we must know
674 * which lap layer that the frame should be transmitted on
676 irlmp_do_lsap_event(self, LM_DISCONNECT_REQUEST, userdata);
678 /* Drop reference count - see irlap_data_request(). */
679 dev_kfree_skb(userdata);
682 * Remove LSAP from list of connected LSAPs for the particular link
683 * and insert it into the list of unconnected LSAPs
685 ASSERT(self->lap != NULL, return -1;);
686 ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
687 ASSERT(self->lap->lsaps != NULL, return -1;);
689 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
690 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
691 self->lap->cache.valid = FALSE;
692 #endif
694 ASSERT(lsap != NULL, return -1;);
695 ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
696 ASSERT(lsap == self, return -1;);
698 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
699 (long) self, NULL);
701 /* Reset some values */
702 self->dlsap_sel = LSAP_ANY;
703 self->lap = NULL;
705 return 0;
709 * Function irlmp_disconnect_indication (reason, userdata)
711 * LSAP is being closed!
713 void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
714 struct sk_buff *skb)
716 struct lsap_cb *lsap;
718 IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, lmp_reasons[reason]);
719 ASSERT(self != NULL, return;);
720 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
722 IRDA_DEBUG(3, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
723 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
725 /* Already disconnected ?
726 * There is a race condition between irlmp_disconnect_request()
727 * and us that might mess up the hashbins below. This fixes it.
728 * Jean II */
729 if (! test_and_clear_bit(0, &self->connected)) {
730 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
731 return;
735 * Remove association between this LSAP and the link it used
737 ASSERT(self->lap != NULL, return;);
738 ASSERT(self->lap->lsaps != NULL, return;);
740 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
741 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
742 self->lap->cache.valid = FALSE;
743 #endif
745 ASSERT(lsap != NULL, return;);
746 ASSERT(lsap == self, return;);
747 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap,
748 (long) lsap, NULL);
750 self->dlsap_sel = LSAP_ANY;
751 self->lap = NULL;
754 * Inform service user
756 if (self->notify.disconnect_indication) {
757 /* Don't forget to refcount it - see irlap_driver_rcv(). */
758 if(skb)
759 skb_get(skb);
760 self->notify.disconnect_indication(self->notify.instance,
761 self, reason, skb);
762 } else {
763 IRDA_DEBUG(0, "%s(), no handler\n", __FUNCTION__);
768 * Function irlmp_do_expiry (void)
770 * Do a cleanup of the discovery log (remove old entries)
772 * Note : separate from irlmp_do_discovery() so that we can handle
773 * passive discovery properly.
775 void irlmp_do_expiry()
777 struct lap_cb *lap;
780 * Expire discovery on all links which are *not* connected.
781 * On links which are connected, we can't do discovery
782 * anymore and can't refresh the log, so we freeze the
783 * discovery log to keep info about the device we are
784 * connected to.
785 * This info is mandatory if we want irlmp_connect_request()
786 * to work properly. - Jean II
788 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
789 while (lap != NULL) {
790 ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
792 if (lap->lap_state == LAP_STANDBY) {
793 /* Expire discoveries discovered on this link */
794 irlmp_expire_discoveries(irlmp->cachelog, lap->saddr,
795 FALSE);
797 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
802 * Function irlmp_do_discovery (nslots)
804 * Do some discovery on all links
806 * Note : log expiry is done above.
808 void irlmp_do_discovery(int nslots)
810 struct lap_cb *lap;
812 /* Make sure the value is sane */
813 if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){
814 WARNING("%s: invalid value for number of slots!\n",
815 __FUNCTION__);
816 nslots = sysctl_discovery_slots = 8;
819 /* Construct new discovery info to be used by IrLAP, */
820 u16ho(irlmp->discovery_cmd.data.hints) = irlmp->hints.word;
823 * Set character set for device name (we use ASCII), and
824 * copy device name. Remember to make room for a \0 at the
825 * end
827 irlmp->discovery_cmd.data.charset = CS_ASCII;
828 strncpy(irlmp->discovery_cmd.data.info, sysctl_devname,
829 NICKNAME_MAX_LEN);
830 irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.data.info);
831 irlmp->discovery_cmd.nslots = nslots;
834 * Try to send discovery packets on all links
836 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
837 while (lap != NULL) {
838 ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
840 if (lap->lap_state == LAP_STANDBY) {
841 /* Try to discover */
842 irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST,
843 NULL);
845 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
850 * Function irlmp_discovery_request (nslots)
852 * Do a discovery of devices in front of the computer
854 * If the caller has registered a client discovery callback, this
855 * allow him to receive the full content of the discovery log through
856 * this callback (as normally he will receive only new discoveries).
858 void irlmp_discovery_request(int nslots)
860 /* Return current cached discovery log (in full) */
861 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_LOG);
864 * Start a single discovery operation if discovery is not already
865 * running
867 if (!sysctl_discovery) {
868 /* Check if user wants to override the default */
869 if (nslots == DISCOVERY_DEFAULT_SLOTS)
870 nslots = sysctl_discovery_slots;
872 irlmp_do_discovery(nslots);
873 /* Note : we never do expiry here. Expiry will run on the
874 * discovery timer regardless of the state of sysctl_discovery
875 * Jean II */
880 * Function irlmp_get_discoveries (pn, mask, slots)
882 * Return the current discovery log
884 * If discovery is not enabled, you should call this function again
885 * after 1 or 2 seconds (i.e. after discovery has been done).
887 struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
889 /* If discovery is not enabled, it's likely that the discovery log
890 * will be empty. So, we trigger a single discovery, so that next
891 * time the user call us there might be some results in the log.
892 * Jean II
894 if (!sysctl_discovery) {
895 /* Check if user wants to override the default */
896 if (nslots == DISCOVERY_DEFAULT_SLOTS)
897 nslots = sysctl_discovery_slots;
899 /* Start discovery - will complete sometime later */
900 irlmp_do_discovery(nslots);
901 /* Note : we never do expiry here. Expiry will run on the
902 * discovery timer regardless of the state of sysctl_discovery
903 * Jean II */
906 /* Return current cached discovery log */
907 return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE));
911 * Function irlmp_notify_client (log)
913 * Notify all about discovered devices
915 * Clients registered with IrLMP are :
916 * o IrComm
917 * o IrLAN
918 * o Any socket (in any state - ouch, that may be a lot !)
919 * The client may have defined a callback to be notified in case of
920 * partial/selective discovery based on the hints that it passed to IrLMP.
922 static inline void
923 irlmp_notify_client(irlmp_client_t *client,
924 hashbin_t *log, DISCOVERY_MODE mode)
926 discinfo_t *discoveries; /* Copy of the discovery log */
927 int number; /* Number of nodes in the log */
928 int i;
930 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
932 /* Check if client wants or not partial/selective log (optimisation) */
933 if (!client->disco_callback)
934 return;
937 * Locking notes :
938 * the old code was manipulating the log directly, which was
939 * very racy. Now, we use copy_discoveries, that protects
940 * itself while dumping the log for us.
941 * The overhead of the copy is compensated by the fact that
942 * we only pass new discoveries in normal mode and don't
943 * pass the same old entry every 3s to the caller as we used
944 * to do (virtual function calling is expensive).
945 * Jean II
949 * Now, check all discovered devices (if any), and notify client
950 * only about the services that the client is interested in
951 * We also notify only about the new devices unless the caller
952 * explicitly request a dump of the log. Jean II
954 discoveries = irlmp_copy_discoveries(log, &number,
955 client->hint_mask.word,
956 (mode == DISCOVERY_LOG));
957 /* Check if the we got some results */
958 if (discoveries == NULL)
959 return; /* No nodes discovered */
961 /* Pass all entries to the listener */
962 for(i = 0; i < number; i++)
963 client->disco_callback(&(discoveries[i]), mode, client->priv);
965 /* Free up our buffer */
966 kfree(discoveries);
970 * Function irlmp_discovery_confirm ( self, log)
972 * Some device(s) answered to our discovery request! Check to see which
973 * device it is, and give indication to the client(s)
976 void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
978 irlmp_client_t *client;
979 irlmp_client_t *client_next;
981 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
983 ASSERT(log != NULL, return;);
985 if (!(HASHBIN_GET_SIZE(log)))
986 return;
988 /* For each client - notify callback may touch client list */
989 client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
990 while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
991 (void *) &client_next) ) {
992 /* Check if we should notify client */
993 irlmp_notify_client(client, log, mode);
995 client = client_next;
1000 * Function irlmp_discovery_expiry (expiry)
1002 * This device is no longer been discovered, and therefore it is being
1003 * purged from the discovery log. Inform all clients who have
1004 * registered for this event...
1006 * Note : called exclusively from discovery.c
1007 * Note : this is no longer called under discovery spinlock, so the
1008 * client can do whatever he wants in the callback.
1010 void irlmp_discovery_expiry(discinfo_t *expiries, int number)
1012 irlmp_client_t *client;
1013 irlmp_client_t *client_next;
1014 int i;
1016 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
1018 ASSERT(expiries != NULL, return;);
1020 /* For each client - notify callback may touch client list */
1021 client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
1022 while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
1023 (void *) &client_next) ) {
1025 /* Pass all entries to the listener */
1026 for(i = 0; i < number; i++) {
1027 /* Check if we should notify client */
1028 if ((client->expir_callback) &&
1029 (client->hint_mask.word & u16ho(expiries[i].hints)
1030 & 0x7f7f) )
1031 client->expir_callback(&(expiries[i]),
1032 EXPIRY_TIMEOUT,
1033 client->priv);
1036 /* Next client */
1037 client = client_next;
1042 * Function irlmp_get_discovery_response ()
1044 * Used by IrLAP to get the discovery info it needs when answering
1045 * discovery requests by other devices.
1047 discovery_t *irlmp_get_discovery_response()
1049 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1051 ASSERT(irlmp != NULL, return NULL;);
1053 u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
1056 * Set character set for device name (we use ASCII), and
1057 * copy device name. Remember to make room for a \0 at the
1058 * end
1060 irlmp->discovery_rsp.data.charset = CS_ASCII;
1062 strncpy(irlmp->discovery_rsp.data.info, sysctl_devname,
1063 NICKNAME_MAX_LEN);
1064 irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.data.info);
1066 return &irlmp->discovery_rsp;
1070 * Function irlmp_data_request (self, skb)
1072 * Send some data to peer device
1074 * Note on skb management :
1075 * After calling the lower layers of the IrDA stack, we always
1076 * kfree() the skb, which drop the reference count (and potentially
1077 * destroy it).
1078 * IrLMP and IrLAP may queue the packet, and in those cases will need
1079 * to use skb_get() to keep it around.
1080 * Jean II
1082 int irlmp_data_request(struct lsap_cb *self, struct sk_buff *userdata)
1084 int ret;
1086 ASSERT(self != NULL, return -1;);
1087 ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
1089 /* Make room for MUX header */
1090 ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;);
1091 skb_push(userdata, LMP_HEADER);
1093 ret = irlmp_do_lsap_event(self, LM_DATA_REQUEST, userdata);
1095 /* Drop reference count - see irlap_data_request(). */
1096 dev_kfree_skb(userdata);
1098 return ret;
1102 * Function irlmp_data_indication (handle, skb)
1104 * Got data from LAP layer so pass it up to upper layer
1107 void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb)
1109 /* Hide LMP header from layer above */
1110 skb_pull(skb, LMP_HEADER);
1112 if (self->notify.data_indication) {
1113 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1114 skb_get(skb);
1115 self->notify.data_indication(self->notify.instance, self, skb);
1120 * Function irlmp_udata_request (self, skb)
1122 int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *userdata)
1124 int ret;
1126 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1128 ASSERT(userdata != NULL, return -1;);
1130 /* Make room for MUX header */
1131 ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;);
1132 skb_push(userdata, LMP_HEADER);
1134 ret = irlmp_do_lsap_event(self, LM_UDATA_REQUEST, userdata);
1136 /* Drop reference count - see irlap_data_request(). */
1137 dev_kfree_skb(userdata);
1139 return ret;
1143 * Function irlmp_udata_indication (self, skb)
1145 * Send unreliable data (but still within the connection)
1148 void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
1150 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1152 ASSERT(self != NULL, return;);
1153 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1154 ASSERT(skb != NULL, return;);
1156 /* Hide LMP header from layer above */
1157 skb_pull(skb, LMP_HEADER);
1159 if (self->notify.udata_indication) {
1160 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1161 skb_get(skb);
1162 self->notify.udata_indication(self->notify.instance, self,
1163 skb);
1168 * Function irlmp_connless_data_request (self, skb)
1170 #ifdef CONFIG_IRDA_ULTRA
1171 int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata)
1173 struct sk_buff *clone_skb;
1174 struct lap_cb *lap;
1176 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1178 ASSERT(userdata != NULL, return -1;);
1180 /* Make room for MUX and PID header */
1181 ASSERT(skb_headroom(userdata) >= LMP_HEADER+LMP_PID_HEADER,
1182 return -1;);
1184 /* Insert protocol identifier */
1185 skb_push(userdata, LMP_PID_HEADER);
1186 userdata->data[0] = self->pid;
1188 /* Connectionless sockets must use 0x70 */
1189 skb_push(userdata, LMP_HEADER);
1190 userdata->data[0] = userdata->data[1] = LSAP_CONNLESS;
1192 /* Try to send Connectionless packets out on all links */
1193 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1194 while (lap != NULL) {
1195 ASSERT(lap->magic == LMP_LAP_MAGIC, return -1;);
1197 clone_skb = skb_clone(userdata, GFP_ATOMIC);
1198 if (!clone_skb) {
1199 dev_kfree_skb(userdata);
1200 return -ENOMEM;
1203 irlap_unitdata_request(lap->irlap, clone_skb);
1204 /* irlap_unitdata_request() don't increase refcount,
1205 * so no dev_kfree_skb() - Jean II */
1207 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1209 dev_kfree_skb(userdata);
1211 return 0;
1213 #endif /* CONFIG_IRDA_ULTRA */
1216 * Function irlmp_connless_data_indication (self, skb)
1218 * Receive unreliable data outside any connection. Mostly used by Ultra
1221 #ifdef CONFIG_IRDA_ULTRA
1222 void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb)
1224 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1226 ASSERT(self != NULL, return;);
1227 ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1228 ASSERT(skb != NULL, return;);
1230 /* Hide LMP and PID header from layer above */
1231 skb_pull(skb, LMP_HEADER+LMP_PID_HEADER);
1233 if (self->notify.udata_indication) {
1234 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1235 skb_get(skb);
1236 self->notify.udata_indication(self->notify.instance, self,
1237 skb);
1240 #endif /* CONFIG_IRDA_ULTRA */
1242 void irlmp_status_request(void)
1244 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
1248 * Propagate status indication from LAP to LSAPs (via LMP)
1249 * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb,
1250 * and the event is stateless, therefore we can bypass both state machines
1251 * and send the event direct to the LSAP user.
1252 * Jean II
1254 void irlmp_status_indication(struct lap_cb *self,
1255 LINK_STATUS link, LOCK_STATUS lock)
1257 struct lsap_cb *next;
1258 struct lsap_cb *curr;
1260 /* Send status_indication to all LSAPs using this link */
1261 curr = (struct lsap_cb *) hashbin_get_first( self->lsaps);
1262 while (NULL != hashbin_find_next(self->lsaps, (long) curr, NULL,
1263 (void *) &next) ) {
1264 ASSERT(curr->magic == LMP_LSAP_MAGIC, return;);
1266 * Inform service user if he has requested it
1268 if (curr->notify.status_indication != NULL)
1269 curr->notify.status_indication(curr->notify.instance,
1270 link, lock);
1271 else
1272 IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__);
1274 curr = next;
1279 * Receive flow control indication from LAP.
1280 * LAP want us to send it one more frame. We implement a simple round
1281 * robin scheduler between the active sockets so that we get a bit of
1282 * fairness. Note that the round robin is far from perfect, but it's
1283 * better than nothing.
1284 * We then poll the selected socket so that we can do synchronous
1285 * refilling of IrLAP (which allow to minimise the number of buffers).
1286 * Jean II
1288 void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow)
1290 struct lsap_cb *next;
1291 struct lsap_cb *curr;
1292 int lsap_todo;
1294 ASSERT(self->magic == LMP_LAP_MAGIC, return;);
1295 ASSERT(flow == FLOW_START, return;);
1297 /* Get the number of lsap. That's the only safe way to know
1298 * that we have looped around... - Jean II */
1299 lsap_todo = HASHBIN_GET_SIZE(self->lsaps);
1300 IRDA_DEBUG(4, "%s() : %d lsaps to scan\n", __FUNCTION__, lsap_todo);
1302 /* Poll lsap in order until the queue is full or until we
1303 * tried them all.
1304 * Most often, the current LSAP will have something to send,
1305 * so we will go through this loop only once. - Jean II */
1306 while((lsap_todo--) &&
1307 (IRLAP_GET_TX_QUEUE_LEN(self->irlap) < LAP_HIGH_THRESHOLD)) {
1308 /* Try to find the next lsap we should poll. */
1309 next = self->flow_next;
1310 /* If we have no lsap, restart from first one */
1311 if(next == NULL)
1312 next = (struct lsap_cb *) hashbin_get_first(self->lsaps);
1313 /* Verify current one and find the next one */
1314 curr = hashbin_find_next(self->lsaps, (long) next, NULL,
1315 (void *) &self->flow_next);
1316 /* Uh-oh... Paranoia */
1317 if(curr == NULL)
1318 break;
1319 IRDA_DEBUG(4, "%s() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", __FUNCTION__, curr, next, self->flow_next, lsap_todo, IRLAP_GET_TX_QUEUE_LEN(self->irlap));
1321 /* Inform lsap user that it can send one more packet. */
1322 if (curr->notify.flow_indication != NULL)
1323 curr->notify.flow_indication(curr->notify.instance,
1324 curr, flow);
1325 else
1326 IRDA_DEBUG(1, "%s(), no handler\n", __FUNCTION__);
1330 #if 0
1332 * Function irlmp_hint_to_service (hint)
1334 * Returns a list of all servics contained in the given hint bits. This
1335 * function assumes that the hint bits have the size of two bytes only
1337 __u8 *irlmp_hint_to_service(__u8 *hint)
1339 __u8 *service;
1340 int i = 0;
1343 * Allocate array to store services in. 16 entries should be safe
1344 * since we currently only support 2 hint bytes
1346 service = kmalloc(16, GFP_ATOMIC);
1347 if (!service) {
1348 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1349 return NULL;
1352 if (!hint[0]) {
1353 IRDA_DEBUG(1, "<None>\n");
1354 kfree(service);
1355 return NULL;
1357 if (hint[0] & HINT_PNP)
1358 IRDA_DEBUG(1, "PnP Compatible ");
1359 if (hint[0] & HINT_PDA)
1360 IRDA_DEBUG(1, "PDA/Palmtop ");
1361 if (hint[0] & HINT_COMPUTER)
1362 IRDA_DEBUG(1, "Computer ");
1363 if (hint[0] & HINT_PRINTER) {
1364 IRDA_DEBUG(1, "Printer ");
1365 service[i++] = S_PRINTER;
1367 if (hint[0] & HINT_MODEM)
1368 IRDA_DEBUG(1, "Modem ");
1369 if (hint[0] & HINT_FAX)
1370 IRDA_DEBUG(1, "Fax ");
1371 if (hint[0] & HINT_LAN) {
1372 IRDA_DEBUG(1, "LAN Access ");
1373 service[i++] = S_LAN;
1376 * Test if extension byte exists. This byte will usually be
1377 * there, but this is not really required by the standard.
1378 * (IrLMP p. 29)
1380 if (hint[0] & HINT_EXTENSION) {
1381 if (hint[1] & HINT_TELEPHONY) {
1382 IRDA_DEBUG(1, "Telephony ");
1383 service[i++] = S_TELEPHONY;
1384 } if (hint[1] & HINT_FILE_SERVER)
1385 IRDA_DEBUG(1, "File Server ");
1387 if (hint[1] & HINT_COMM) {
1388 IRDA_DEBUG(1, "IrCOMM ");
1389 service[i++] = S_COMM;
1391 if (hint[1] & HINT_OBEX) {
1392 IRDA_DEBUG(1, "IrOBEX ");
1393 service[i++] = S_OBEX;
1396 IRDA_DEBUG(1, "\n");
1398 /* So that client can be notified about any discovery */
1399 service[i++] = S_ANY;
1401 service[i] = S_END;
1403 return service;
1405 #endif
1407 const __u16 service_hint_mapping[S_END][2] = {
1408 { HINT_PNP, 0 }, /* S_PNP */
1409 { HINT_PDA, 0 }, /* S_PDA */
1410 { HINT_COMPUTER, 0 }, /* S_COMPUTER */
1411 { HINT_PRINTER, 0 }, /* S_PRINTER */
1412 { HINT_MODEM, 0 }, /* S_MODEM */
1413 { HINT_FAX, 0 }, /* S_FAX */
1414 { HINT_LAN, 0 }, /* S_LAN */
1415 { HINT_EXTENSION, HINT_TELEPHONY }, /* S_TELEPHONY */
1416 { HINT_EXTENSION, HINT_COMM }, /* S_COMM */
1417 { HINT_EXTENSION, HINT_OBEX }, /* S_OBEX */
1418 { 0xFF, 0xFF }, /* S_ANY */
1422 * Function irlmp_service_to_hint (service)
1424 * Converts a service type, to a hint bit
1426 * Returns: a 16 bit hint value, with the service bit set
1428 __u16 irlmp_service_to_hint(int service)
1430 __u16_host_order hint;
1432 hint.byte[0] = service_hint_mapping[service][0];
1433 hint.byte[1] = service_hint_mapping[service][1];
1435 return hint.word;
1439 * Function irlmp_register_service (service)
1441 * Register local service with IrLMP
1444 void *irlmp_register_service(__u16 hints)
1446 irlmp_service_t *service;
1448 IRDA_DEBUG(4, "%s(), hints = %04x\n", __FUNCTION__, hints);
1450 /* Make a new registration */
1451 service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
1452 if (!service) {
1453 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1454 return 0;
1456 service->hints.word = hints;
1457 hashbin_insert(irlmp->services, (irda_queue_t *) service,
1458 (long) service, NULL);
1460 irlmp->hints.word |= hints;
1462 return (void *)service;
1466 * Function irlmp_unregister_service (handle)
1468 * Unregister service with IrLMP.
1470 * Returns: 0 on success, -1 on error
1472 int irlmp_unregister_service(void *handle)
1474 irlmp_service_t *service;
1475 unsigned long flags;
1477 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1479 if (!handle)
1480 return -1;
1482 /* Caller may call with invalid handle (it's legal) - Jean II */
1483 service = hashbin_lock_find(irlmp->services, (long) handle, NULL);
1484 if (!service) {
1485 IRDA_DEBUG(1, "%s(), Unknown service!\n", __FUNCTION__);
1486 return -1;
1489 hashbin_remove_this(irlmp->services, (irda_queue_t *) service);
1490 kfree(service);
1492 /* Remove old hint bits */
1493 irlmp->hints.word = 0;
1495 /* Refresh current hint bits */
1496 spin_lock_irqsave(&irlmp->services->hb_spinlock, flags);
1497 service = (irlmp_service_t *) hashbin_get_first(irlmp->services);
1498 while (service) {
1499 irlmp->hints.word |= service->hints.word;
1501 service = (irlmp_service_t *)hashbin_get_next(irlmp->services);
1503 spin_unlock_irqrestore(&irlmp->services->hb_spinlock, flags);
1504 return 0;
1508 * Function irlmp_register_client (hint_mask, callback1, callback2)
1510 * Register a local client with IrLMP
1511 * First callback is selective discovery (based on hints)
1512 * Second callback is for selective discovery expiries
1514 * Returns: handle > 0 on success, 0 on error
1516 void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
1517 DISCOVERY_CALLBACK2 expir_clb, void *priv)
1519 irlmp_client_t *client;
1521 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
1522 ASSERT(irlmp != NULL, return 0;);
1524 /* Make a new registration */
1525 client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
1526 if (!client) {
1527 IRDA_DEBUG( 1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1528 return 0;
1531 /* Register the details */
1532 client->hint_mask.word = hint_mask;
1533 client->disco_callback = disco_clb;
1534 client->expir_callback = expir_clb;
1535 client->priv = priv;
1537 hashbin_insert(irlmp->clients, (irda_queue_t *) client,
1538 (long) client, NULL);
1540 return (void *) client;
1544 * Function irlmp_update_client (handle, hint_mask, callback1, callback2)
1546 * Updates specified client (handle) with possibly new hint_mask and
1547 * callback
1549 * Returns: 0 on success, -1 on error
1551 int irlmp_update_client(void *handle, __u16 hint_mask,
1552 DISCOVERY_CALLBACK1 disco_clb,
1553 DISCOVERY_CALLBACK2 expir_clb, void *priv)
1555 irlmp_client_t *client;
1557 if (!handle)
1558 return -1;
1560 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
1561 if (!client) {
1562 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
1563 return -1;
1566 client->hint_mask.word = hint_mask;
1567 client->disco_callback = disco_clb;
1568 client->expir_callback = expir_clb;
1569 client->priv = priv;
1571 return 0;
1575 * Function irlmp_unregister_client (handle)
1577 * Returns: 0 on success, -1 on error
1580 int irlmp_unregister_client(void *handle)
1582 struct irlmp_client *client;
1584 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1586 if (!handle)
1587 return -1;
1589 /* Caller may call with invalid handle (it's legal) - Jean II */
1590 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
1591 if (!client) {
1592 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
1593 return -1;
1596 IRDA_DEBUG(4, "%s(), removing client!\n", __FUNCTION__);
1597 hashbin_remove_this(irlmp->clients, (irda_queue_t *) client);
1598 kfree(client);
1600 return 0;
1604 * Function irlmp_slsap_inuse (slsap)
1606 * Check if the given source LSAP selector is in use
1608 int irlmp_slsap_inuse(__u8 slsap_sel)
1610 struct lsap_cb *self;
1611 struct lap_cb *lap;
1612 unsigned long flags;
1614 ASSERT(irlmp != NULL, return TRUE;);
1615 ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;);
1616 ASSERT(slsap_sel != LSAP_ANY, return TRUE;);
1618 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1620 #ifdef CONFIG_IRDA_ULTRA
1621 /* Accept all bindings to the connectionless LSAP */
1622 if (slsap_sel == LSAP_CONNLESS)
1623 return FALSE;
1624 #endif /* CONFIG_IRDA_ULTRA */
1626 /* Valid values are between 0 and 127 */
1627 if (slsap_sel > LSAP_MAX)
1628 return TRUE;
1631 * Check if slsap is already in use. To do this we have to loop over
1632 * every IrLAP connection and check every LSAP associated with each
1633 * the connection.
1635 spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
1636 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1637 while (lap != NULL) {
1638 ASSERT(lap->magic == LMP_LAP_MAGIC, return TRUE;);
1640 /* Careful for priority inversions here !
1641 * All other uses of attrib spinlock are independent of
1642 * the object spinlock, so we are safe. Jean II */
1643 spin_lock(&lap->lsaps->hb_spinlock);
1645 self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1646 while (self != NULL) {
1647 ASSERT(self->magic == LMP_LSAP_MAGIC, return TRUE;);
1649 if ((self->slsap_sel == slsap_sel)) {
1650 IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
1651 self->slsap_sel);
1652 return TRUE;
1654 self = (struct lsap_cb*) hashbin_get_next(lap->lsaps);
1656 spin_unlock(&lap->lsaps->hb_spinlock);
1657 /* Next LAP */
1658 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1660 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
1661 return FALSE;
1665 * Function irlmp_find_free_slsap ()
1667 * Find a free source LSAP to use. This function is called if the service
1668 * user has requested a source LSAP equal to LM_ANY
1670 __u8 irlmp_find_free_slsap(void)
1672 __u8 lsap_sel;
1673 int wrapped = 0;
1675 ASSERT(irlmp != NULL, return -1;);
1676 ASSERT(irlmp->magic == LMP_MAGIC, return -1;);
1678 lsap_sel = irlmp->free_lsap_sel++;
1680 /* Check if the new free lsap is really free */
1681 while (irlmp_slsap_inuse(irlmp->free_lsap_sel)) {
1682 irlmp->free_lsap_sel++;
1684 /* Check if we need to wraparound (0x70-0x7f are reserved) */
1685 if (irlmp->free_lsap_sel > LSAP_MAX) {
1686 irlmp->free_lsap_sel = 10;
1688 /* Make sure we terminate the loop */
1689 if (wrapped++)
1690 return 0;
1693 IRDA_DEBUG(4, "%s(), next free lsap_sel=%02x\n",
1694 __FUNCTION__, lsap_sel);
1696 return lsap_sel;
1700 * Function irlmp_convert_lap_reason (lap_reason)
1702 * Converts IrLAP disconnect reason codes to IrLMP disconnect reason
1703 * codes
1706 LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason)
1708 int reason = LM_LAP_DISCONNECT;
1710 switch (lap_reason) {
1711 case LAP_DISC_INDICATION: /* Received a disconnect request from peer */
1712 IRDA_DEBUG( 1, "%s(), LAP_DISC_INDICATION\n", __FUNCTION__);
1713 reason = LM_USER_REQUEST;
1714 break;
1715 case LAP_NO_RESPONSE: /* To many retransmits without response */
1716 IRDA_DEBUG( 1, "%s(), LAP_NO_RESPONSE\n", __FUNCTION__);
1717 reason = LM_LAP_DISCONNECT;
1718 break;
1719 case LAP_RESET_INDICATION:
1720 IRDA_DEBUG( 1, "%s(), LAP_RESET_INDICATION\n", __FUNCTION__);
1721 reason = LM_LAP_RESET;
1722 break;
1723 case LAP_FOUND_NONE:
1724 case LAP_MEDIA_BUSY:
1725 case LAP_PRIMARY_CONFLICT:
1726 IRDA_DEBUG(1, "%s(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n", __FUNCTION__);
1727 reason = LM_CONNECT_FAILURE;
1728 break;
1729 default:
1730 IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n",
1731 __FUNCTION__, lap_reason);
1732 reason = LM_LAP_DISCONNECT;
1733 break;
1736 return reason;
1739 __u32 irlmp_get_saddr(struct lsap_cb *self)
1741 ASSERT(self != NULL, return 0;);
1742 ASSERT(self->lap != NULL, return 0;);
1744 return self->lap->saddr;
1747 __u32 irlmp_get_daddr(struct lsap_cb *self)
1749 ASSERT(self != NULL, return 0;);
1750 ASSERT(self->lap != NULL, return 0;);
1752 return self->lap->daddr;
1755 #ifdef CONFIG_PROC_FS
1757 * Function irlmp_proc_read (buf, start, offset, len, unused)
1759 * Give some info to the /proc file system
1762 int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
1764 struct lsap_cb *self;
1765 struct lap_cb *lap;
1766 unsigned long flags;
1768 ASSERT(irlmp != NULL, return 0;);
1770 len = 0;
1772 len += sprintf( buf+len, "Unconnected LSAPs:\n");
1773 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
1774 self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
1775 while (self != NULL) {
1776 ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
1777 len += sprintf(buf+len, "lsap state: %s, ",
1778 irlsap_state[ self->lsap_state]);
1779 len += sprintf(buf+len,
1780 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1781 self->slsap_sel, self->dlsap_sel);
1782 len += sprintf(buf+len, "(%s)", self->notify.name);
1783 len += sprintf(buf+len, "\n");
1785 self = (struct lsap_cb *) hashbin_get_next(
1786 irlmp->unconnected_lsaps);
1788 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
1790 len += sprintf(buf+len, "\nRegistred Link Layers:\n");
1791 spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
1792 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1793 while (lap != NULL) {
1794 len += sprintf(buf+len, "lap state: %s, ",
1795 irlmp_state[lap->lap_state]);
1797 len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
1798 lap->saddr, lap->daddr);
1799 len += sprintf(buf+len, "num lsaps: %d",
1800 HASHBIN_GET_SIZE(lap->lsaps));
1801 len += sprintf(buf+len, "\n");
1803 /* Careful for priority inversions here !
1804 * All other uses of attrib spinlock are independent of
1805 * the object spinlock, so we are safe. Jean II */
1806 spin_lock(&lap->lsaps->hb_spinlock);
1808 len += sprintf(buf+len, "\n Connected LSAPs:\n");
1809 self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1810 while (self != NULL) {
1811 ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
1812 len += sprintf(buf+len, " lsap state: %s, ",
1813 irlsap_state[ self->lsap_state]);
1814 len += sprintf(buf+len,
1815 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1816 self->slsap_sel, self->dlsap_sel);
1817 len += sprintf(buf+len, "(%s)", self->notify.name);
1818 len += sprintf(buf+len, "\n");
1820 self = (struct lsap_cb *) hashbin_get_next(
1821 lap->lsaps);
1823 spin_unlock(&lap->lsaps->hb_spinlock);
1824 len += sprintf(buf+len, "\n");
1826 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1828 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
1830 return len;
1833 #endif /* PROC_FS */