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 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com> 15 * 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. 20 * 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. 24 * 25 ********************************************************************/ 26 27#include <linux/module.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> 36#include <linux/seq_file.h> 37 38#include <net/irda/irda.h> 39#include <net/irda/timer.h> 40#include <net/irda/qos.h> 41#include <net/irda/irlap.h> 42#include <net/irda/iriap.h> 43#include <net/irda/irlmp.h> 44#include <net/irda/irlmp_frame.h> 45 46#include <asm/unaligned.h> 47 48static __u8 irlmp_find_free_slsap(void); 49static int irlmp_slsap_inuse(__u8 slsap_sel); 50 51/* Master structure */ 52struct irlmp_cb *irlmp = NULL; 53 54/* These can be altered by the sysctl interface */ 55int sysctl_discovery = 0; 56int sysctl_discovery_timeout = 3; /* 3 seconds by default */ 57int sysctl_discovery_slots = 6; /* 6 slots by default */ 58int sysctl_lap_keepalive_time = LM_IDLE_TIMEOUT * 1000 / HZ; 59char sysctl_devname[65]; 60 61const char *irlmp_reasons[] = { 62 "ERROR, NOT USED", 63 "LM_USER_REQUEST", 64 "LM_LAP_DISCONNECT", 65 "LM_CONNECT_FAILURE", 66 "LM_LAP_RESET", 67 "LM_INIT_DISCONNECT", 68 "ERROR, NOT USED", 69}; 70 71/* 72 * Function irlmp_init (void) 73 * 74 * Create (allocate) the main IrLMP structure 75 * 76 */ 77int __init irlmp_init(void) 78{ 79 IRDA_DEBUG(1, "%s()\n", __FUNCTION__); 80 /* Initialize the irlmp structure. */ 81 irlmp = kzalloc( sizeof(struct irlmp_cb), GFP_KERNEL); 82 if (irlmp == NULL) 83 return -ENOMEM; 84 85 irlmp->magic = LMP_MAGIC; 86 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 93 if ((irlmp->clients == NULL) || 94 (irlmp->services == NULL) || 95 (irlmp->links == NULL) || 96 (irlmp->unconnected_lsaps == NULL) || 97 (irlmp->cachelog == NULL)) { 98 return -ENOMEM; 99 } 100 101 spin_lock_init(&irlmp->cachelog->hb_spinlock); 102 103 irlmp->last_lsap_sel = 0x0f; /* Reserved 0x00-0x0f */ 104 strcpy(sysctl_devname, "Linux"); 105 106 /* Do discovery every 3 seconds */ 107 init_timer(&irlmp->discovery_timer); 108 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ); 109 110 return 0; 111} 112 113/* 114 * Function irlmp_cleanup (void) 115 * 116 * Remove IrLMP layer 117 * 118 */ 119void __exit irlmp_cleanup(void) 120{ 121 /* Check for main structure */ 122 IRDA_ASSERT(irlmp != NULL, return;); 123 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return;); 124 125 del_timer(&irlmp->discovery_timer); 126 127 hashbin_delete(irlmp->links, (FREE_FUNC) kfree); 128 hashbin_delete(irlmp->unconnected_lsaps, (FREE_FUNC) kfree); 129 hashbin_delete(irlmp->clients, (FREE_FUNC) kfree); 130 hashbin_delete(irlmp->services, (FREE_FUNC) kfree); 131 hashbin_delete(irlmp->cachelog, (FREE_FUNC) kfree); 132 133 /* De-allocate main structure */ 134 kfree(irlmp); 135 irlmp = NULL; 136} 137 138/* 139 * Function irlmp_open_lsap (slsap, notify) 140 * 141 * Register with IrLMP and create a local LSAP, 142 * returns handle to LSAP. 143 */ 144struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) 145{ 146 struct lsap_cb *self; 147 148 IRDA_ASSERT(notify != NULL, return NULL;); 149 IRDA_ASSERT(irlmp != NULL, return NULL;); 150 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return NULL;); 151 IRDA_ASSERT(notify->instance != NULL, return NULL;); 152 153 /* Does the client care which Source LSAP selector it gets? */ 154 if (slsap_sel == LSAP_ANY) { 155 slsap_sel = irlmp_find_free_slsap(); 156 if (!slsap_sel) 157 return NULL; 158 } else if (irlmp_slsap_inuse(slsap_sel)) 159 return NULL; 160 161 /* Allocate new instance of a LSAP connection */ 162 self = kzalloc(sizeof(struct lsap_cb), GFP_ATOMIC); 163 if (self == NULL) { 164 IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__); 165 return NULL; 166 } 167 168 self->magic = LMP_LSAP_MAGIC; 169 self->slsap_sel = slsap_sel; 170 171 /* Fix connectionless LSAP's */ 172 if (slsap_sel == LSAP_CONNLESS) { 173#ifdef CONFIG_IRDA_ULTRA 174 self->dlsap_sel = LSAP_CONNLESS; 175 self->pid = pid; 176#endif /* CONFIG_IRDA_ULTRA */ 177 } else 178 self->dlsap_sel = LSAP_ANY; 179 /* self->connected = FALSE; -> already NULL via memset() */ 180 181 init_timer(&self->watchdog_timer); 182 183 self->notify = *notify; 184 185 self->lsap_state = LSAP_DISCONNECTED; 186 187 /* Insert into queue of unconnected LSAPs */ 188 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, 189 (long) self, NULL); 190 191 return self; 192} 193EXPORT_SYMBOL(irlmp_open_lsap); 194 195/* 196 * Function __irlmp_close_lsap (self) 197 * 198 * Remove an instance of LSAP 199 */ 200static void __irlmp_close_lsap(struct lsap_cb *self) 201{ 202 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 203 204 IRDA_ASSERT(self != NULL, return;); 205 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 206 207 /* 208 * Set some of the variables to preset values 209 */ 210 self->magic = 0; 211 del_timer(&self->watchdog_timer); /* Important! */ 212 213 if (self->conn_skb) 214 dev_kfree_skb(self->conn_skb); 215 216 kfree(self); 217} 218 219/* 220 * Function irlmp_close_lsap (self) 221 * 222 * Close and remove LSAP 223 * 224 */ 225void irlmp_close_lsap(struct lsap_cb *self) 226{ 227 struct lap_cb *lap; 228 struct lsap_cb *lsap = NULL; 229 230 IRDA_ASSERT(self != NULL, return;); 231 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 232 233 /* 234 * Find out if we should remove this LSAP from a link or from the 235 * list of unconnected lsaps (not associated with a link) 236 */ 237 lap = self->lap; 238 if (lap) { 239 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;); 240 /* We might close a LSAP before it has completed the 241 * connection setup. In those case, higher layers won't 242 * send a proper disconnect request. Harmless, except 243 * that we will forget to close LAP... - Jean II */ 244 if(self->lsap_state != LSAP_DISCONNECTED) { 245 self->lsap_state = LSAP_DISCONNECTED; 246 irlmp_do_lap_event(self->lap, 247 LM_LAP_DISCONNECT_REQUEST, NULL); 248 } 249 /* Now, remove from the link */ 250 lsap = hashbin_remove(lap->lsaps, (long) self, NULL); 251#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 252 lap->cache.valid = FALSE; 253#endif 254 } 255 self->lap = NULL; 256 /* Check if we found the LSAP! If not then try the unconnected lsaps */ 257 if (!lsap) { 258 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self, 259 NULL); 260 } 261 if (!lsap) { 262 IRDA_DEBUG(0, 263 "%s(), Looks like somebody has removed me already!\n", 264 __FUNCTION__); 265 return; 266 } 267 __irlmp_close_lsap(self); 268} 269EXPORT_SYMBOL(irlmp_close_lsap); 270 271/* 272 * Function irlmp_register_irlap (saddr, notify) 273 * 274 * Register IrLAP layer with IrLMP. There is possible to have multiple 275 * instances of the IrLAP layer, each connected to different IrDA ports 276 * 277 */ 278void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) 279{ 280 struct lap_cb *lap; 281 282 IRDA_ASSERT(irlmp != NULL, return;); 283 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return;); 284 IRDA_ASSERT(notify != NULL, return;); 285 286 /* 287 * Allocate new instance of a LSAP connection 288 */ 289 lap = kzalloc(sizeof(struct lap_cb), GFP_KERNEL); 290 if (lap == NULL) { 291 IRDA_ERROR("%s: unable to kmalloc\n", __FUNCTION__); 292 return; 293 } 294 295 lap->irlap = irlap; 296 lap->magic = LMP_LAP_MAGIC; 297 lap->saddr = saddr; 298 lap->daddr = DEV_ADDR_ANY; 299#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 300 lap->cache.valid = FALSE; 301#endif 302 lap->lsaps = hashbin_new(HB_LOCK); 303 if (lap->lsaps == NULL) { 304 IRDA_WARNING("%s(), unable to kmalloc lsaps\n", __FUNCTION__); 305 kfree(lap); 306 return; 307 } 308 309 lap->lap_state = LAP_STANDBY; 310 311 init_timer(&lap->idle_timer); 312 313 /* 314 * Insert into queue of LMP links 315 */ 316 hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL); 317 318 /* 319 * We set only this variable so IrLAP can tell us on which link the 320 * different events happened on 321 */ 322 irda_notify_init(notify); 323 notify->instance = lap; 324} 325 326/* 327 * Function irlmp_unregister_irlap (saddr) 328 * 329 * IrLAP layer has been removed! 330 * 331 */ 332void irlmp_unregister_link(__u32 saddr) 333{ 334 struct lap_cb *link; 335 336 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 337 338 /* We must remove ourselves from the hashbin *first*. This ensure 339 * that no more LSAPs will be open on this link and no discovery 340 * will be triggered anymore. Jean II */ 341 link = hashbin_remove(irlmp->links, saddr, NULL); 342 if (link) { 343 IRDA_ASSERT(link->magic == LMP_LAP_MAGIC, return;); 344 345 /* Kill all the LSAPs on this link. Jean II */ 346 link->reason = LAP_DISC_INDICATION; 347 link->daddr = DEV_ADDR_ANY; 348 irlmp_do_lap_event(link, LM_LAP_DISCONNECT_INDICATION, NULL); 349 350 /* Remove all discoveries discovered at this link */ 351 irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE); 352 353 /* Final cleanup */ 354 del_timer(&link->idle_timer); 355 link->magic = 0; 356 kfree(link); 357 } 358} 359 360/* 361 * Function irlmp_connect_request (handle, dlsap, userdata) 362 * 363 * Connect with a peer LSAP 364 * 365 */ 366int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, 367 __u32 saddr, __u32 daddr, 368 struct qos_info *qos, struct sk_buff *userdata) 369{ 370 struct sk_buff *tx_skb = userdata; 371 struct lap_cb *lap; 372 struct lsap_cb *lsap; 373 int ret; 374 375 IRDA_ASSERT(self != NULL, return -EBADR;); 376 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;); 377 378 IRDA_DEBUG(2, 379 "%s(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n", 380 __FUNCTION__, self->slsap_sel, dlsap_sel, saddr, daddr); 381 382 if (test_bit(0, &self->connected)) { 383 ret = -EISCONN; 384 goto err; 385 } 386 387 /* Client must supply destination device address */ 388 if (!daddr) { 389 ret = -EINVAL; 390 goto err; 391 } 392 393 /* Any userdata? */ 394 if (tx_skb == NULL) { 395 tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC); 396 if (!tx_skb) 397 return -ENOMEM; 398 399 skb_reserve(tx_skb, LMP_MAX_HEADER); 400 } 401 402 /* Make room for MUX control header (3 bytes) */ 403 IRDA_ASSERT(skb_headroom(tx_skb) >= LMP_CONTROL_HEADER, return -1;); 404 skb_push(tx_skb, LMP_CONTROL_HEADER); 405 406 self->dlsap_sel = dlsap_sel; 407 408 /* 409 * Find the link to where we should try to connect since there may 410 * be more than one IrDA port on this machine. If the client has 411 * passed us the saddr (and already knows which link to use), then 412 * we use that to find the link, if not then we have to look in the 413 * discovery log and check if any of the links has discovered a 414 * device with the given daddr 415 */ 416 if ((!saddr) || (saddr == DEV_ADDR_ANY)) { 417 discovery_t *discovery; 418 unsigned long flags; 419 420 spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, flags); 421 if (daddr != DEV_ADDR_ANY) 422 discovery = hashbin_find(irlmp->cachelog, daddr, NULL); 423 else { 424 IRDA_DEBUG(2, "%s(), no daddr\n", __FUNCTION__); 425 discovery = (discovery_t *) 426 hashbin_get_first(irlmp->cachelog); 427 } 428 429 if (discovery) { 430 saddr = discovery->data.saddr; 431 daddr = discovery->data.daddr; 432 } 433 spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, flags); 434 } 435 lap = hashbin_lock_find(irlmp->links, saddr, NULL); 436 if (lap == NULL) { 437 IRDA_DEBUG(1, "%s(), Unable to find a usable link!\n", __FUNCTION__); 438 ret = -EHOSTUNREACH; 439 goto err; 440 } 441 442 /* Check if LAP is disconnected or already connected */ 443 if (lap->daddr == DEV_ADDR_ANY) 444 lap->daddr = daddr; 445 else if (lap->daddr != daddr) { 446 /* Check if some LSAPs are active on this LAP */ 447 if (HASHBIN_GET_SIZE(lap->lsaps) == 0) { 448 /* No active connection, but LAP hasn't been 449 * disconnected yet (waiting for timeout in LAP). 450 * Maybe we could give LAP a bit of help in this case. 451 */ 452 IRDA_DEBUG(0, "%s(), sorry, but I'm waiting for LAP to timeout!\n", __FUNCTION__); 453 ret = -EAGAIN; 454 goto err; 455 } 456 457 /* LAP is already connected to a different node, and LAP 458 * can only talk to one node at a time */ 459 IRDA_DEBUG(0, "%s(), sorry, but link is busy!\n", __FUNCTION__); 460 ret = -EBUSY; 461 goto err; 462 } 463 464 self->lap = lap; 465 466 /* 467 * Remove LSAP from list of unconnected LSAPs and insert it into the 468 * list of connected LSAPs for the particular link 469 */ 470 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self, NULL); 471 472 IRDA_ASSERT(lsap != NULL, return -1;); 473 IRDA_ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); 474 IRDA_ASSERT(lsap->lap != NULL, return -1;); 475 IRDA_ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;); 476 477 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (long) self, 478 NULL); 479 480 set_bit(0, &self->connected); /* TRUE */ 481 482 /* 483 * User supplied qos specifications? 484 */ 485 if (qos) 486 self->qos = *qos; 487 488 irlmp_do_lsap_event(self, LM_CONNECT_REQUEST, tx_skb); 489 490 /* Drop reference count - see irlap_data_request(). */ 491 dev_kfree_skb(tx_skb); 492 493 return 0; 494 495err: 496 /* Cleanup */ 497 if(tx_skb) 498 dev_kfree_skb(tx_skb); 499 return ret; 500} 501EXPORT_SYMBOL(irlmp_connect_request); 502 503/* 504 * Function irlmp_connect_indication (self) 505 * 506 * Incoming connection 507 * 508 */ 509void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb) 510{ 511 int max_seg_size; 512 int lap_header_size; 513 int max_header_size; 514 515 IRDA_ASSERT(self != NULL, return;); 516 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 517 IRDA_ASSERT(skb != NULL, return;); 518 IRDA_ASSERT(self->lap != NULL, return;); 519 520 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n", 521 __FUNCTION__, self->slsap_sel, self->dlsap_sel); 522 523 /* Note : self->lap is set in irlmp_link_data_indication(), 524 * (case CONNECT_CMD:) because we have no way to set it here. 525 * Similarly, self->dlsap_sel is usually set in irlmp_find_lsap(). 526 * Jean II */ 527 528 self->qos = *self->lap->qos; 529 530 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER; 531 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap); 532 max_header_size = LMP_HEADER + lap_header_size; 533 534 /* Hide LMP_CONTROL_HEADER header from layer above */ 535 skb_pull(skb, LMP_CONTROL_HEADER); 536 537 if (self->notify.connect_indication) { 538 /* Don't forget to refcount it - see irlap_driver_rcv(). */ 539 skb_get(skb); 540 self->notify.connect_indication(self->notify.instance, self, 541 &self->qos, max_seg_size, 542 max_header_size, skb); 543 } 544} 545 546/* 547 * Function irlmp_connect_response (handle, userdata) 548 * 549 * Service user is accepting connection 550 * 551 */ 552int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata) 553{ 554 IRDA_ASSERT(self != NULL, return -1;); 555 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); 556 IRDA_ASSERT(userdata != NULL, return -1;); 557 558 /* We set the connected bit and move the lsap to the connected list 559 * in the state machine itself. Jean II */ 560 561 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n", 562 __FUNCTION__, self->slsap_sel, self->dlsap_sel); 563 564 /* Make room for MUX control header (3 bytes) */ 565 IRDA_ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;); 566 skb_push(userdata, LMP_CONTROL_HEADER); 567 568 irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata); 569 570 /* Drop reference count - see irlap_data_request(). */ 571 dev_kfree_skb(userdata); 572 573 return 0; 574} 575EXPORT_SYMBOL(irlmp_connect_response); 576 577/* 578 * Function irlmp_connect_confirm (handle, skb) 579 * 580 * LSAP connection confirmed peer device! 581 */ 582void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) 583{ 584 int max_header_size; 585 int lap_header_size; 586 int max_seg_size; 587 588 IRDA_DEBUG(3, "%s()\n", __FUNCTION__); 589 590 IRDA_ASSERT(skb != NULL, return;); 591 IRDA_ASSERT(self != NULL, return;); 592 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 593 IRDA_ASSERT(self->lap != NULL, return;); 594 595 self->qos = *self->lap->qos; 596 597 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER; 598 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap); 599 max_header_size = LMP_HEADER + lap_header_size; 600 601 IRDA_DEBUG(2, "%s(), max_header_size=%d\n", 602 __FUNCTION__, max_header_size); 603 604 /* Hide LMP_CONTROL_HEADER header from layer above */ 605 skb_pull(skb, LMP_CONTROL_HEADER); 606 607 if (self->notify.connect_confirm) { 608 /* Don't forget to refcount it - see irlap_driver_rcv() */ 609 skb_get(skb); 610 self->notify.connect_confirm(self->notify.instance, self, 611 &self->qos, max_seg_size, 612 max_header_size, skb); 613 } 614} 615 616/* 617 * Function irlmp_dup (orig, instance) 618 * 619 * Duplicate LSAP, can be used by servers to confirm a connection on a 620 * new LSAP so it can keep listening on the old one. 621 * 622 */ 623struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) 624{ 625 struct lsap_cb *new; 626 unsigned long flags; 627 628 IRDA_DEBUG(1, "%s()\n", __FUNCTION__); 629 630 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags); 631 632 /* Only allowed to duplicate unconnected LSAP's, and only LSAPs 633 * that have received a connect indication. Jean II */ 634 if ((!hashbin_find(irlmp->unconnected_lsaps, (long) orig, NULL)) || 635 (orig->lap == NULL)) { 636 IRDA_DEBUG(0, "%s(), invalid LSAP (wrong state)\n", 637 __FUNCTION__); 638 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, 639 flags); 640 return NULL; 641 } 642 643 /* Allocate a new instance */ 644 new = kmemdup(orig, sizeof(*new), GFP_ATOMIC); 645 if (!new) { 646 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__); 647 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, 648 flags); 649 return NULL; 650 } 651 /* new->lap = orig->lap; => done in the memcpy() */ 652 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */ 653 new->conn_skb = NULL; 654 655 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags); 656 657 /* Not everything is the same */ 658 new->notify.instance = instance; 659 660 init_timer(&new->watchdog_timer); 661 662 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, 663 (long) new, NULL); 664 665#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 666 /* Make sure that we invalidate the LSAP cache */ 667 new->lap->cache.valid = FALSE; 668#endif /* CONFIG_IRDA_CACHE_LAST_LSAP */ 669 670 return new; 671} 672 673/* 674 * Function irlmp_disconnect_request (handle, userdata) 675 * 676 * The service user is requesting disconnection, this will not remove the 677 * LSAP, but only mark it as disconnected 678 */ 679int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) 680{ 681 struct lsap_cb *lsap; 682 683 IRDA_ASSERT(self != NULL, return -1;); 684 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); 685 IRDA_ASSERT(userdata != NULL, return -1;); 686 687 /* Already disconnected ? 688 * There is a race condition between irlmp_disconnect_indication() 689 * and us that might mess up the hashbins below. This fixes it. 690 * Jean II */ 691 if (! test_and_clear_bit(0, &self->connected)) { 692 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__); 693 dev_kfree_skb(userdata); 694 return -1; 695 } 696 697 skb_push(userdata, LMP_CONTROL_HEADER); 698 699 /* 700 * Do the event before the other stuff since we must know 701 * which lap layer that the frame should be transmitted on 702 */ 703 irlmp_do_lsap_event(self, LM_DISCONNECT_REQUEST, userdata); 704 705 /* Drop reference count - see irlap_data_request(). */ 706 dev_kfree_skb(userdata); 707 708 /* 709 * Remove LSAP from list of connected LSAPs for the particular link 710 * and insert it into the list of unconnected LSAPs 711 */ 712 IRDA_ASSERT(self->lap != NULL, return -1;); 713 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;); 714 IRDA_ASSERT(self->lap->lsaps != NULL, return -1;); 715 716 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL); 717#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 718 self->lap->cache.valid = FALSE; 719#endif 720 721 IRDA_ASSERT(lsap != NULL, return -1;); 722 IRDA_ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); 723 IRDA_ASSERT(lsap == self, return -1;); 724 725 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, 726 (long) self, NULL); 727 728 /* Reset some values */ 729 self->dlsap_sel = LSAP_ANY; 730 self->lap = NULL; 731 732 return 0; 733} 734EXPORT_SYMBOL(irlmp_disconnect_request); 735 736/* 737 * Function irlmp_disconnect_indication (reason, userdata) 738 * 739 * LSAP is being closed! 740 */ 741void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, 742 struct sk_buff *skb) 743{ 744 struct lsap_cb *lsap; 745 746 IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, irlmp_reasons[reason]); 747 IRDA_ASSERT(self != NULL, return;); 748 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 749 750 IRDA_DEBUG(3, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n", 751 __FUNCTION__, self->slsap_sel, self->dlsap_sel); 752 753 /* Already disconnected ? 754 * There is a race condition between irlmp_disconnect_request() 755 * and us that might mess up the hashbins below. This fixes it. 756 * Jean II */ 757 if (! test_and_clear_bit(0, &self->connected)) { 758 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__); 759 return; 760 } 761 762 /* 763 * Remove association between this LSAP and the link it used 764 */ 765 IRDA_ASSERT(self->lap != NULL, return;); 766 IRDA_ASSERT(self->lap->lsaps != NULL, return;); 767 768 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL); 769#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 770 self->lap->cache.valid = FALSE; 771#endif 772 773 IRDA_ASSERT(lsap != NULL, return;); 774 IRDA_ASSERT(lsap == self, return;); 775 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, 776 (long) lsap, NULL); 777 778 self->dlsap_sel = LSAP_ANY; 779 self->lap = NULL; 780 781 /* 782 * Inform service user 783 */ 784 if (self->notify.disconnect_indication) { 785 /* Don't forget to refcount it - see irlap_driver_rcv(). */ 786 if(skb) 787 skb_get(skb); 788 self->notify.disconnect_indication(self->notify.instance, 789 self, reason, skb); 790 } else { 791 IRDA_DEBUG(0, "%s(), no handler\n", __FUNCTION__); 792 } 793} 794 795/* 796 * Function irlmp_do_expiry (void) 797 * 798 * Do a cleanup of the discovery log (remove old entries) 799 * 800 * Note : separate from irlmp_do_discovery() so that we can handle 801 * passive discovery properly. 802 */ 803void irlmp_do_expiry(void) 804{ 805 struct lap_cb *lap; 806 807 /* 808 * Expire discovery on all links which are *not* connected. 809 * On links which are connected, we can't do discovery 810 * anymore and can't refresh the log, so we freeze the 811 * discovery log to keep info about the device we are 812 * connected to. 813 * This info is mandatory if we want irlmp_connect_request() 814 * to work properly. - Jean II 815 */ 816 lap = (struct lap_cb *) hashbin_get_first(irlmp->links); 817 while (lap != NULL) { 818 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;); 819 820 if (lap->lap_state == LAP_STANDBY) { 821 /* Expire discoveries discovered on this link */ 822 irlmp_expire_discoveries(irlmp->cachelog, lap->saddr, 823 FALSE); 824 } 825 lap = (struct lap_cb *) hashbin_get_next(irlmp->links); 826 } 827} 828 829/* 830 * Function irlmp_do_discovery (nslots) 831 * 832 * Do some discovery on all links 833 * 834 * Note : log expiry is done above. 835 */ 836void irlmp_do_discovery(int nslots) 837{ 838 struct lap_cb *lap; 839 __u16 *data_hintsp; 840 841 /* Make sure the value is sane */ 842 if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){ 843 IRDA_WARNING("%s: invalid value for number of slots!\n", 844 __FUNCTION__); 845 nslots = sysctl_discovery_slots = 8; 846 } 847 848 /* Construct new discovery info to be used by IrLAP, */ 849 data_hintsp = (__u16 *) irlmp->discovery_cmd.data.hints; 850 put_unaligned(irlmp->hints.word, data_hintsp); 851 852 /* 853 * Set character set for device name (we use ASCII), and 854 * copy device name. Remember to make room for a \0 at the 855 * end 856 */ 857 irlmp->discovery_cmd.data.charset = CS_ASCII; 858 strncpy(irlmp->discovery_cmd.data.info, sysctl_devname, 859 NICKNAME_MAX_LEN); 860 irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.data.info); 861 irlmp->discovery_cmd.nslots = nslots; 862 863 /* 864 * Try to send discovery packets on all links 865 */ 866 lap = (struct lap_cb *) hashbin_get_first(irlmp->links); 867 while (lap != NULL) { 868 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;); 869 870 if (lap->lap_state == LAP_STANDBY) { 871 /* Try to discover */ 872 irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST, 873 NULL); 874 } 875 lap = (struct lap_cb *) hashbin_get_next(irlmp->links); 876 } 877} 878 879/* 880 * Function irlmp_discovery_request (nslots) 881 * 882 * Do a discovery of devices in front of the computer 883 * 884 * If the caller has registered a client discovery callback, this 885 * allow him to receive the full content of the discovery log through 886 * this callback (as normally he will receive only new discoveries). 887 */ 888void irlmp_discovery_request(int nslots) 889{ 890 /* Return current cached discovery log (in full) */ 891 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_LOG); 892 893 /* 894 * Start a single discovery operation if discovery is not already 895 * running 896 */ 897 if (!sysctl_discovery) { 898 /* Check if user wants to override the default */ 899 if (nslots == DISCOVERY_DEFAULT_SLOTS) 900 nslots = sysctl_discovery_slots; 901 902 irlmp_do_discovery(nslots); 903 /* Note : we never do expiry here. Expiry will run on the 904 * discovery timer regardless of the state of sysctl_discovery 905 * Jean II */ 906 } 907} 908EXPORT_SYMBOL(irlmp_discovery_request); 909 910/* 911 * Function irlmp_get_discoveries (pn, mask, slots) 912 * 913 * Return the current discovery log 914 * 915 * If discovery is not enabled, you should call this function again 916 * after 1 or 2 seconds (i.e. after discovery has been done). 917 */ 918struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots) 919{ 920 /* If discovery is not enabled, it's likely that the discovery log 921 * will be empty. So, we trigger a single discovery, so that next 922 * time the user call us there might be some results in the log. 923 * Jean II 924 */ 925 if (!sysctl_discovery) { 926 /* Check if user wants to override the default */ 927 if (nslots == DISCOVERY_DEFAULT_SLOTS) 928 nslots = sysctl_discovery_slots; 929 930 /* Start discovery - will complete sometime later */ 931 irlmp_do_discovery(nslots); 932 /* Note : we never do expiry here. Expiry will run on the 933 * discovery timer regardless of the state of sysctl_discovery 934 * Jean II */ 935 } 936 937 /* Return current cached discovery log */ 938 return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE)); 939} 940EXPORT_SYMBOL(irlmp_get_discoveries); 941 942/* 943 * Function irlmp_notify_client (log) 944 * 945 * Notify all about discovered devices 946 * 947 * Clients registered with IrLMP are : 948 * o IrComm 949 * o IrLAN 950 * o Any socket (in any state - ouch, that may be a lot !) 951 * The client may have defined a callback to be notified in case of 952 * partial/selective discovery based on the hints that it passed to IrLMP. 953 */ 954static inline void 955irlmp_notify_client(irlmp_client_t *client, 956 hashbin_t *log, DISCOVERY_MODE mode) 957{ 958 discinfo_t *discoveries; /* Copy of the discovery log */ 959 int number; /* Number of nodes in the log */ 960 int i; 961 962 IRDA_DEBUG(3, "%s()\n", __FUNCTION__); 963 964 /* Check if client wants or not partial/selective log (optimisation) */ 965 if (!client->disco_callback) 966 return; 967 968 /* 969 * Locking notes : 970 * the old code was manipulating the log directly, which was 971 * very racy. Now, we use copy_discoveries, that protects 972 * itself while dumping the log for us. 973 * The overhead of the copy is compensated by the fact that 974 * we only pass new discoveries in normal mode and don't 975 * pass the same old entry every 3s to the caller as we used 976 * to do (virtual function calling is expensive). 977 * Jean II 978 */ 979 980 /* 981 * Now, check all discovered devices (if any), and notify client 982 * only about the services that the client is interested in 983 * We also notify only about the new devices unless the caller 984 * explicitly request a dump of the log. Jean II 985 */ 986 discoveries = irlmp_copy_discoveries(log, &number, 987 client->hint_mask.word, 988 (mode == DISCOVERY_LOG)); 989 /* Check if the we got some results */ 990 if (discoveries == NULL) 991 return; /* No nodes discovered */ 992 993 /* Pass all entries to the listener */ 994 for(i = 0; i < number; i++) 995 client->disco_callback(&(discoveries[i]), mode, client->priv); 996 997 /* Free up our buffer */ 998 kfree(discoveries); 999} 1000 1001/* 1002 * Function irlmp_discovery_confirm ( self, log) 1003 * 1004 * Some device(s) answered to our discovery request! Check to see which 1005 * device it is, and give indication to the client(s) 1006 * 1007 */ 1008void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode) 1009{ 1010 irlmp_client_t *client; 1011 irlmp_client_t *client_next; 1012 1013 IRDA_DEBUG(3, "%s()\n", __FUNCTION__); 1014 1015 IRDA_ASSERT(log != NULL, return;); 1016 1017 if (!(HASHBIN_GET_SIZE(log))) 1018 return; 1019 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) ) { 1024 /* Check if we should notify client */ 1025 irlmp_notify_client(client, log, mode); 1026 1027 client = client_next; 1028 } 1029} 1030 1031/* 1032 * Function irlmp_discovery_expiry (expiry) 1033 * 1034 * This device is no longer been discovered, and therefore it is being 1035 * purged from the discovery log. Inform all clients who have 1036 * registered for this event... 1037 * 1038 * Note : called exclusively from discovery.c 1039 * Note : this is no longer called under discovery spinlock, so the 1040 * client can do whatever he wants in the callback. 1041 */ 1042void irlmp_discovery_expiry(discinfo_t *expiries, int number) 1043{ 1044 irlmp_client_t *client; 1045 irlmp_client_t *client_next; 1046 int i; 1047 1048 IRDA_DEBUG(3, "%s()\n", __FUNCTION__); 1049 1050 IRDA_ASSERT(expiries != NULL, return;); 1051 1052 /* For each client - notify callback may touch client list */ 1053 client = (irlmp_client_t *) hashbin_get_first(irlmp->clients); 1054 while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL, 1055 (void *) &client_next) ) { 1056 1057 /* Pass all entries to the listener */ 1058 for(i = 0; i < number; i++) { 1059 /* Check if we should notify client */ 1060 if ((client->expir_callback) && 1061 (client->hint_mask.word & u16ho(expiries[i].hints) 1062 & 0x7f7f) ) 1063 client->expir_callback(&(expiries[i]), 1064 EXPIRY_TIMEOUT, 1065 client->priv); 1066 } 1067 1068 /* Next client */ 1069 client = client_next; 1070 } 1071} 1072 1073/* 1074 * Function irlmp_get_discovery_response () 1075 * 1076 * Used by IrLAP to get the discovery info it needs when answering 1077 * discovery requests by other devices. 1078 */ 1079discovery_t *irlmp_get_discovery_response(void) 1080{ 1081 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1082 1083 IRDA_ASSERT(irlmp != NULL, return NULL;); 1084 1085 u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word; 1086 1087 /* 1088 * Set character set for device name (we use ASCII), and 1089 * copy device name. Remember to make room for a \0 at the 1090 * end 1091 */ 1092 irlmp->discovery_rsp.data.charset = CS_ASCII; 1093 1094 strncpy(irlmp->discovery_rsp.data.info, sysctl_devname, 1095 NICKNAME_MAX_LEN); 1096 irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.data.info); 1097 1098 return &irlmp->discovery_rsp; 1099} 1100 1101/* 1102 * Function irlmp_data_request (self, skb) 1103 * 1104 * Send some data to peer device 1105 * 1106 * Note on skb management : 1107 * After calling the lower layers of the IrDA stack, we always 1108 * kfree() the skb, which drop the reference count (and potentially 1109 * destroy it). 1110 * IrLMP and IrLAP may queue the packet, and in those cases will need 1111 * to use skb_get() to keep it around. 1112 * Jean II 1113 */ 1114int irlmp_data_request(struct lsap_cb *self, struct sk_buff *userdata) 1115{ 1116 int ret; 1117 1118 IRDA_ASSERT(self != NULL, return -1;); 1119 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); 1120 1121 /* Make room for MUX header */ 1122 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;); 1123 skb_push(userdata, LMP_HEADER); 1124 1125 ret = irlmp_do_lsap_event(self, LM_DATA_REQUEST, userdata); 1126 1127 /* Drop reference count - see irlap_data_request(). */ 1128 dev_kfree_skb(userdata); 1129 1130 return ret; 1131} 1132EXPORT_SYMBOL(irlmp_data_request); 1133 1134/* 1135 * Function irlmp_data_indication (handle, skb) 1136 * 1137 * Got data from LAP layer so pass it up to upper layer 1138 * 1139 */ 1140void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) 1141{ 1142 /* Hide LMP header from layer above */ 1143 skb_pull(skb, LMP_HEADER); 1144 1145 if (self->notify.data_indication) { 1146 /* Don't forget to refcount it - see irlap_driver_rcv(). */ 1147 skb_get(skb); 1148 self->notify.data_indication(self->notify.instance, self, skb); 1149 } 1150} 1151 1152/* 1153 * Function irlmp_udata_request (self, skb) 1154 */ 1155int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *userdata) 1156{ 1157 int ret; 1158 1159 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1160 1161 IRDA_ASSERT(userdata != NULL, return -1;); 1162 1163 /* Make room for MUX header */ 1164 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;); 1165 skb_push(userdata, LMP_HEADER); 1166 1167 ret = irlmp_do_lsap_event(self, LM_UDATA_REQUEST, userdata); 1168 1169 /* Drop reference count - see irlap_data_request(). */ 1170 dev_kfree_skb(userdata); 1171 1172 return ret; 1173} 1174 1175/* 1176 * Function irlmp_udata_indication (self, skb) 1177 * 1178 * Send unreliable data (but still within the connection) 1179 * 1180 */ 1181void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) 1182{ 1183 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1184 1185 IRDA_ASSERT(self != NULL, return;); 1186 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 1187 IRDA_ASSERT(skb != NULL, return;); 1188 1189 /* Hide LMP header from layer above */ 1190 skb_pull(skb, LMP_HEADER); 1191 1192 if (self->notify.udata_indication) { 1193 /* Don't forget to refcount it - see irlap_driver_rcv(). */ 1194 skb_get(skb); 1195 self->notify.udata_indication(self->notify.instance, self, 1196 skb); 1197 } 1198} 1199 1200/* 1201 * Function irlmp_connless_data_request (self, skb) 1202 */ 1203#ifdef CONFIG_IRDA_ULTRA 1204int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata, 1205 __u8 pid) 1206{ 1207 struct sk_buff *clone_skb; 1208 struct lap_cb *lap; 1209 1210 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1211 1212 IRDA_ASSERT(userdata != NULL, return -1;); 1213 1214 /* Make room for MUX and PID header */ 1215 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER+LMP_PID_HEADER, 1216 return -1;); 1217 1218 /* Insert protocol identifier */ 1219 skb_push(userdata, LMP_PID_HEADER); 1220 if(self != NULL) 1221 userdata->data[0] = self->pid; 1222 else 1223 userdata->data[0] = pid; 1224 1225 /* Connectionless sockets must use 0x70 */ 1226 skb_push(userdata, LMP_HEADER); 1227 userdata->data[0] = userdata->data[1] = LSAP_CONNLESS; 1228 1229 /* Try to send Connectionless packets out on all links */ 1230 lap = (struct lap_cb *) hashbin_get_first(irlmp->links); 1231 while (lap != NULL) { 1232 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return -1;); 1233 1234 clone_skb = skb_clone(userdata, GFP_ATOMIC); 1235 if (!clone_skb) { 1236 dev_kfree_skb(userdata); 1237 return -ENOMEM; 1238 } 1239 1240 irlap_unitdata_request(lap->irlap, clone_skb); 1241 /* irlap_unitdata_request() don't increase refcount, 1242 * so no dev_kfree_skb() - Jean II */ 1243 1244 lap = (struct lap_cb *) hashbin_get_next(irlmp->links); 1245 } 1246 dev_kfree_skb(userdata); 1247 1248 return 0; 1249} 1250#endif /* CONFIG_IRDA_ULTRA */ 1251 1252/* 1253 * Function irlmp_connless_data_indication (self, skb) 1254 * 1255 * Receive unreliable data outside any connection. Mostly used by Ultra 1256 * 1257 */ 1258#ifdef CONFIG_IRDA_ULTRA 1259void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb) 1260{ 1261 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1262 1263 IRDA_ASSERT(self != NULL, return;); 1264 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 1265 IRDA_ASSERT(skb != NULL, return;); 1266 1267 /* Hide LMP and PID header from layer above */ 1268 skb_pull(skb, LMP_HEADER+LMP_PID_HEADER); 1269 1270 if (self->notify.udata_indication) { 1271 /* Don't forget to refcount it - see irlap_driver_rcv(). */ 1272 skb_get(skb); 1273 self->notify.udata_indication(self->notify.instance, self, 1274 skb); 1275 } 1276} 1277#endif /* CONFIG_IRDA_ULTRA */ 1278 1279/* 1280 * Propagate status indication from LAP to LSAPs (via LMP) 1281 * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb, 1282 * and the event is stateless, therefore we can bypass both state machines 1283 * and send the event direct to the LSAP user. 1284 * Jean II 1285 */ 1286void irlmp_status_indication(struct lap_cb *self, 1287 LINK_STATUS link, LOCK_STATUS lock) 1288{ 1289 struct lsap_cb *next; 1290 struct lsap_cb *curr; 1291 1292 /* Send status_indication to all LSAPs using this link */ 1293 curr = (struct lsap_cb *) hashbin_get_first( self->lsaps); 1294 while (NULL != hashbin_find_next(self->lsaps, (long) curr, NULL, 1295 (void *) &next) ) { 1296 IRDA_ASSERT(curr->magic == LMP_LSAP_MAGIC, return;); 1297 /* 1298 * Inform service user if he has requested it 1299 */ 1300 if (curr->notify.status_indication != NULL) 1301 curr->notify.status_indication(curr->notify.instance, 1302 link, lock); 1303 else 1304 IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__); 1305 1306 curr = next; 1307 } 1308} 1309 1310/* 1311 * Receive flow control indication from LAP. 1312 * LAP want us to send it one more frame. We implement a simple round 1313 * robin scheduler between the active sockets so that we get a bit of 1314 * fairness. Note that the round robin is far from perfect, but it's 1315 * better than nothing. 1316 * We then poll the selected socket so that we can do synchronous 1317 * refilling of IrLAP (which allow to minimise the number of buffers). 1318 * Jean II 1319 */ 1320void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow) 1321{ 1322 struct lsap_cb *next; 1323 struct lsap_cb *curr; 1324 int lsap_todo; 1325 1326 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;); 1327 IRDA_ASSERT(flow == FLOW_START, return;); 1328 1329 /* Get the number of lsap. That's the only safe way to know 1330 * that we have looped around... - Jean II */ 1331 lsap_todo = HASHBIN_GET_SIZE(self->lsaps); 1332 IRDA_DEBUG(4, "%s() : %d lsaps to scan\n", __FUNCTION__, lsap_todo); 1333 1334 /* Poll lsap in order until the queue is full or until we 1335 * tried them all. 1336 * Most often, the current LSAP will have something to send, 1337 * so we will go through this loop only once. - Jean II */ 1338 while((lsap_todo--) && 1339 (IRLAP_GET_TX_QUEUE_LEN(self->irlap) < LAP_HIGH_THRESHOLD)) { 1340 /* Try to find the next lsap we should poll. */ 1341 next = self->flow_next; 1342 /* If we have no lsap, restart from first one */ 1343 if(next == NULL) 1344 next = (struct lsap_cb *) hashbin_get_first(self->lsaps); 1345 /* Verify current one and find the next one */ 1346 curr = hashbin_find_next(self->lsaps, (long) next, NULL, 1347 (void *) &self->flow_next); 1348 /* Uh-oh... Paranoia */ 1349 if(curr == NULL) 1350 break; 1351 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)); 1352 1353 /* Inform lsap user that it can send one more packet. */ 1354 if (curr->notify.flow_indication != NULL) 1355 curr->notify.flow_indication(curr->notify.instance, 1356 curr, flow); 1357 else 1358 IRDA_DEBUG(1, "%s(), no handler\n", __FUNCTION__); 1359 } 1360} 1361 1362 1363static const __u16 service_hint_mapping[S_END][2] = { 1364 { HINT_PNP, 0 }, /* S_PNP */ 1365 { HINT_PDA, 0 }, /* S_PDA */ 1366 { HINT_COMPUTER, 0 }, /* S_COMPUTER */ 1367 { HINT_PRINTER, 0 }, /* S_PRINTER */ 1368 { HINT_MODEM, 0 }, /* S_MODEM */ 1369 { HINT_FAX, 0 }, /* S_FAX */ 1370 { HINT_LAN, 0 }, /* S_LAN */ 1371 { HINT_EXTENSION, HINT_TELEPHONY }, /* S_TELEPHONY */ 1372 { HINT_EXTENSION, HINT_COMM }, /* S_COMM */ 1373 { HINT_EXTENSION, HINT_OBEX }, /* S_OBEX */ 1374 { 0xFF, 0xFF }, /* S_ANY */ 1375}; 1376 1377/* 1378 * Function irlmp_service_to_hint (service) 1379 * 1380 * Converts a service type, to a hint bit 1381 * 1382 * Returns: a 16 bit hint value, with the service bit set 1383 */ 1384__u16 irlmp_service_to_hint(int service) 1385{ 1386 __u16_host_order hint; 1387 1388 hint.byte[0] = service_hint_mapping[service][0]; 1389 hint.byte[1] = service_hint_mapping[service][1]; 1390 1391 return hint.word; 1392} 1393EXPORT_SYMBOL(irlmp_service_to_hint); 1394 1395/* 1396 * Function irlmp_register_service (service) 1397 * 1398 * Register local service with IrLMP 1399 * 1400 */ 1401void *irlmp_register_service(__u16 hints) 1402{ 1403 irlmp_service_t *service; 1404 1405 IRDA_DEBUG(4, "%s(), hints = %04x\n", __FUNCTION__, hints); 1406 1407 /* Make a new registration */ 1408 service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC); 1409 if (!service) { 1410 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__); 1411 return NULL; 1412 } 1413 service->hints.word = hints; 1414 hashbin_insert(irlmp->services, (irda_queue_t *) service, 1415 (long) service, NULL); 1416 1417 irlmp->hints.word |= hints; 1418 1419 return (void *)service; 1420} 1421EXPORT_SYMBOL(irlmp_register_service); 1422 1423/* 1424 * Function irlmp_unregister_service (handle) 1425 * 1426 * Unregister service with IrLMP. 1427 * 1428 * Returns: 0 on success, -1 on error 1429 */ 1430int irlmp_unregister_service(void *handle) 1431{ 1432 irlmp_service_t *service; 1433 unsigned long flags; 1434 1435 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1436 1437 if (!handle) 1438 return -1; 1439 1440 /* Caller may call with invalid handle (it's legal) - Jean II */ 1441 service = hashbin_lock_find(irlmp->services, (long) handle, NULL); 1442 if (!service) { 1443 IRDA_DEBUG(1, "%s(), Unknown service!\n", __FUNCTION__); 1444 return -1; 1445 } 1446 1447 hashbin_remove_this(irlmp->services, (irda_queue_t *) service); 1448 kfree(service); 1449 1450 /* Remove old hint bits */ 1451 irlmp->hints.word = 0; 1452 1453 /* Refresh current hint bits */ 1454 spin_lock_irqsave(&irlmp->services->hb_spinlock, flags); 1455 service = (irlmp_service_t *) hashbin_get_first(irlmp->services); 1456 while (service) { 1457 irlmp->hints.word |= service->hints.word; 1458 1459 service = (irlmp_service_t *)hashbin_get_next(irlmp->services); 1460 } 1461 spin_unlock_irqrestore(&irlmp->services->hb_spinlock, flags); 1462 return 0; 1463} 1464EXPORT_SYMBOL(irlmp_unregister_service); 1465 1466/* 1467 * Function irlmp_register_client (hint_mask, callback1, callback2) 1468 * 1469 * Register a local client with IrLMP 1470 * First callback is selective discovery (based on hints) 1471 * Second callback is for selective discovery expiries 1472 * 1473 * Returns: handle > 0 on success, 0 on error 1474 */ 1475void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, 1476 DISCOVERY_CALLBACK2 expir_clb, void *priv) 1477{ 1478 irlmp_client_t *client; 1479 1480 IRDA_DEBUG(1, "%s()\n", __FUNCTION__); 1481 IRDA_ASSERT(irlmp != NULL, return NULL;); 1482 1483 /* Make a new registration */ 1484 client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC); 1485 if (!client) { 1486 IRDA_DEBUG( 1, "%s(), Unable to kmalloc!\n", __FUNCTION__); 1487 return NULL; 1488 } 1489 1490 /* Register the details */ 1491 client->hint_mask.word = hint_mask; 1492 client->disco_callback = disco_clb; 1493 client->expir_callback = expir_clb; 1494 client->priv = priv; 1495 1496 hashbin_insert(irlmp->clients, (irda_queue_t *) client, 1497 (long) client, NULL); 1498 1499 return (void *) client; 1500} 1501EXPORT_SYMBOL(irlmp_register_client); 1502 1503/* 1504 * Function irlmp_update_client (handle, hint_mask, callback1, callback2) 1505 * 1506 * Updates specified client (handle) with possibly new hint_mask and 1507 * callback 1508 * 1509 * Returns: 0 on success, -1 on error 1510 */ 1511int irlmp_update_client(void *handle, __u16 hint_mask, 1512 DISCOVERY_CALLBACK1 disco_clb, 1513 DISCOVERY_CALLBACK2 expir_clb, void *priv) 1514{ 1515 irlmp_client_t *client; 1516 1517 if (!handle) 1518 return -1; 1519 1520 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL); 1521 if (!client) { 1522 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__); 1523 return -1; 1524 } 1525 1526 client->hint_mask.word = hint_mask; 1527 client->disco_callback = disco_clb; 1528 client->expir_callback = expir_clb; 1529 client->priv = priv; 1530 1531 return 0; 1532} 1533EXPORT_SYMBOL(irlmp_update_client); 1534 1535/* 1536 * Function irlmp_unregister_client (handle) 1537 * 1538 * Returns: 0 on success, -1 on error 1539 * 1540 */ 1541int irlmp_unregister_client(void *handle) 1542{ 1543 struct irlmp_client *client; 1544 1545 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1546 1547 if (!handle) 1548 return -1; 1549 1550 /* Caller may call with invalid handle (it's legal) - Jean II */ 1551 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL); 1552 if (!client) { 1553 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__); 1554 return -1; 1555 } 1556 1557 IRDA_DEBUG(4, "%s(), removing client!\n", __FUNCTION__); 1558 hashbin_remove_this(irlmp->clients, (irda_queue_t *) client); 1559 kfree(client); 1560 1561 return 0; 1562} 1563EXPORT_SYMBOL(irlmp_unregister_client); 1564 1565/* 1566 * Function irlmp_slsap_inuse (slsap) 1567 * 1568 * Check if the given source LSAP selector is in use 1569 * 1570 * This function is clearly not very efficient. On the mitigating side, the 1571 * stack make sure that in 99% of the cases, we are called only once 1572 * for each socket allocation. We could probably keep a bitmap 1573 * of the allocated LSAP, but I'm not sure the complexity is worth it. 1574 * Jean II 1575 */ 1576static int irlmp_slsap_inuse(__u8 slsap_sel) 1577{ 1578 struct lsap_cb *self; 1579 struct lap_cb *lap; 1580 unsigned long flags; 1581 1582 IRDA_ASSERT(irlmp != NULL, return TRUE;); 1583 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;); 1584 IRDA_ASSERT(slsap_sel != LSAP_ANY, return TRUE;); 1585 1586 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 1587 1588#ifdef CONFIG_IRDA_ULTRA 1589 /* Accept all bindings to the connectionless LSAP */ 1590 if (slsap_sel == LSAP_CONNLESS) 1591 return FALSE; 1592#endif /* CONFIG_IRDA_ULTRA */ 1593 1594 /* Valid values are between 0 and 127 (0x0-0x6F) */ 1595 if (slsap_sel > LSAP_MAX) 1596 return TRUE; 1597 1598 /* 1599 * Check if slsap is already in use. To do this we have to loop over 1600 * every IrLAP connection and check every LSAP associated with each 1601 * the connection. 1602 */ 1603 spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags, 1604 SINGLE_DEPTH_NESTING); 1605 lap = (struct lap_cb *) hashbin_get_first(irlmp->links); 1606 while (lap != NULL) { 1607 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); 1608 1609 /* Careful for priority inversions here ! 1610 * irlmp->links is never taken while another IrDA 1611 * spinlock is held, so we are safe. Jean II */ 1612 spin_lock(&lap->lsaps->hb_spinlock); 1613 1614 /* For this IrLAP, check all the LSAPs */ 1615 self = (struct lsap_cb *) hashbin_get_first(lap->lsaps); 1616 while (self != NULL) { 1617 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, 1618 goto errlsap;); 1619 1620 if ((self->slsap_sel == slsap_sel)) { 1621 IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n", 1622 self->slsap_sel); 1623 goto errlsap; 1624 } 1625 self = (struct lsap_cb*) hashbin_get_next(lap->lsaps); 1626 } 1627 spin_unlock(&lap->lsaps->hb_spinlock); 1628 1629 /* Next LAP */ 1630 lap = (struct lap_cb *) hashbin_get_next(irlmp->links); 1631 } 1632 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags); 1633 1634 /* 1635 * Server sockets are typically waiting for connections and 1636 * therefore reside in the unconnected list. We don't want 1637 * to give out their LSAPs for obvious reasons... 1638 * Jean II 1639 */ 1640 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags); 1641 1642 self = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps); 1643 while (self != NULL) { 1644 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, goto erruncon;); 1645 if ((self->slsap_sel == slsap_sel)) { 1646 IRDA_DEBUG(4, "Source LSAP selector=%02x in use (unconnected)\n", 1647 self->slsap_sel); 1648 goto erruncon; 1649 } 1650 self = (struct lsap_cb*) hashbin_get_next(irlmp->unconnected_lsaps); 1651 } 1652 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags); 1653 1654 return FALSE; 1655 1656 /* Error exit from within one of the two nested loops. 1657 * Make sure we release the right spinlock in the righ order. 1658 * Jean II */ 1659errlsap: 1660 spin_unlock(&lap->lsaps->hb_spinlock); 1661IRDA_ASSERT_LABEL(errlap:) 1662 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags); 1663 return TRUE; 1664 1665 /* Error exit from within the unconnected loop. 1666 * Just one spinlock to release... Jean II */ 1667erruncon: 1668 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags); 1669 return TRUE; 1670} 1671 1672/* 1673 * Function irlmp_find_free_slsap () 1674 * 1675 * Find a free source LSAP to use. This function is called if the service 1676 * user has requested a source LSAP equal to LM_ANY 1677 */ 1678static __u8 irlmp_find_free_slsap(void) 1679{ 1680 __u8 lsap_sel; 1681 int wrapped = 0; 1682 1683 IRDA_ASSERT(irlmp != NULL, return -1;); 1684 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return -1;); 1685 1686 /* Most users don't really care which LSAPs they are given, 1687 * and therefore we automatically give them a free LSAP. 1688 * This function try to find a suitable LSAP, i.e. which is 1689 * not in use and is within the acceptable range. Jean II */ 1690 1691 do { 1692 /* Always increment to LSAP number before using it. 1693 * In theory, we could reuse the last LSAP number, as long 1694 * as it is no longer in use. Some IrDA stack do that. 1695 * However, the previous socket may be half closed, i.e. 1696 * we closed it, we think it's no longer in use, but the 1697 * other side did not receive our close and think it's 1698 * active and still send data on it. 1699 * This is similar to what is done with PIDs and TCP ports. 1700 * Also, this reduce the number of calls to irlmp_slsap_inuse() 1701 * which is an expensive function to call. 1702 * Jean II */ 1703 irlmp->last_lsap_sel++; 1704 1705 /* Check if we need to wraparound (0x70-0x7f are reserved) */ 1706 if (irlmp->last_lsap_sel > LSAP_MAX) { 1707 /* 0x00-0x10 are also reserved for well know ports */ 1708 irlmp->last_lsap_sel = 0x10; 1709 1710 /* Make sure we terminate the loop */ 1711 if (wrapped++) { 1712 IRDA_ERROR("%s: no more free LSAPs !\n", 1713 __FUNCTION__); 1714 return 0; 1715 } 1716 } 1717 1718 /* If the LSAP is in use, try the next one. 1719 * Despite the autoincrement, we need to check if the lsap 1720 * is really in use or not, first because LSAP may be 1721 * directly allocated in irlmp_open_lsap(), and also because 1722 * we may wraparound on old sockets. Jean II */ 1723 } while (irlmp_slsap_inuse(irlmp->last_lsap_sel)); 1724 1725 /* Got it ! */ 1726 lsap_sel = irlmp->last_lsap_sel; 1727 IRDA_DEBUG(4, "%s(), found free lsap_sel=%02x\n", 1728 __FUNCTION__, lsap_sel); 1729 1730 return lsap_sel; 1731} 1732 1733/* 1734 * Function irlmp_convert_lap_reason (lap_reason) 1735 * 1736 * Converts IrLAP disconnect reason codes to IrLMP disconnect reason 1737 * codes 1738 * 1739 */ 1740LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason) 1741{ 1742 int reason = LM_LAP_DISCONNECT; 1743 1744 switch (lap_reason) { 1745 case LAP_DISC_INDICATION: /* Received a disconnect request from peer */ 1746 IRDA_DEBUG( 1, "%s(), LAP_DISC_INDICATION\n", __FUNCTION__); 1747 reason = LM_USER_REQUEST; 1748 break; 1749 case LAP_NO_RESPONSE: /* To many retransmits without response */ 1750 IRDA_DEBUG( 1, "%s(), LAP_NO_RESPONSE\n", __FUNCTION__); 1751 reason = LM_LAP_DISCONNECT; 1752 break; 1753 case LAP_RESET_INDICATION: 1754 IRDA_DEBUG( 1, "%s(), LAP_RESET_INDICATION\n", __FUNCTION__); 1755 reason = LM_LAP_RESET; 1756 break; 1757 case LAP_FOUND_NONE: 1758 case LAP_MEDIA_BUSY: 1759 case LAP_PRIMARY_CONFLICT: 1760 IRDA_DEBUG(1, "%s(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n", __FUNCTION__); 1761 reason = LM_CONNECT_FAILURE; 1762 break; 1763 default: 1764 IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n", 1765 __FUNCTION__, lap_reason); 1766 reason = LM_LAP_DISCONNECT; 1767 break; 1768 } 1769 1770 return reason; 1771} 1772 1773#ifdef CONFIG_PROC_FS 1774 1775struct irlmp_iter_state { 1776 hashbin_t *hashbin; 1777}; 1778 1779#define LSAP_START_TOKEN ((void *)1) 1780#define LINK_START_TOKEN ((void *)2) 1781 1782static void *irlmp_seq_hb_idx(struct irlmp_iter_state *iter, loff_t *off) 1783{ 1784 void *element; 1785 1786 spin_lock_irq(&iter->hashbin->hb_spinlock); 1787 for (element = hashbin_get_first(iter->hashbin); 1788 element != NULL; 1789 element = hashbin_get_next(iter->hashbin)) { 1790 if (!off || *off-- == 0) { 1791 /* NB: hashbin left locked */ 1792 return element; 1793 } 1794 } 1795 spin_unlock_irq(&iter->hashbin->hb_spinlock); 1796 iter->hashbin = NULL; 1797 return NULL; 1798} 1799 1800 1801static void *irlmp_seq_start(struct seq_file *seq, loff_t *pos) 1802{ 1803 struct irlmp_iter_state *iter = seq->private; 1804 void *v; 1805 loff_t off = *pos; 1806 1807 iter->hashbin = NULL; 1808 if (off-- == 0) 1809 return LSAP_START_TOKEN; 1810 1811 iter->hashbin = irlmp->unconnected_lsaps; 1812 v = irlmp_seq_hb_idx(iter, &off); 1813 if (v) 1814 return v; 1815 1816 if (off-- == 0) 1817 return LINK_START_TOKEN; 1818 1819 iter->hashbin = irlmp->links; 1820 return irlmp_seq_hb_idx(iter, &off); 1821} 1822 1823static void *irlmp_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1824{ 1825 struct irlmp_iter_state *iter = seq->private; 1826 1827 ++*pos; 1828 1829 if (v == LSAP_START_TOKEN) { /* start of list of lsaps */ 1830 iter->hashbin = irlmp->unconnected_lsaps; 1831 v = irlmp_seq_hb_idx(iter, NULL); 1832 return v ? v : LINK_START_TOKEN; 1833 } 1834 1835 if (v == LINK_START_TOKEN) { /* start of list of links */ 1836 iter->hashbin = irlmp->links; 1837 return irlmp_seq_hb_idx(iter, NULL); 1838 } 1839 1840 v = hashbin_get_next(iter->hashbin); 1841 1842 if (v == NULL) { /* no more in this hash bin */ 1843 spin_unlock_irq(&iter->hashbin->hb_spinlock); 1844 1845 if (iter->hashbin == irlmp->unconnected_lsaps) 1846 v = LINK_START_TOKEN; 1847 1848 iter->hashbin = NULL; 1849 } 1850 return v; 1851} 1852 1853static void irlmp_seq_stop(struct seq_file *seq, void *v) 1854{ 1855 struct irlmp_iter_state *iter = seq->private; 1856 1857 if (iter->hashbin) 1858 spin_unlock_irq(&iter->hashbin->hb_spinlock); 1859} 1860 1861static int irlmp_seq_show(struct seq_file *seq, void *v) 1862{ 1863 const struct irlmp_iter_state *iter = seq->private; 1864 struct lsap_cb *self = v; 1865 1866 if (v == LSAP_START_TOKEN) 1867 seq_puts(seq, "Unconnected LSAPs:\n"); 1868 else if (v == LINK_START_TOKEN) 1869 seq_puts(seq, "\nRegistered Link Layers:\n"); 1870 else if (iter->hashbin == irlmp->unconnected_lsaps) { 1871 self = v; 1872 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -EINVAL; ); 1873 seq_printf(seq, "lsap state: %s, ", 1874 irlsap_state[ self->lsap_state]); 1875 seq_printf(seq, 1876 "slsap_sel: %#02x, dlsap_sel: %#02x, ", 1877 self->slsap_sel, self->dlsap_sel); 1878 seq_printf(seq, "(%s)", self->notify.name); 1879 seq_printf(seq, "\n"); 1880 } else if (iter->hashbin == irlmp->links) { 1881 struct lap_cb *lap = v; 1882 1883 seq_printf(seq, "lap state: %s, ", 1884 irlmp_state[lap->lap_state]); 1885 1886 seq_printf(seq, "saddr: %#08x, daddr: %#08x, ", 1887 lap->saddr, lap->daddr); 1888 seq_printf(seq, "num lsaps: %d", 1889 HASHBIN_GET_SIZE(lap->lsaps)); 1890 seq_printf(seq, "\n"); 1891 1892 /* Careful for priority inversions here ! 1893 * All other uses of attrib spinlock are independent of 1894 * the object spinlock, so we are safe. Jean II */ 1895 spin_lock(&lap->lsaps->hb_spinlock); 1896 1897 seq_printf(seq, "\n Connected LSAPs:\n"); 1898 for (self = (struct lsap_cb *) hashbin_get_first(lap->lsaps); 1899 self != NULL; 1900 self = (struct lsap_cb *)hashbin_get_next(lap->lsaps)) { 1901 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, 1902 goto outloop;); 1903 seq_printf(seq, " lsap state: %s, ", 1904 irlsap_state[ self->lsap_state]); 1905 seq_printf(seq, 1906 "slsap_sel: %#02x, dlsap_sel: %#02x, ", 1907 self->slsap_sel, self->dlsap_sel); 1908 seq_printf(seq, "(%s)", self->notify.name); 1909 seq_putc(seq, '\n'); 1910 1911 } 1912 IRDA_ASSERT_LABEL(outloop:) 1913 spin_unlock(&lap->lsaps->hb_spinlock); 1914 seq_putc(seq, '\n'); 1915 } else 1916 return -EINVAL; 1917 1918 return 0; 1919} 1920 1921static struct seq_operations irlmp_seq_ops = { 1922 .start = irlmp_seq_start, 1923 .next = irlmp_seq_next, 1924 .stop = irlmp_seq_stop, 1925 .show = irlmp_seq_show, 1926}; 1927 1928static int irlmp_seq_open(struct inode *inode, struct file *file) 1929{ 1930 struct seq_file *seq; 1931 int rc = -ENOMEM; 1932 struct irlmp_iter_state *s; 1933 1934 IRDA_ASSERT(irlmp != NULL, return -EINVAL;); 1935 1936 s = kmalloc(sizeof(*s), GFP_KERNEL); 1937 if (!s) 1938 goto out; 1939 1940 rc = seq_open(file, &irlmp_seq_ops); 1941 if (rc) 1942 goto out_kfree; 1943 1944 seq = file->private_data; 1945 seq->private = s; 1946out: 1947 return rc; 1948out_kfree: 1949 kfree(s); 1950 goto out; 1951} 1952 1953const struct file_operations irlmp_seq_fops = { 1954 .owner = THIS_MODULE, 1955 .open = irlmp_seq_open, 1956 .read = seq_read, 1957 .llseek = seq_lseek, 1958 .release = seq_release_private, 1959}; 1960 1961#endif /* PROC_FS */ 1962