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