Blame view
net/irda/af_irda.c
66.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/********************************************************************* * * Filename: af_irda.c * Version: 0.9 * Description: IrDA sockets implementation * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun May 31 10:12:43 1998 * Modified at: Sat Dec 25 21:10:23 1999 * Modified by: Dag Brattli <dag@brattli.net> * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc. * * Copyright (c) 1999 Dag Brattli <dagb@cs.uit.no> * Copyright (c) 1999-2003 Jean Tourrilhes <jt@hpl.hp.com> * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License |
d37705092 net/irda: Fix FSF... |
28 |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 33 34 35 36 37 38 39 40 41 |
* * Linux-IrDA now supports four different types of IrDA sockets: * * o SOCK_STREAM: TinyTP connections with SAR disabled. The * max SDU size is 0 for conn. of this type * o SOCK_SEQPACKET: TinyTP connections with SAR enabled. TTP may * fragment the messages, but will preserve * the message boundaries * o SOCK_DGRAM: IRDAPROTO_UNITDATA: TinyTP connections with Unitdata * (unreliable) transfers * IRDAPROTO_ULTRA: Connectionless and unreliable data * ********************************************************************/ |
4fc268d24 [PATCH] capable/c... |
42 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 46 |
#include <linux/module.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/sockios.h> |
5a0e3ad6a include cleanup: ... |
47 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 51 52 53 54 55 56 |
#include <linux/init.h> #include <linux/net.h> #include <linux/irda.h> #include <linux/poll.h> #include <asm/ioctls.h> /* TIOCOUTQ, TIOCINQ */ #include <asm/uaccess.h> #include <net/sock.h> |
c752f0739 [TCP]: Move the t... |
57 |
#include <net/tcp_states.h> |
1da177e4c Linux-2.6.12-rc2 |
58 59 |
#include <net/irda/af_irda.h> |
3f378b684 net: pass kern to... |
60 |
static int irda_create(struct net *net, struct socket *sock, int protocol, int kern); |
1da177e4c Linux-2.6.12-rc2 |
61 |
|
90ddc4f04 [NET]: move struc... |
62 63 64 |
static const struct proto_ops irda_stream_ops; static const struct proto_ops irda_seqpacket_ops; static const struct proto_ops irda_dgram_ops; |
1da177e4c Linux-2.6.12-rc2 |
65 66 |
#ifdef CONFIG_IRDA_ULTRA |
90ddc4f04 [NET]: move struc... |
67 |
static const struct proto_ops irda_ultra_ops; |
1da177e4c Linux-2.6.12-rc2 |
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#define ULTRA_MAX_DATA 382 #endif /* CONFIG_IRDA_ULTRA */ #define IRDA_MAX_HEADER (TTP_MAX_HEADER) /* * Function irda_data_indication (instance, sap, skb) * * Received some data from TinyTP. Just queue it on the receive queue * */ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb) { struct irda_sock *self; struct sock *sk; int err; |
1da177e4c Linux-2.6.12-rc2 |
84 85 |
self = instance; sk = instance; |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 |
err = sock_queue_rcv_skb(sk, skb); if (err) { |
955a9d202 irda: Convert IRD... |
89 90 |
pr_debug("%s(), error: no more mem! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
self->rx_flow = FLOW_STOP; /* When we return error, TTP will need to requeue the skb */ return err; } return 0; } /* * Function irda_disconnect_indication (instance, sap, reason, skb) * * Connection has been closed. Check reason to find out why * */ static void irda_disconnect_indication(void *instance, void *sap, LM_REASON reason, struct sk_buff *skb) { struct irda_sock *self; struct sock *sk; self = instance; |
955a9d202 irda: Convert IRD... |
113 114 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
115 116 117 118 119 120 121 |
/* Don't care about it, but let's not leak it */ if(skb) dev_kfree_skb(skb); sk = instance; if (sk == NULL) { |
955a9d202 irda: Convert IRD... |
122 123 124 |
pr_debug("%s(%p) : BUG : sk is NULL ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 128 |
return; } /* Prevent race conditions with irda_release() and irda_shutdown() */ |
6e66aa15d [IrDA] af_irda: S... |
129 |
bh_lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
130 131 |
if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) { sk->sk_state = TCP_CLOSE; |
1da177e4c Linux-2.6.12-rc2 |
132 133 134 |
sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_state_change(sk); |
1da177e4c Linux-2.6.12-rc2 |
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
/* Close our TSAP. * If we leave it open, IrLMP put it back into the list of * unconnected LSAPs. The problem is that any incoming request * can then be matched to this socket (and it will be, because * it is at the head of the list). This would prevent any * listening socket waiting on the same TSAP to get those * requests. Some apps forget to close sockets, or hang to it * a bit too long, so we may stay in this dead state long * enough to be noticed... * Note : all socket function do check sk->sk_state, so we are * safe... * Jean II */ if (self->tsap) { irttp_close_tsap(self->tsap); self->tsap = NULL; } |
6819bc2e1 [NET] IRDA: Fix w... |
153 |
} |
6e66aa15d [IrDA] af_irda: S... |
154 |
bh_unlock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
/* Note : once we are there, there is not much you want to do * with the socket anymore, apart from closing it. * For example, bind() and connect() won't reset sk->sk_err, * sk->sk_shutdown and sk->sk_flags to valid values... * Jean II */ } /* * Function irda_connect_confirm (instance, sap, qos, max_sdu_size, skb) * * Connections has been confirmed by the remote device * */ static void irda_connect_confirm(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, __u8 max_header_size, struct sk_buff *skb) { struct irda_sock *self; struct sock *sk; self = instance; |
955a9d202 irda: Convert IRD... |
179 180 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
sk = instance; if (sk == NULL) { dev_kfree_skb(skb); return; } dev_kfree_skb(skb); // Should be ??? skb_queue_tail(&sk->sk_receive_queue, skb); /* How much header space do we need to reserve */ self->max_header_size = max_header_size; /* IrTTP max SDU size in transmit direction */ self->max_sdu_size_tx = max_sdu_size; /* Find out what the largest chunk of data that we can transmit is */ switch (sk->sk_type) { case SOCK_STREAM: if (max_sdu_size != 0) { |
6c91023dc irda: Remove IRDA... |
201 202 203 |
net_err_ratelimited("%s: max_sdu_size must be 0 ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
204 205 206 207 208 209 |
return; } self->max_data_size = irttp_get_max_seg_size(self->tsap); break; case SOCK_SEQPACKET: if (max_sdu_size == 0) { |
6c91023dc irda: Remove IRDA... |
210 211 212 |
net_err_ratelimited("%s: max_sdu_size cannot be 0 ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
213 214 215 216 217 218 |
return; } self->max_data_size = max_sdu_size; break; default: self->max_data_size = irttp_get_max_seg_size(self->tsap); |
3ff50b799 [NET]: cleanup ex... |
219 |
} |
1da177e4c Linux-2.6.12-rc2 |
220 |
|
955a9d202 irda: Convert IRD... |
221 222 223 |
pr_debug("%s(), max_data_size=%d ", __func__, self->max_data_size); |
1da177e4c Linux-2.6.12-rc2 |
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
memcpy(&self->qos_tx, qos, sizeof(struct qos_info)); /* We are now connected! */ sk->sk_state = TCP_ESTABLISHED; sk->sk_state_change(sk); } /* * Function irda_connect_indication(instance, sap, qos, max_sdu_size, userdata) * * Incoming connection * */ static void irda_connect_indication(void *instance, void *sap, struct qos_info *qos, __u32 max_sdu_size, __u8 max_header_size, struct sk_buff *skb) { struct irda_sock *self; struct sock *sk; self = instance; |
955a9d202 irda: Convert IRD... |
246 247 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
sk = instance; if (sk == NULL) { dev_kfree_skb(skb); return; } /* How much header space do we need to reserve */ self->max_header_size = max_header_size; /* IrTTP max SDU size in transmit direction */ self->max_sdu_size_tx = max_sdu_size; /* Find out what the largest chunk of data that we can transmit is */ switch (sk->sk_type) { case SOCK_STREAM: if (max_sdu_size != 0) { |
6c91023dc irda: Remove IRDA... |
265 266 267 |
net_err_ratelimited("%s: max_sdu_size must be 0 ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 271 272 273 274 |
kfree_skb(skb); return; } self->max_data_size = irttp_get_max_seg_size(self->tsap); break; case SOCK_SEQPACKET: if (max_sdu_size == 0) { |
6c91023dc irda: Remove IRDA... |
275 276 277 |
net_err_ratelimited("%s: max_sdu_size cannot be 0 ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
278 279 280 281 282 283 284 |
kfree_skb(skb); return; } self->max_data_size = max_sdu_size; break; default: self->max_data_size = irttp_get_max_seg_size(self->tsap); |
3ff50b799 [NET]: cleanup ex... |
285 |
} |
1da177e4c Linux-2.6.12-rc2 |
286 |
|
955a9d202 irda: Convert IRD... |
287 288 289 |
pr_debug("%s(), max_data_size=%d ", __func__, self->max_data_size); |
1da177e4c Linux-2.6.12-rc2 |
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
memcpy(&self->qos_tx, qos, sizeof(struct qos_info)); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_state_change(sk); } /* * Function irda_connect_response (handle) * * Accept incoming connection * */ static void irda_connect_response(struct irda_sock *self) { struct sk_buff *skb; |
e1e3c806d irda: use GFP_KER... |
306 |
skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
307 |
if (skb == NULL) { |
955a9d202 irda: Convert IRD... |
308 309 310 |
pr_debug("%s() Unable to allocate sk_buff! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
return; } /* Reserve space for MUX_CONTROL and LAP header */ skb_reserve(skb, IRDA_MAX_HEADER); irttp_connect_response(self->tsap, self->max_sdu_size_rx, skb); } /* * Function irda_flow_indication (instance, sap, flow) * * Used by TinyTP to tell us if it can accept more data or not * */ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) { struct irda_sock *self; struct sock *sk; |
1da177e4c Linux-2.6.12-rc2 |
330 331 |
self = instance; sk = instance; |
c3ea9fa27 [IrDA] af_irda: I... |
332 |
BUG_ON(sk == NULL); |
1da177e4c Linux-2.6.12-rc2 |
333 334 335 |
switch (flow) { case FLOW_STOP: |
955a9d202 irda: Convert IRD... |
336 337 338 |
pr_debug("%s(), IrTTP wants us to slow down ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
339 340 341 342 |
self->tx_flow = flow; break; case FLOW_START: self->tx_flow = flow; |
955a9d202 irda: Convert IRD... |
343 344 345 |
pr_debug("%s(), IrTTP wants us to start again ", __func__); |
aa3951451 net: sk_sleep() h... |
346 |
wake_up_interruptible(sk_sleep(sk)); |
1da177e4c Linux-2.6.12-rc2 |
347 348 |
break; default: |
955a9d202 irda: Convert IRD... |
349 350 |
pr_debug("%s(), Unknown flow command! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
/* Unknown flow command, better stop */ self->tx_flow = flow; break; } } /* * Function irda_getvalue_confirm (obj_id, value, priv) * * Got answer from remote LM-IAS, just pass object to requester... * * Note : duplicate from above, but we need our own version that * doesn't touch the dtsap_sel and save the full value structure... */ static void irda_getvalue_confirm(int result, __u16 obj_id, struct ias_value *value, void *priv) { struct irda_sock *self; |
ea1107338 net: Remove casts... |
369 |
self = priv; |
1da177e4c Linux-2.6.12-rc2 |
370 |
if (!self) { |
6c91023dc irda: Remove IRDA... |
371 372 |
net_warn_ratelimited("%s: lost myself! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
373 374 |
return; } |
955a9d202 irda: Convert IRD... |
375 376 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
377 378 379 380 381 382 383 |
/* We probably don't need to make any more queries */ iriap_close(self->iriap); self->iriap = NULL; /* Check if request succeeded */ if (result != IAS_SUCCESS) { |
955a9d202 irda: Convert IRD... |
384 385 386 |
pr_debug("%s(), IAS query failed! (%d) ", __func__, result); |
1da177e4c Linux-2.6.12-rc2 |
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
self->errno = result; /* We really need it later */ /* Wake up any processes waiting for result */ wake_up_interruptible(&self->query_wait); return; } /* Pass the object to the caller (so the caller must delete it) */ self->ias_result = value; self->errno = 0; /* Wake up any processes waiting for result */ wake_up_interruptible(&self->query_wait); } /* * Function irda_selective_discovery_indication (discovery) * * Got a selective discovery indication from IrLMP. * * IrLMP is telling us that this node is new and matching our hint bit * filter. Wake up any process waiting for answer... */ static void irda_selective_discovery_indication(discinfo_t *discovery, DISCOVERY_MODE mode, void *priv) { struct irda_sock *self; |
ea1107338 net: Remove casts... |
417 |
self = priv; |
1da177e4c Linux-2.6.12-rc2 |
418 |
if (!self) { |
6c91023dc irda: Remove IRDA... |
419 420 |
net_warn_ratelimited("%s: lost myself! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
return; } /* Pass parameter to the caller */ self->cachedaddr = discovery->daddr; /* Wake up process if its waiting for device to be discovered */ wake_up_interruptible(&self->query_wait); } /* * Function irda_discovery_timeout (priv) * * Timeout in the selective discovery process * * We were waiting for a node to be discovered, but nothing has come up * so far. Wake up the user and tell him that we failed... */ static void irda_discovery_timeout(u_long priv) { struct irda_sock *self; |
1da177e4c Linux-2.6.12-rc2 |
442 |
self = (struct irda_sock *) priv; |
c3ea9fa27 [IrDA] af_irda: I... |
443 |
BUG_ON(self == NULL); |
1da177e4c Linux-2.6.12-rc2 |
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
/* Nothing for the caller */ self->cachelog = NULL; self->cachedaddr = 0; self->errno = -ETIME; /* Wake up process if its still waiting... */ wake_up_interruptible(&self->query_wait); } /* * Function irda_open_tsap (self) * * Open local Transport Service Access Point (TSAP) * */ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name) { notify_t notify; if (self->tsap) { |
955a9d202 irda: Convert IRD... |
465 466 |
pr_debug("%s: busy! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
return -EBUSY; } /* Initialize callbacks to be used by the IrDA stack */ irda_notify_init(¬ify); notify.connect_confirm = irda_connect_confirm; notify.connect_indication = irda_connect_indication; notify.disconnect_indication = irda_disconnect_indication; notify.data_indication = irda_data_indication; notify.udata_indication = irda_data_indication; notify.flow_indication = irda_flow_indication; notify.instance = self; strncpy(notify.name, name, NOTIFY_MAX_NAME); self->tsap = irttp_open_tsap(tsap_sel, DEFAULT_INITIAL_CREDIT, ¬ify); if (self->tsap == NULL) { |
955a9d202 irda: Convert IRD... |
484 485 486 |
pr_debug("%s(), Unable to allocate TSAP! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
return -ENOMEM; } /* Remember which TSAP selector we actually got */ self->stsap_sel = self->tsap->stsap_sel; return 0; } /* * Function irda_open_lsap (self) * * Open local Link Service Access Point (LSAP). Used for opening Ultra * sockets */ #ifdef CONFIG_IRDA_ULTRA static int irda_open_lsap(struct irda_sock *self, int pid) { notify_t notify; if (self->lsap) { |
6c91023dc irda: Remove IRDA... |
507 508 |
net_warn_ratelimited("%s(), busy! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
509 510 511 512 513 514 515 516 517 518 519 |
return -EBUSY; } /* Initialize callbacks to be used by the IrDA stack */ irda_notify_init(¬ify); notify.udata_indication = irda_data_indication; notify.instance = self; strncpy(notify.name, "Ultra", NOTIFY_MAX_NAME); self->lsap = irlmp_open_lsap(LSAP_CONNLESS, ¬ify, pid); if (self->lsap == NULL) { |
955a9d202 irda: Convert IRD... |
520 521 |
pr_debug("%s(), Unable to allocate LSAP! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
return -ENOMEM; } return 0; } #endif /* CONFIG_IRDA_ULTRA */ /* * Function irda_find_lsap_sel (self, name) * * Try to lookup LSAP selector in remote LM-IAS * * Basically, we start a IAP query, and then go to sleep. When the query * return, irda_getvalue_confirm will wake us up, and we can examine the * result of the query... * Note that in some case, the query fail even before we go to sleep, * creating some races... */ static int irda_find_lsap_sel(struct irda_sock *self, char *name) { |
955a9d202 irda: Convert IRD... |
542 543 |
pr_debug("%s(%p, %s) ", __func__, self, name); |
1da177e4c Linux-2.6.12-rc2 |
544 |
|
1da177e4c Linux-2.6.12-rc2 |
545 |
if (self->iriap) { |
6c91023dc irda: Remove IRDA... |
546 547 548 |
net_warn_ratelimited("%s(): busy with a previous query ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
return -EBUSY; } self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, irda_getvalue_confirm); if(self->iriap == NULL) return -ENOMEM; /* Treat unexpected wakeup as disconnect */ self->errno = -EHOSTUNREACH; /* Query remote LM-IAS */ iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr, name, "IrDA:TinyTP:LsapSel"); /* Wait for answer, if not yet finished (or failed) */ if (wait_event_interruptible(self->query_wait, (self->iriap==NULL))) /* Treat signals as disconnect */ return -EHOSTUNREACH; /* Check what happened */ if (self->errno) { /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) |
a02cec215 net: return opera... |
575 |
return -EADDRNOTAVAIL; |
1da177e4c Linux-2.6.12-rc2 |
576 |
else |
a02cec215 net: return opera... |
577 |
return -EHOSTUNREACH; |
1da177e4c Linux-2.6.12-rc2 |
578 579 580 581 582 |
} /* Get the remote TSAP selector */ switch (self->ias_result->type) { case IAS_INTEGER: |
955a9d202 irda: Convert IRD... |
583 584 585 |
pr_debug("%s() int=%d ", __func__, self->ias_result->t.integer); |
1da177e4c Linux-2.6.12-rc2 |
586 587 588 589 590 591 592 593 |
if (self->ias_result->t.integer != -1) self->dtsap_sel = self->ias_result->t.integer; else self->dtsap_sel = 0; break; default: self->dtsap_sel = 0; |
955a9d202 irda: Convert IRD... |
594 595 |
pr_debug("%s(), bad type! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 |
break; } if (self->ias_result) irias_delete_value(self->ias_result); if (self->dtsap_sel) return 0; return -EADDRNOTAVAIL; } /* * Function irda_discover_daddr_and_lsap_sel (self, name) * * This try to find a device with the requested service. * * It basically look into the discovery log. For each address in the list, * it queries the LM-IAS of the device to find if this device offer * the requested service. * If there is more than one node supporting the service, we complain * to the user (it should move devices around). * The, we set both the destination address and the lsap selector to point * on the service on the unique device we have found. * * Note : this function fails if there is more than one device in range, * because IrLMP doesn't disconnect the LAP when the last LSAP is closed. * Moreover, we would need to wait the LAP disconnection... */ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) { discinfo_t *discoveries; /* Copy of the discovery log */ int number; /* Number of nodes in the log */ int i; int err = -ENETUNREACH; __u32 daddr = DEV_ADDR_ANY; /* Address we found the service on */ __u8 dtsap_sel = 0x0; /* TSAP associated with it */ |
955a9d202 irda: Convert IRD... |
632 633 |
pr_debug("%s(), name=%s ", __func__, name); |
1da177e4c Linux-2.6.12-rc2 |
634 |
|
1da177e4c Linux-2.6.12-rc2 |
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 |
/* Ask lmp for the current discovery log * Note : we have to use irlmp_get_discoveries(), as opposed * to play with the cachelog directly, because while we are * making our ias query, le log might change... */ discoveries = irlmp_get_discoveries(&number, self->mask.word, self->nslots); /* Check if the we got some results */ if (discoveries == NULL) return -ENETUNREACH; /* No nodes discovered */ /* * Now, check all discovered devices (if any), and connect * client only about the services that the client is * interested in... */ for(i = 0; i < number; i++) { /* Try the address in the log */ self->daddr = discoveries[i].daddr; self->saddr = 0x0; |
955a9d202 irda: Convert IRD... |
654 655 656 |
pr_debug("%s(), trying daddr = %08x ", __func__, self->daddr); |
1da177e4c Linux-2.6.12-rc2 |
657 658 659 660 661 662 663 |
/* Query remote LM-IAS for this service */ err = irda_find_lsap_sel(self, name); switch (err) { case 0: /* We found the requested service */ if(daddr != DEV_ADDR_ANY) { |
955a9d202 irda: Convert IRD... |
664 665 666 |
pr_debug("%s(), discovered service ''%s'' in two different devices !!! ", __func__, name); |
1da177e4c Linux-2.6.12-rc2 |
667 668 |
self->daddr = DEV_ADDR_ANY; kfree(discoveries); |
a02cec215 net: return opera... |
669 |
return -ENOTUNIQ; |
1da177e4c Linux-2.6.12-rc2 |
670 671 672 673 674 675 676 677 678 679 |
} /* First time we found that one, save it ! */ daddr = self->daddr; dtsap_sel = self->dtsap_sel; break; case -EADDRNOTAVAIL: /* Requested service simply doesn't exist on this node */ break; default: /* Something bad did happen :-( */ |
955a9d202 irda: Convert IRD... |
680 681 682 |
pr_debug("%s(), unexpected IAS query failure ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
683 684 |
self->daddr = DEV_ADDR_ANY; kfree(discoveries); |
a02cec215 net: return opera... |
685 |
return -EHOSTUNREACH; |
1da177e4c Linux-2.6.12-rc2 |
686 687 688 689 690 691 692 |
} } /* Cleanup our copy of the discovery log */ kfree(discoveries); /* Check out what we found */ if(daddr == DEV_ADDR_ANY) { |
955a9d202 irda: Convert IRD... |
693 694 695 |
pr_debug("%s(), cannot discover service ''%s'' in any device !!! ", __func__, name); |
1da177e4c Linux-2.6.12-rc2 |
696 |
self->daddr = DEV_ADDR_ANY; |
a02cec215 net: return opera... |
697 |
return -EADDRNOTAVAIL; |
1da177e4c Linux-2.6.12-rc2 |
698 699 700 701 702 703 |
} /* Revert back to discovered device & service */ self->daddr = daddr; self->saddr = 0x0; self->dtsap_sel = dtsap_sel; |
955a9d202 irda: Convert IRD... |
704 705 706 |
pr_debug("%s(), discovered requested service ''%s'' at address %08x ", __func__, name, self->daddr); |
1da177e4c Linux-2.6.12-rc2 |
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
return 0; } /* * Function irda_getname (sock, uaddr, uaddr_len, peer) * * Return the our own, or peers socket address (sockaddr_irda) * */ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sockaddr_irda saddr; struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); |
09384dfc7 irda: Fix irda_ge... |
723 |
memset(&saddr, 0, sizeof(saddr)); |
1da177e4c Linux-2.6.12-rc2 |
724 725 |
if (peer) { if (sk->sk_state != TCP_ESTABLISHED) |
5b40964ea irda: Remove BKL ... |
726 |
return -ENOTCONN; |
1da177e4c Linux-2.6.12-rc2 |
727 728 729 730 731 732 733 734 735 |
saddr.sir_family = AF_IRDA; saddr.sir_lsap_sel = self->dtsap_sel; saddr.sir_addr = self->daddr; } else { saddr.sir_family = AF_IRDA; saddr.sir_lsap_sel = self->stsap_sel; saddr.sir_addr = self->saddr; } |
955a9d202 irda: Convert IRD... |
736 737 738 739 |
pr_debug("%s(), tsap_sel = %#x ", __func__, saddr.sir_lsap_sel); pr_debug("%s(), addr = %08x ", __func__, saddr.sir_addr); |
1da177e4c Linux-2.6.12-rc2 |
740 741 742 743 |
/* uaddr_len come to us uninitialised */ *uaddr_len = sizeof (struct sockaddr_irda); memcpy(uaddr, &saddr, *uaddr_len); |
5b40964ea irda: Remove BKL ... |
744 745 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
746 747 748 749 750 751 752 753 754 755 756 |
} /* * Function irda_listen (sock, backlog) * * Just move to the listen state * */ static int irda_listen(struct socket *sock, int backlog) { struct sock *sk = sock->sk; |
58a9d7320 net/irda: push BK... |
757 |
int err = -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
758 |
|
5b40964ea irda: Remove BKL ... |
759 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
760 761 |
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && (sk->sk_type != SOCK_DGRAM)) |
58a9d7320 net/irda: push BK... |
762 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
763 764 765 766 |
if (sk->sk_state != TCP_LISTEN) { sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; |
58a9d7320 net/irda: push BK... |
767 |
err = 0; |
1da177e4c Linux-2.6.12-rc2 |
768 |
} |
58a9d7320 net/irda: push BK... |
769 |
out: |
5b40964ea irda: Remove BKL ... |
770 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
771 |
|
58a9d7320 net/irda: push BK... |
772 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
} /* * Function irda_bind (sock, uaddr, addr_len) * * Used by servers to register their well known TSAP * */ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr; struct irda_sock *self = irda_sk(sk); int err; |
955a9d202 irda: Convert IRD... |
787 788 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
789 790 791 |
if (addr_len != sizeof(struct sockaddr_irda)) return -EINVAL; |
5b40964ea irda: Remove BKL ... |
792 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
793 794 795 796 797 |
#ifdef CONFIG_IRDA_ULTRA /* Special care for Ultra sockets */ if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) { self->pid = addr->sir_lsap_sel; |
58a9d7320 net/irda: push BK... |
798 |
err = -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
799 |
if (self->pid & 0x80) { |
955a9d202 irda: Convert IRD... |
800 801 802 |
pr_debug("%s(), extension in PID not supp! ", __func__); |
58a9d7320 net/irda: push BK... |
803 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
804 805 806 |
} err = irda_open_lsap(self, self->pid); if (err < 0) |
58a9d7320 net/irda: push BK... |
807 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
808 809 810 811 |
/* Pretend we are connected */ sock->state = SS_CONNECTED; sk->sk_state = TCP_ESTABLISHED; |
58a9d7320 net/irda: push BK... |
812 |
err = 0; |
1da177e4c Linux-2.6.12-rc2 |
813 |
|
58a9d7320 net/irda: push BK... |
814 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
815 816 |
} #endif /* CONFIG_IRDA_ULTRA */ |
61e44b481 [IrDA]: af_irda m... |
817 |
self->ias_obj = irias_new_object(addr->sir_name, jiffies); |
58a9d7320 net/irda: push BK... |
818 |
err = -ENOMEM; |
61e44b481 [IrDA]: af_irda m... |
819 |
if (self->ias_obj == NULL) |
58a9d7320 net/irda: push BK... |
820 |
goto out; |
61e44b481 [IrDA]: af_irda m... |
821 |
|
1da177e4c Linux-2.6.12-rc2 |
822 |
err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
61e44b481 [IrDA]: af_irda m... |
823 |
if (err < 0) { |
628e300cc irda: Correctly c... |
824 825 |
irias_delete_object(self->ias_obj); self->ias_obj = NULL; |
58a9d7320 net/irda: push BK... |
826 |
goto out; |
61e44b481 [IrDA]: af_irda m... |
827 |
} |
1da177e4c Linux-2.6.12-rc2 |
828 829 |
/* Register with LM-IAS */ |
1da177e4c Linux-2.6.12-rc2 |
830 831 832 |
irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel", self->stsap_sel, IAS_KERNEL_ATTR); irias_insert_object(self->ias_obj); |
58a9d7320 net/irda: push BK... |
833 834 |
err = 0; out: |
5b40964ea irda: Remove BKL ... |
835 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
836 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
837 838 839 840 841 842 843 844 845 846 847 848 849 |
} /* * Function irda_accept (sock, newsock, flags) * * Wait for incoming connection * */ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) { struct sock *sk = sock->sk; struct irda_sock *new, *self = irda_sk(sk); struct sock *newsk; |
8ab86c00e irda: Free skb on... |
850 |
struct sk_buff *skb = NULL; |
1da177e4c Linux-2.6.12-rc2 |
851 |
int err; |
3f378b684 net: pass kern to... |
852 |
err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); |
1da177e4c Linux-2.6.12-rc2 |
853 |
if (err) |
5b40964ea irda: Remove BKL ... |
854 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
855 |
|
58a9d7320 net/irda: push BK... |
856 |
err = -EINVAL; |
5b40964ea irda: Remove BKL ... |
857 858 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
859 |
if (sock->state != SS_UNCONNECTED) |
58a9d7320 net/irda: push BK... |
860 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
861 |
|
58a9d7320 net/irda: push BK... |
862 |
err = -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
863 864 |
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && (sk->sk_type != SOCK_DGRAM)) |
58a9d7320 net/irda: push BK... |
865 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
866 |
|
58a9d7320 net/irda: push BK... |
867 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
868 |
if (sk->sk_state != TCP_LISTEN) |
58a9d7320 net/irda: push BK... |
869 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
870 871 872 873 874 875 876 877 878 879 880 881 882 883 |
/* * The read queue this time is holding sockets ready to use * hooked into the SABM we saved */ /* * We can perform the accept only if there is incoming data * on the listening socket. * So, we will block the caller until we receive any data. * If the caller was waiting on select() or poll() before * calling us, the data is waiting for us ;-) * Jean II */ |
d7f48d1a9 [IrDA] af_irda: i... |
884 885 886 887 |
while (1) { skb = skb_dequeue(&sk->sk_receive_queue); if (skb) break; |
1da177e4c Linux-2.6.12-rc2 |
888 889 |
/* Non blocking operation */ |
58a9d7320 net/irda: push BK... |
890 |
err = -EWOULDBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
891 |
if (flags & O_NONBLOCK) |
58a9d7320 net/irda: push BK... |
892 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
893 |
|
aa3951451 net: sk_sleep() h... |
894 |
err = wait_event_interruptible(*(sk_sleep(sk)), |
d7f48d1a9 [IrDA] af_irda: i... |
895 896 |
skb_peek(&sk->sk_receive_queue)); if (err) |
58a9d7320 net/irda: push BK... |
897 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
898 899 900 |
} newsk = newsock->sk; |
58a9d7320 net/irda: push BK... |
901 |
err = -EIO; |
c3ea9fa27 [IrDA] af_irda: I... |
902 |
if (newsk == NULL) |
58a9d7320 net/irda: push BK... |
903 |
goto out; |
c3ea9fa27 [IrDA] af_irda: I... |
904 |
|
1da177e4c Linux-2.6.12-rc2 |
905 906 907 |
newsk->sk_state = TCP_ESTABLISHED; new = irda_sk(newsk); |
1da177e4c Linux-2.6.12-rc2 |
908 909 910 |
/* Now attach up the new socket */ new->tsap = irttp_dup(self->tsap, new); |
58a9d7320 net/irda: push BK... |
911 |
err = -EPERM; /* value does not seem to make sense. -arnd */ |
1da177e4c Linux-2.6.12-rc2 |
912 |
if (!new->tsap) { |
955a9d202 irda: Convert IRD... |
913 914 |
pr_debug("%s(), dup failed! ", __func__); |
58a9d7320 net/irda: push BK... |
915 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 |
} new->stsap_sel = new->tsap->stsap_sel; new->dtsap_sel = new->tsap->dtsap_sel; new->saddr = irttp_get_saddr(new->tsap); new->daddr = irttp_get_daddr(new->tsap); new->max_sdu_size_tx = self->max_sdu_size_tx; new->max_sdu_size_rx = self->max_sdu_size_rx; new->max_data_size = self->max_data_size; new->max_header_size = self->max_header_size; memcpy(&new->qos_tx, &self->qos_tx, sizeof(struct qos_info)); /* Clean up the original one to keep it in listen state */ irttp_listen(self->tsap); |
1da177e4c Linux-2.6.12-rc2 |
932 933 934 935 936 |
sk->sk_ack_backlog--; newsock->state = SS_CONNECTED; irda_connect_response(new); |
58a9d7320 net/irda: push BK... |
937 938 |
err = 0; out: |
8ab86c00e irda: Free skb on... |
939 |
kfree_skb(skb); |
5b40964ea irda: Remove BKL ... |
940 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
941 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
942 943 944 945 946 947 948 949 950 951 |
} /* * Function irda_connect (sock, uaddr, addr_len, flags) * * Connect to a IrDA device * * The main difference with a "standard" connect is that with IrDA we need * to resolve the service name into a TSAP selector (in TCP, port number * doesn't have to be resolved). |
ad8c94532 irda: Fix typo in... |
952 |
* Because of this service name resolution, we can offer "auto-connect", |
1da177e4c Linux-2.6.12-rc2 |
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 |
* where we connect to a service without specifying a destination address. * * Note : by consulting "errno", the user space caller may learn the cause * of the failure. Most of them are visible in the function, others may come * from subroutines called and are listed here : * o EBUSY : already processing a connect * o EHOSTUNREACH : bad addr->sir_addr argument * o EADDRNOTAVAIL : bad addr->sir_name argument * o ENOTUNIQ : more than one node has addr->sir_name (auto-connect) * o ENETUNREACH : no node found on the network (auto-connect) */ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { struct sock *sk = sock->sk; struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr; struct irda_sock *self = irda_sk(sk); int err; |
955a9d202 irda: Convert IRD... |
971 972 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
973 |
|
5b40964ea irda: Remove BKL ... |
974 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
975 |
/* Don't allow connect for Ultra sockets */ |
58a9d7320 net/irda: push BK... |
976 |
err = -ESOCKTNOSUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
977 |
if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) |
58a9d7320 net/irda: push BK... |
978 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
979 980 981 |
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { sock->state = SS_CONNECTED; |
58a9d7320 net/irda: push BK... |
982 983 |
err = 0; goto out; /* Connect completed during a ERESTARTSYS event */ |
1da177e4c Linux-2.6.12-rc2 |
984 985 986 987 |
} if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { sock->state = SS_UNCONNECTED; |
58a9d7320 net/irda: push BK... |
988 989 |
err = -ECONNREFUSED; goto out; |
1da177e4c Linux-2.6.12-rc2 |
990 |
} |
58a9d7320 net/irda: push BK... |
991 |
err = -EISCONN; /* No reconnect on a seqpacket socket */ |
1da177e4c Linux-2.6.12-rc2 |
992 |
if (sk->sk_state == TCP_ESTABLISHED) |
58a9d7320 net/irda: push BK... |
993 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
994 995 996 |
sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; |
58a9d7320 net/irda: push BK... |
997 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
998 |
if (addr_len != sizeof(struct sockaddr_irda)) |
58a9d7320 net/irda: push BK... |
999 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1000 1001 1002 1003 1004 1005 |
/* Check if user supplied any destination device address */ if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { /* Try to find one suitable */ err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); if (err) { |
955a9d202 irda: Convert IRD... |
1006 1007 |
pr_debug("%s(), auto-connect failed! ", __func__); |
58a9d7320 net/irda: push BK... |
1008 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1009 1010 1011 1012 |
} } else { /* Use the one provided by the user */ self->daddr = addr->sir_addr; |
955a9d202 irda: Convert IRD... |
1013 1014 |
pr_debug("%s(), daddr = %08x ", __func__, self->daddr); |
1da177e4c Linux-2.6.12-rc2 |
1015 1016 1017 1018 1019 1020 1021 1022 1023 |
/* If we don't have a valid service name, we assume the * user want to connect on a specific LSAP. Prevent * the use of invalid LSAPs (IrLMP 1.1 p10). Jean II */ if((addr->sir_name[0] != '\0') || (addr->sir_lsap_sel >= 0x70)) { /* Query remote LM-IAS using service name */ err = irda_find_lsap_sel(self, addr->sir_name); if (err) { |
955a9d202 irda: Convert IRD... |
1024 1025 |
pr_debug("%s(), connect failed! ", __func__); |
58a9d7320 net/irda: push BK... |
1026 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 |
} } else { /* Directly connect to the remote LSAP * specified by the sir_lsap field. * Please use with caution, in IrDA LSAPs are * dynamic and there is no "well-known" LSAP. */ self->dtsap_sel = addr->sir_lsap_sel; } } /* Check if we have opened a local TSAP */ |
d3e6952cf net/irda: fix NUL... |
1038 1039 1040 1041 1042 |
if (!self->tsap) { err = irda_open_tsap(self, LSAP_ANY, addr->sir_name); if (err) goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 |
/* Move to connecting socket, start sending Connect Requests */ sock->state = SS_CONNECTING; sk->sk_state = TCP_SYN_SENT; /* Connect to remote device */ err = irttp_connect_request(self->tsap, self->dtsap_sel, self->saddr, self->daddr, NULL, self->max_sdu_size_rx, NULL); if (err) { |
955a9d202 irda: Convert IRD... |
1053 1054 |
pr_debug("%s(), connect failed! ", __func__); |
58a9d7320 net/irda: push BK... |
1055 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1056 1057 1058 |
} /* Now the loop */ |
58a9d7320 net/irda: push BK... |
1059 |
err = -EINPROGRESS; |
1da177e4c Linux-2.6.12-rc2 |
1060 |
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) |
58a9d7320 net/irda: push BK... |
1061 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1062 |
|
58a9d7320 net/irda: push BK... |
1063 |
err = -ERESTARTSYS; |
aa3951451 net: sk_sleep() h... |
1064 |
if (wait_event_interruptible(*(sk_sleep(sk)), |
1da177e4c Linux-2.6.12-rc2 |
1065 |
(sk->sk_state != TCP_SYN_SENT))) |
58a9d7320 net/irda: push BK... |
1066 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1067 1068 1069 |
if (sk->sk_state != TCP_ESTABLISHED) { sock->state = SS_UNCONNECTED; |
6e66aa15d [IrDA] af_irda: S... |
1070 |
err = sock_error(sk); |
58a9d7320 net/irda: push BK... |
1071 1072 1073 |
if (!err) err = -ECONNRESET; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1074 1075 1076 1077 1078 1079 |
} sock->state = SS_CONNECTED; /* At this point, IrLMP has assigned our source address */ self->saddr = irttp_get_saddr(self->tsap); |
58a9d7320 net/irda: push BK... |
1080 1081 |
err = 0; out: |
5b40964ea irda: Remove BKL ... |
1082 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
1083 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 |
} static struct proto irda_proto = { .name = "IRDA", .owner = THIS_MODULE, .obj_size = sizeof(struct irda_sock), }; /* * Function irda_create (sock, protocol) * * Create IrDA socket * */ |
3f378b684 net: pass kern to... |
1098 1099 |
static int irda_create(struct net *net, struct socket *sock, int protocol, int kern) |
1da177e4c Linux-2.6.12-rc2 |
1100 1101 1102 |
{ struct sock *sk; struct irda_sock *self; |
79462ad02 net: add validati... |
1103 1104 |
if (protocol < 0 || protocol > SK_PROTOCOL_MAX) return -EINVAL; |
1b8d7ae42 [NET]: Make socke... |
1105 1106 |
if (net != &init_net) return -EAFNOSUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 |
/* Check for valid socket type */ switch (sock->type) { case SOCK_STREAM: /* For TTP connections with SAR disabled */ case SOCK_SEQPACKET: /* For TTP connections with SAR enabled */ case SOCK_DGRAM: /* For TTP Unitdata or LMP Ultra transfers */ break; default: return -ESOCKTNOSUPPORT; } /* Allocate networking socket */ |
11aa9c28b net: Pass kern fr... |
1118 |
sk = sk_alloc(net, PF_IRDA, GFP_KERNEL, &irda_proto, kern); |
1da177e4c Linux-2.6.12-rc2 |
1119 1120 1121 1122 |
if (sk == NULL) return -ENOMEM; self = irda_sk(sk); |
955a9d202 irda: Convert IRD... |
1123 1124 |
pr_debug("%s() : self is %p ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
1125 1126 |
init_waitqueue_head(&self->query_wait); |
1da177e4c Linux-2.6.12-rc2 |
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 |
switch (sock->type) { case SOCK_STREAM: sock->ops = &irda_stream_ops; self->max_sdu_size_rx = TTP_SAR_DISABLE; break; case SOCK_SEQPACKET: sock->ops = &irda_seqpacket_ops; self->max_sdu_size_rx = TTP_SAR_UNBOUND; break; case SOCK_DGRAM: switch (protocol) { #ifdef CONFIG_IRDA_ULTRA case IRDAPROTO_ULTRA: sock->ops = &irda_ultra_ops; /* Initialise now, because we may send on unbound * sockets. Jean II */ self->max_data_size = ULTRA_MAX_DATA - LMP_PID_HEADER; self->max_header_size = IRDA_MAX_HEADER + LMP_PID_HEADER; break; #endif /* CONFIG_IRDA_ULTRA */ case IRDAPROTO_UNITDATA: sock->ops = &irda_dgram_ops; /* We let Unitdata conn. be like seqpack conn. */ self->max_sdu_size_rx = TTP_SAR_UNBOUND; break; default: |
9ecad8779 irda: Sock leak o... |
1153 |
sk_free(sk); |
1da177e4c Linux-2.6.12-rc2 |
1154 1155 1156 1157 |
return -ESOCKTNOSUPPORT; } break; default: |
9ecad8779 irda: Sock leak o... |
1158 |
sk_free(sk); |
1da177e4c Linux-2.6.12-rc2 |
1159 1160 |
return -ESOCKTNOSUPPORT; } |
9ecad8779 irda: Sock leak o... |
1161 1162 1163 1164 |
/* Initialise networking socket struct */ sock_init_data(sock, sk); /* Note : set sk->sk_refcnt to 1 */ sk->sk_family = PF_IRDA; sk->sk_protocol = protocol; |
1da177e4c Linux-2.6.12-rc2 |
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 |
/* Register as a client with IrLMP */ self->ckey = irlmp_register_client(0, NULL, NULL, NULL); self->mask.word = 0xffff; self->rx_flow = self->tx_flow = FLOW_START; self->nslots = DISCOVERY_DEFAULT_SLOTS; self->daddr = DEV_ADDR_ANY; /* Until we get connected */ self->saddr = 0x0; /* so IrLMP assign us any link */ return 0; } /* * Function irda_destroy_socket (self) * * Destroy socket * */ static void irda_destroy_socket(struct irda_sock *self) { |
955a9d202 irda: Convert IRD... |
1183 1184 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
1185 |
|
1da177e4c Linux-2.6.12-rc2 |
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 |
/* Unregister with IrLMP */ irlmp_unregister_client(self->ckey); irlmp_unregister_service(self->skey); /* Unregister with LM-IAS */ if (self->ias_obj) { irias_delete_object(self->ias_obj); self->ias_obj = NULL; } if (self->iriap) { iriap_close(self->iriap); self->iriap = NULL; } if (self->tsap) { irttp_disconnect_request(self->tsap, NULL, P_NORMAL); irttp_close_tsap(self->tsap); self->tsap = NULL; } #ifdef CONFIG_IRDA_ULTRA if (self->lsap) { irlmp_close_lsap(self->lsap); self->lsap = NULL; } #endif /* CONFIG_IRDA_ULTRA */ } /* * Function irda_release (sock) */ static int irda_release(struct socket *sock) { struct sock *sk = sock->sk; |
6819bc2e1 [NET] IRDA: Fix w... |
1220 |
if (sk == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1221 |
return 0; |
da349f1c2 [IrDA]: af_irda.c... |
1222 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1223 1224 1225 1226 1227 1228 1229 1230 1231 |
sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_state_change(sk); /* Destroy IrDA socket */ irda_destroy_socket(irda_sk(sk)); sock_orphan(sk); sock->sk = NULL; |
da349f1c2 [IrDA]: af_irda.c... |
1232 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
/* Purge queues (see sock_init_data()) */ skb_queue_purge(&sk->sk_receive_queue); /* Destroy networking socket if we are the last reference on it, * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ sock_put(sk); /* Notes on socket locking and deallocation... - Jean II * In theory we should put pairs of sock_hold() / sock_put() to * prevent the socket to be destroyed whenever there is an * outstanding request or outstanding incoming packet or event. * * 1) This may include IAS request, both in connect and getsockopt. * Unfortunately, the situation is a bit more messy than it looks, * because we close iriap and kfree(self) above. * * 2) This may include selective discovery in getsockopt. * Same stuff as above, irlmp registration and self are gone. * * Probably 1 and 2 may not matter, because it's all triggered * by a process and the socket layer already prevent the * socket to go away while a process is holding it, through * sockfd_put() and fput()... * * 3) This may include deferred TSAP closure. In particular, * we may receive a late irda_disconnect_indication() * Fortunately, (tsap_cb *)->close_pend should protect us * from that. * * I did some testing on SMP, and it looks solid. And the socket * memory leak is now gone... - Jean II */ |
6819bc2e1 [NET] IRDA: Fix w... |
1266 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1267 1268 1269 |
} /* |
1b7841404 net: Remove iocb ... |
1270 |
* Function irda_sendmsg (sock, msg, len) |
1da177e4c Linux-2.6.12-rc2 |
1271 1272 1273 1274 1275 |
* * Send message down to TinyTP. This function is used for both STREAM and * SEQPACK services. This is possible since it forces the client to * fragment the message if necessary */ |
1b7841404 net: Remove iocb ... |
1276 |
static int irda_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
1277 1278 1279 1280 |
{ struct sock *sk = sock->sk; struct irda_sock *self; struct sk_buff *skb; |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1281 |
int err = -EPIPE; |
1da177e4c Linux-2.6.12-rc2 |
1282 |
|
955a9d202 irda: Convert IRD... |
1283 1284 |
pr_debug("%s(), len=%zd ", __func__, len); |
1da177e4c Linux-2.6.12-rc2 |
1285 1286 |
/* Note : socket.c set MSG_EOR on SEQPACKET sockets */ |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1287 |
if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | |
58a9d7320 net/irda: push BK... |
1288 |
MSG_NOSIGNAL)) { |
020318d0d irda: fix locking... |
1289 |
return -EINVAL; |
58a9d7320 net/irda: push BK... |
1290 |
} |
1da177e4c Linux-2.6.12-rc2 |
1291 |
|
5b40964ea irda: Remove BKL ... |
1292 |
lock_sock(sk); |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1293 1294 |
if (sk->sk_shutdown & SEND_SHUTDOWN) goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1295 |
|
58a9d7320 net/irda: push BK... |
1296 1297 1298 1299 |
if (sk->sk_state != TCP_ESTABLISHED) { err = -ENOTCONN; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1300 1301 |
self = irda_sk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1302 1303 |
/* Check if IrTTP is wants us to slow down */ |
aa3951451 net: sk_sleep() h... |
1304 |
if (wait_event_interruptible(*(sk_sleep(sk)), |
58a9d7320 net/irda: push BK... |
1305 1306 1307 1308 |
(self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) { err = -ERESTARTSYS; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1309 1310 |
/* Check if we are still connected */ |
58a9d7320 net/irda: push BK... |
1311 1312 1313 1314 |
if (sk->sk_state != TCP_ESTABLISHED) { err = -ENOTCONN; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1315 |
|
7f927fcc2 [PATCH] Typo fixes |
1316 |
/* Check that we don't send out too big frames */ |
1da177e4c Linux-2.6.12-rc2 |
1317 |
if (len > self->max_data_size) { |
955a9d202 irda: Convert IRD... |
1318 1319 1320 |
pr_debug("%s(), Chopping frame from %zd to %d bytes! ", __func__, len, self->max_data_size); |
1da177e4c Linux-2.6.12-rc2 |
1321 1322 |
len = self->max_data_size; } |
6819bc2e1 [NET] IRDA: Fix w... |
1323 |
skb = sock_alloc_send_skb(sk, len + self->max_header_size + 16, |
1da177e4c Linux-2.6.12-rc2 |
1324 1325 |
msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1326 |
goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1327 1328 |
skb_reserve(skb, self->max_header_size + 16); |
eeeb03745 [SK_BUFF]: More s... |
1329 1330 |
skb_reset_transport_header(skb); skb_put(skb, len); |
6ce8e9ce5 new helper: memcp... |
1331 |
err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1da177e4c Linux-2.6.12-rc2 |
1332 1333 |
if (err) { kfree_skb(skb); |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1334 |
goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1335 1336 1337 1338 1339 1340 1341 1342 |
} /* * Just send the message to TinyTP, and let it deal with possible * errors. No need to duplicate all that here */ err = irttp_data_request(self->tsap, skb); if (err) { |
955a9d202 irda: Convert IRD... |
1343 1344 |
pr_debug("%s(), err=%d ", __func__, err); |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1345 |
goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1346 |
} |
58a9d7320 net/irda: push BK... |
1347 |
|
5b40964ea irda: Remove BKL ... |
1348 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1349 1350 |
/* Tell client how much data we actually sent */ return len; |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1351 |
|
58a9d7320 net/irda: push BK... |
1352 1353 1354 |
out_err: err = sk_stream_error(sk, msg->msg_flags, err); out: |
5b40964ea irda: Remove BKL ... |
1355 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
1356 |
return err; |
bcb5e0eef [IrDA]: MSG_NOSIG... |
1357 |
|
1da177e4c Linux-2.6.12-rc2 |
1358 1359 1360 |
} /* |
1b7841404 net: Remove iocb ... |
1361 |
* Function irda_recvmsg_dgram (sock, msg, size, flags) |
1da177e4c Linux-2.6.12-rc2 |
1362 1363 1364 1365 |
* * Try to receive message and copy it to user. The frame is discarded * after being read, regardless of how much the user actually read */ |
1b7841404 net: Remove iocb ... |
1366 1367 |
static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg, size_t size, int flags) |
1da177e4c Linux-2.6.12-rc2 |
1368 1369 1370 1371 1372 1373 |
{ struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); struct sk_buff *skb; size_t copied; int err; |
1da177e4c Linux-2.6.12-rc2 |
1374 1375 1376 |
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); if (!skb) |
5b40964ea irda: Remove BKL ... |
1377 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1378 |
|
badff6d01 [SK_BUFF]: Introd... |
1379 1380 |
skb_reset_transport_header(skb); copied = skb->len; |
1da177e4c Linux-2.6.12-rc2 |
1381 1382 |
if (copied > size) { |
955a9d202 irda: Convert IRD... |
1383 1384 1385 |
pr_debug("%s(), Received truncated frame (%zd < %zd)! ", __func__, copied, size); |
1da177e4c Linux-2.6.12-rc2 |
1386 1387 1388 |
copied = size; msg->msg_flags |= MSG_TRUNC; } |
51f3d02b9 net: Add and use ... |
1389 |
skb_copy_datagram_msg(skb, 0, msg, copied); |
1da177e4c Linux-2.6.12-rc2 |
1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 |
skb_free_datagram(sk, skb); /* * Check if we have previously stopped IrTTP and we know * have more free space in our rx_queue. If so tell IrTTP * to start delivering frames again before our rx_queue gets * empty */ if (self->rx_flow == FLOW_STOP) { if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) { |
955a9d202 irda: Convert IRD... |
1401 1402 |
pr_debug("%s(), Starting IrTTP ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1403 1404 1405 1406 |
self->rx_flow = FLOW_START; irttp_flow_request(self->tsap, FLOW_START); } } |
58a9d7320 net/irda: push BK... |
1407 |
|
5b40964ea irda: Remove BKL ... |
1408 |
return copied; |
1da177e4c Linux-2.6.12-rc2 |
1409 1410 1411 |
} /* |
1b7841404 net: Remove iocb ... |
1412 |
* Function irda_recvmsg_stream (sock, msg, size, flags) |
1da177e4c Linux-2.6.12-rc2 |
1413 |
*/ |
1b7841404 net: Remove iocb ... |
1414 1415 |
static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, size_t size, int flags) |
1da177e4c Linux-2.6.12-rc2 |
1416 1417 1418 1419 1420 |
{ struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); int noblock = flags & MSG_DONTWAIT; size_t copied = 0; |
6e66aa15d [IrDA] af_irda: S... |
1421 |
int target, err; |
305f2aa18 [IrDA] af_irda: i... |
1422 |
long timeo; |
1da177e4c Linux-2.6.12-rc2 |
1423 |
|
6e66aa15d [IrDA] af_irda: S... |
1424 |
if ((err = sock_error(sk)) < 0) |
5b40964ea irda: Remove BKL ... |
1425 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1426 1427 |
if (sock->flags & __SO_ACCEPTCON) |
5b40964ea irda: Remove BKL ... |
1428 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1429 |
|
58a9d7320 net/irda: push BK... |
1430 |
err =-EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
1431 |
if (flags & MSG_OOB) |
5b40964ea irda: Remove BKL ... |
1432 |
return -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
1433 |
|
58a9d7320 net/irda: push BK... |
1434 |
err = 0; |
305f2aa18 [IrDA] af_irda: i... |
1435 1436 |
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); timeo = sock_rcvtimeo(sk, noblock); |
1da177e4c Linux-2.6.12-rc2 |
1437 |
|
1da177e4c Linux-2.6.12-rc2 |
1438 1439 1440 |
do { int chunk; struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); |
305f2aa18 [IrDA] af_irda: i... |
1441 1442 |
if (skb == NULL) { DEFINE_WAIT(wait); |
58a9d7320 net/irda: push BK... |
1443 |
err = 0; |
1da177e4c Linux-2.6.12-rc2 |
1444 1445 1446 |
if (copied >= target) break; |
aa3951451 net: sk_sleep() h... |
1447 |
prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1da177e4c Linux-2.6.12-rc2 |
1448 1449 1450 1451 |
/* * POSIX 1003.1g mandates this order. */ |
58a9d7320 net/irda: push BK... |
1452 1453 |
err = sock_error(sk); if (err) |
bfb6709d0 [IrDA]: Correctly... |
1454 |
; |
1da177e4c Linux-2.6.12-rc2 |
1455 1456 1457 |
else if (sk->sk_shutdown & RCV_SHUTDOWN) ; else if (noblock) |
58a9d7320 net/irda: push BK... |
1458 |
err = -EAGAIN; |
1da177e4c Linux-2.6.12-rc2 |
1459 |
else if (signal_pending(current)) |
58a9d7320 net/irda: push BK... |
1460 |
err = sock_intr_errno(timeo); |
305f2aa18 [IrDA] af_irda: i... |
1461 |
else if (sk->sk_state != TCP_ESTABLISHED) |
58a9d7320 net/irda: push BK... |
1462 |
err = -ENOTCONN; |
1da177e4c Linux-2.6.12-rc2 |
1463 1464 1465 |
else if (skb_peek(&sk->sk_receive_queue) == NULL) /* Wait process until data arrives */ schedule(); |
aa3951451 net: sk_sleep() h... |
1466 |
finish_wait(sk_sleep(sk), &wait); |
1da177e4c Linux-2.6.12-rc2 |
1467 |
|
58a9d7320 net/irda: push BK... |
1468 |
if (err) |
5b40964ea irda: Remove BKL ... |
1469 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1470 1471 1472 1473 1474 1475 1476 |
if (sk->sk_shutdown & RCV_SHUTDOWN) break; continue; } chunk = min_t(unsigned int, skb->len, size); |
7eab8d9e8 new helper: memcp... |
1477 |
if (memcpy_to_msg(msg, skb->data, chunk)) { |
1da177e4c Linux-2.6.12-rc2 |
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 |
skb_queue_head(&sk->sk_receive_queue, skb); if (copied == 0) copied = -EFAULT; break; } copied += chunk; size -= chunk; /* Mark read part of skb as used */ if (!(flags & MSG_PEEK)) { skb_pull(skb, chunk); /* put the skb back if we didn't use it up.. */ if (skb->len) { |
955a9d202 irda: Convert IRD... |
1492 1493 1494 |
pr_debug("%s(), back on q! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1495 1496 1497 1498 1499 1500 |
skb_queue_head(&sk->sk_receive_queue, skb); break; } kfree_skb(skb); } else { |
955a9d202 irda: Convert IRD... |
1501 1502 |
pr_debug("%s() questionable!? ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 |
/* put message back and return */ skb_queue_head(&sk->sk_receive_queue, skb); break; } } while (size); /* * Check if we have previously stopped IrTTP and we know * have more free space in our rx_queue. If so tell IrTTP * to start delivering frames again before our rx_queue gets * empty */ if (self->rx_flow == FLOW_STOP) { if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) { |
955a9d202 irda: Convert IRD... |
1518 1519 |
pr_debug("%s(), Starting IrTTP ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1520 1521 1522 1523 |
self->rx_flow = FLOW_START; irttp_flow_request(self->tsap, FLOW_START); } } |
5b40964ea irda: Remove BKL ... |
1524 |
return copied; |
1da177e4c Linux-2.6.12-rc2 |
1525 1526 1527 |
} /* |
1b7841404 net: Remove iocb ... |
1528 |
* Function irda_sendmsg_dgram (sock, msg, len) |
1da177e4c Linux-2.6.12-rc2 |
1529 1530 1531 1532 1533 |
* * Send message down to TinyTP for the unreliable sequenced * packet service... * */ |
1b7841404 net: Remove iocb ... |
1534 1535 |
static int irda_sendmsg_dgram(struct socket *sock, struct msghdr *msg, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
1536 1537 1538 1539 |
{ struct sock *sk = sock->sk; struct irda_sock *self; struct sk_buff *skb; |
1da177e4c Linux-2.6.12-rc2 |
1540 |
int err; |
955a9d202 irda: Convert IRD... |
1541 1542 |
pr_debug("%s(), len=%zd ", __func__, len); |
1da177e4c Linux-2.6.12-rc2 |
1543 1544 |
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
5b40964ea irda: Remove BKL ... |
1545 1546 1547 |
return -EINVAL; lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1548 1549 1550 |
if (sk->sk_shutdown & SEND_SHUTDOWN) { send_sig(SIGPIPE, current, 0); |
58a9d7320 net/irda: push BK... |
1551 1552 |
err = -EPIPE; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1553 |
} |
58a9d7320 net/irda: push BK... |
1554 |
err = -ENOTCONN; |
1da177e4c Linux-2.6.12-rc2 |
1555 |
if (sk->sk_state != TCP_ESTABLISHED) |
58a9d7320 net/irda: push BK... |
1556 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1557 1558 |
self = irda_sk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1559 1560 |
/* |
7f927fcc2 [PATCH] Typo fixes |
1561 |
* Check that we don't send out too big frames. This is an unreliable |
1da177e4c Linux-2.6.12-rc2 |
1562 1563 1564 |
* service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { |
955a9d202 irda: Convert IRD... |
1565 1566 1567 |
pr_debug("%s(), Warning too much data! Chopping frame from %zd to %d bytes! ", __func__, len, self->max_data_size); |
1da177e4c Linux-2.6.12-rc2 |
1568 1569 1570 1571 1572 |
len = self->max_data_size; } skb = sock_alloc_send_skb(sk, len + self->max_header_size, msg->msg_flags & MSG_DONTWAIT, &err); |
58a9d7320 net/irda: push BK... |
1573 |
err = -ENOBUFS; |
1da177e4c Linux-2.6.12-rc2 |
1574 |
if (!skb) |
58a9d7320 net/irda: push BK... |
1575 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1576 1577 |
skb_reserve(skb, self->max_header_size); |
eeeb03745 [SK_BUFF]: More s... |
1578 |
skb_reset_transport_header(skb); |
1da177e4c Linux-2.6.12-rc2 |
1579 |
|
955a9d202 irda: Convert IRD... |
1580 1581 |
pr_debug("%s(), appending user data ", __func__); |
eeeb03745 [SK_BUFF]: More s... |
1582 |
skb_put(skb, len); |
6ce8e9ce5 new helper: memcp... |
1583 |
err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1da177e4c Linux-2.6.12-rc2 |
1584 1585 |
if (err) { kfree_skb(skb); |
58a9d7320 net/irda: push BK... |
1586 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1587 1588 1589 1590 1591 1592 1593 1594 |
} /* * Just send the message to TinyTP, and let it deal with possible * errors. No need to duplicate all that here */ err = irttp_udata_request(self->tsap, skb); if (err) { |
955a9d202 irda: Convert IRD... |
1595 1596 |
pr_debug("%s(), err=%d ", __func__, err); |
58a9d7320 net/irda: push BK... |
1597 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1598 |
} |
5b40964ea irda: Remove BKL ... |
1599 1600 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1601 |
return len; |
5b40964ea irda: Remove BKL ... |
1602 |
|
58a9d7320 net/irda: push BK... |
1603 |
out: |
5b40964ea irda: Remove BKL ... |
1604 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
1605 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1606 1607 1608 |
} /* |
1b7841404 net: Remove iocb ... |
1609 |
* Function irda_sendmsg_ultra (sock, msg, len) |
1da177e4c Linux-2.6.12-rc2 |
1610 1611 1612 1613 1614 |
* * Send message down to IrLMP for the unreliable Ultra * packet service... */ #ifdef CONFIG_IRDA_ULTRA |
1b7841404 net: Remove iocb ... |
1615 1616 |
static int irda_sendmsg_ultra(struct socket *sock, struct msghdr *msg, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
1617 1618 1619 1620 1621 1622 |
{ struct sock *sk = sock->sk; struct irda_sock *self; __u8 pid = 0; int bound = 0; struct sk_buff *skb; |
1da177e4c Linux-2.6.12-rc2 |
1623 |
int err; |
955a9d202 irda: Convert IRD... |
1624 1625 |
pr_debug("%s(), len=%zd ", __func__, len); |
1da177e4c Linux-2.6.12-rc2 |
1626 |
|
58a9d7320 net/irda: push BK... |
1627 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1628 |
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
5b40964ea irda: Remove BKL ... |
1629 1630 1631 |
return -EINVAL; lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1632 |
|
58a9d7320 net/irda: push BK... |
1633 |
err = -EPIPE; |
1da177e4c Linux-2.6.12-rc2 |
1634 1635 |
if (sk->sk_shutdown & SEND_SHUTDOWN) { send_sig(SIGPIPE, current, 0); |
58a9d7320 net/irda: push BK... |
1636 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1637 1638 1639 |
} self = irda_sk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1640 1641 1642 |
/* Check if an address was specified with sendto. Jean II */ if (msg->msg_name) { |
342dfc306 net: add build-ti... |
1643 |
DECLARE_SOCKADDR(struct sockaddr_irda *, addr, msg->msg_name); |
58a9d7320 net/irda: push BK... |
1644 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1645 1646 |
/* Check address, extract pid. Jean II */ if (msg->msg_namelen < sizeof(*addr)) |
58a9d7320 net/irda: push BK... |
1647 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1648 |
if (addr->sir_family != AF_IRDA) |
58a9d7320 net/irda: push BK... |
1649 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1650 1651 1652 |
pid = addr->sir_lsap_sel; if (pid & 0x80) { |
955a9d202 irda: Convert IRD... |
1653 1654 1655 |
pr_debug("%s(), extension in PID not supp! ", __func__); |
58a9d7320 net/irda: push BK... |
1656 1657 |
err = -EOPNOTSUPP; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1658 1659 1660 1661 1662 1663 |
} } else { /* Check that the socket is properly bound to an Ultra * port. Jean II */ if ((self->lsap == NULL) || (sk->sk_state != TCP_ESTABLISHED)) { |
955a9d202 irda: Convert IRD... |
1664 1665 1666 |
pr_debug("%s(), socket not bound to Ultra PID. ", __func__); |
58a9d7320 net/irda: push BK... |
1667 1668 |
err = -ENOTCONN; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1669 1670 1671 1672 1673 1674 |
} /* Use PID from socket */ bound = 1; } /* |
7f927fcc2 [PATCH] Typo fixes |
1675 |
* Check that we don't send out too big frames. This is an unreliable |
1da177e4c Linux-2.6.12-rc2 |
1676 1677 1678 |
* service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { |
955a9d202 irda: Convert IRD... |
1679 1680 1681 |
pr_debug("%s(), Warning too much data! Chopping frame from %zd to %d bytes! ", __func__, len, self->max_data_size); |
1da177e4c Linux-2.6.12-rc2 |
1682 1683 1684 1685 1686 |
len = self->max_data_size; } skb = sock_alloc_send_skb(sk, len + self->max_header_size, msg->msg_flags & MSG_DONTWAIT, &err); |
58a9d7320 net/irda: push BK... |
1687 |
err = -ENOBUFS; |
1da177e4c Linux-2.6.12-rc2 |
1688 |
if (!skb) |
58a9d7320 net/irda: push BK... |
1689 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1690 1691 |
skb_reserve(skb, self->max_header_size); |
eeeb03745 [SK_BUFF]: More s... |
1692 |
skb_reset_transport_header(skb); |
1da177e4c Linux-2.6.12-rc2 |
1693 |
|
955a9d202 irda: Convert IRD... |
1694 1695 |
pr_debug("%s(), appending user data ", __func__); |
eeeb03745 [SK_BUFF]: More s... |
1696 |
skb_put(skb, len); |
6ce8e9ce5 new helper: memcp... |
1697 |
err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1da177e4c Linux-2.6.12-rc2 |
1698 1699 |
if (err) { kfree_skb(skb); |
58a9d7320 net/irda: push BK... |
1700 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1701 1702 1703 1704 |
} err = irlmp_connless_data_request((bound ? self->lsap : NULL), skb, pid); |
58a9d7320 net/irda: push BK... |
1705 |
if (err) |
955a9d202 irda: Convert IRD... |
1706 1707 |
pr_debug("%s(), err=%d ", __func__, err); |
58a9d7320 net/irda: push BK... |
1708 |
out: |
5b40964ea irda: Remove BKL ... |
1709 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
1710 |
return err ? : len; |
1da177e4c Linux-2.6.12-rc2 |
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 |
} #endif /* CONFIG_IRDA_ULTRA */ /* * Function irda_shutdown (sk, how) */ static int irda_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); |
955a9d202 irda: Convert IRD... |
1721 1722 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
1723 |
|
5b40964ea irda: Remove BKL ... |
1724 |
lock_sock(sk); |
58a9d7320 net/irda: push BK... |
1725 |
|
1da177e4c Linux-2.6.12-rc2 |
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 |
sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_state_change(sk); if (self->iriap) { iriap_close(self->iriap); self->iriap = NULL; } if (self->tsap) { irttp_disconnect_request(self->tsap, NULL, P_NORMAL); irttp_close_tsap(self->tsap); self->tsap = NULL; } /* A few cleanup so the socket look as good as new... */ self->rx_flow = self->tx_flow = FLOW_START; /* needed ??? */ self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ self->saddr = 0x0; /* so IrLMP assign us any link */ |
5b40964ea irda: Remove BKL ... |
1745 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
1746 |
|
6819bc2e1 [NET] IRDA: Fix w... |
1747 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 |
} /* * Function irda_poll (file, sock, wait) */ static unsigned int irda_poll(struct file * file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); unsigned int mask; |
aa3951451 net: sk_sleep() h... |
1759 |
poll_wait(file, sk_sleep(sk), wait); |
1da177e4c Linux-2.6.12-rc2 |
1760 1761 1762 1763 1764 1765 |
mask = 0; /* Exceptional events? */ if (sk->sk_err) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) { |
955a9d202 irda: Convert IRD... |
1766 1767 |
pr_debug("%s(), POLLHUP ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1768 1769 1770 1771 1772 |
mask |= POLLHUP; } /* Readable? */ if (!skb_queue_empty(&sk->sk_receive_queue)) { |
955a9d202 irda: Convert IRD... |
1773 1774 |
pr_debug("Socket is readable "); |
1da177e4c Linux-2.6.12-rc2 |
1775 1776 1777 1778 1779 1780 1781 |
mask |= POLLIN | POLLRDNORM; } /* Connection-based need to check for termination and startup */ switch (sk->sk_type) { case SOCK_STREAM: if (sk->sk_state == TCP_CLOSE) { |
955a9d202 irda: Convert IRD... |
1782 1783 |
pr_debug("%s(), POLLHUP ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 |
mask |= POLLHUP; } if (sk->sk_state == TCP_ESTABLISHED) { if ((self->tx_flow == FLOW_START) && sock_writeable(sk)) { mask |= POLLOUT | POLLWRNORM | POLLWRBAND; } } break; case SOCK_SEQPACKET: if ((self->tx_flow == FLOW_START) && sock_writeable(sk)) { mask |= POLLOUT | POLLWRNORM | POLLWRBAND; } break; case SOCK_DGRAM: if (sock_writeable(sk)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; break; default: break; } |
1da177e4c Linux-2.6.12-rc2 |
1809 |
|
5b40964ea irda: Remove BKL ... |
1810 |
return mask; |
58a9d7320 net/irda: push BK... |
1811 |
} |
1da177e4c Linux-2.6.12-rc2 |
1812 1813 1814 1815 1816 1817 |
/* * Function irda_ioctl (sock, cmd, arg) */ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; |
58a9d7320 net/irda: push BK... |
1818 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
1819 |
|
955a9d202 irda: Convert IRD... |
1820 1821 |
pr_debug("%s(), cmd=%#x ", __func__, cmd); |
1da177e4c Linux-2.6.12-rc2 |
1822 |
|
58a9d7320 net/irda: push BK... |
1823 |
err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1824 1825 1826 |
switch (cmd) { case TIOCOUTQ: { long amount; |
31e6d363a net: correct off-... |
1827 1828 |
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1da177e4c Linux-2.6.12-rc2 |
1829 1830 |
if (amount < 0) amount = 0; |
58a9d7320 net/irda: push BK... |
1831 1832 |
err = put_user(amount, (unsigned int __user *)arg); break; |
1da177e4c Linux-2.6.12-rc2 |
1833 1834 1835 1836 1837 1838 1839 1840 |
} case TIOCINQ: { struct sk_buff *skb; long amount = 0L; /* These two are safe on a single CPU system as only user tasks fiddle here */ if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; |
58a9d7320 net/irda: push BK... |
1841 1842 |
err = put_user(amount, (unsigned int __user *)arg); break; |
1da177e4c Linux-2.6.12-rc2 |
1843 1844 1845 1846 |
} case SIOCGSTAMP: if (sk != NULL) |
58a9d7320 net/irda: push BK... |
1847 1848 |
err = sock_get_timestamp(sk, (struct timeval __user *)arg); break; |
1da177e4c Linux-2.6.12-rc2 |
1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 |
case SIOCGIFADDR: case SIOCSIFADDR: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFBRDADDR: case SIOCSIFBRDADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: case SIOCGIFMETRIC: case SIOCSIFMETRIC: |
58a9d7320 net/irda: push BK... |
1860 |
break; |
1da177e4c Linux-2.6.12-rc2 |
1861 |
default: |
955a9d202 irda: Convert IRD... |
1862 1863 |
pr_debug("%s(), doing device ioctl! ", __func__); |
58a9d7320 net/irda: push BK... |
1864 |
err = -ENOIOCTLCMD; |
1da177e4c Linux-2.6.12-rc2 |
1865 |
} |
58a9d7320 net/irda: push BK... |
1866 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1867 |
} |
f6c90b71a [NET]: Fix ipx/ec... |
1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 |
#ifdef CONFIG_COMPAT /* * Function irda_ioctl (sock, cmd, arg) */ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { /* * All IRDA's ioctl are standard ones. */ return -ENOIOCTLCMD; } #endif |
1da177e4c Linux-2.6.12-rc2 |
1880 1881 1882 1883 1884 1885 |
/* * Function irda_setsockopt (sock, level, optname, optval, optlen) * * Set some options for the socket * */ |
5b40964ea irda: Remove BKL ... |
1886 |
static int irda_setsockopt(struct socket *sock, int level, int optname, |
b7058842c net: Make setsock... |
1887 |
char __user *optval, unsigned int optlen) |
1da177e4c Linux-2.6.12-rc2 |
1888 1889 1890 1891 1892 1893 |
{ struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); struct irda_ias_set *ias_opt; struct ias_object *ias_obj; struct ias_attrib * ias_attr; /* Attribute in IAS object */ |
5b40964ea irda: Remove BKL ... |
1894 |
int opt, free_ias = 0, err = 0; |
1da177e4c Linux-2.6.12-rc2 |
1895 |
|
955a9d202 irda: Convert IRD... |
1896 1897 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
1898 1899 1900 |
if (level != SOL_IRLMP) return -ENOPROTOOPT; |
5b40964ea irda: Remove BKL ... |
1901 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1902 1903 1904 1905 1906 1907 1908 1909 |
switch (optname) { case IRLMP_IAS_SET: /* The user want to add an attribute to an existing IAS object * (in the IAS database) or to create a new object with this * attribute. * We first query IAS to know if the object exist, and then * create the right attribute... */ |
5b40964ea irda: Remove BKL ... |
1910 1911 1912 1913 |
if (optlen != sizeof(struct irda_ias_set)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1914 1915 |
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
5b40964ea irda: Remove BKL ... |
1916 1917 1918 1919 |
if (ias_opt == NULL) { err = -ENOMEM; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1920 1921 1922 1923 |
/* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
1924 1925 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1926 1927 1928 1929 1930 1931 1932 1933 1934 |
} /* Find the object we target. * If the user gives us an empty string, we use the object * associated with this socket. This will workaround * duplicated class name - Jean II */ if(ias_opt->irda_class_name[0] == '\0') { if(self->ias_obj == NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
1935 1936 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 |
} ias_obj = self->ias_obj; } else ias_obj = irias_find_object(ias_opt->irda_class_name); /* Only ROOT can mess with the global IAS database. * Users can only add attributes to the object associated * with the socket they own - Jean II */ if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
1948 1949 |
err = -EPERM; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1950 1951 1952 1953 1954 1955 1956 |
} /* If the object doesn't exist, create it */ if(ias_obj == (struct ias_object *) NULL) { /* Create a new object */ ias_obj = irias_new_object(ias_opt->irda_class_name, jiffies); |
61e44b481 [IrDA]: af_irda m... |
1957 1958 |
if (ias_obj == NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
1959 1960 |
err = -ENOMEM; goto out; |
61e44b481 [IrDA]: af_irda m... |
1961 1962 |
} free_ias = 1; |
1da177e4c Linux-2.6.12-rc2 |
1963 1964 1965 1966 1967 |
} /* Do we have the attribute already ? */ if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) { kfree(ias_opt); |
61e44b481 [IrDA]: af_irda m... |
1968 1969 1970 1971 |
if (free_ias) { kfree(ias_obj->name); kfree(ias_obj); } |
5b40964ea irda: Remove BKL ... |
1972 1973 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 |
} /* Look at the type */ switch(ias_opt->irda_attrib_type) { case IAS_INTEGER: /* Add an integer attribute */ irias_add_integer_attrib( ias_obj, ias_opt->irda_attrib_name, ias_opt->attribute.irda_attrib_int, IAS_USER_ATTR); break; case IAS_OCT_SEQ: /* Check length */ if(ias_opt->attribute.irda_attrib_octet_seq.len > IAS_MAX_OCTET_STRING) { kfree(ias_opt); |
61e44b481 [IrDA]: af_irda m... |
1991 1992 1993 1994 |
if (free_ias) { kfree(ias_obj->name); kfree(ias_obj); } |
5b40964ea irda: Remove BKL ... |
1995 1996 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 |
} /* Add an octet sequence attribute */ irias_add_octseq_attrib( ias_obj, ias_opt->irda_attrib_name, ias_opt->attribute.irda_attrib_octet_seq.octet_seq, ias_opt->attribute.irda_attrib_octet_seq.len, IAS_USER_ATTR); break; case IAS_STRING: /* Should check charset & co */ /* Check length */ /* The length is encoded in a __u8, and * IAS_MAX_STRING == 256, so there is no way * userspace can pass us a string too large. * Jean II */ /* NULL terminate the string (avoid troubles) */ ias_opt->attribute.irda_attrib_string.string[ias_opt->attribute.irda_attrib_string.len] = '\0'; /* Add a string attribute */ irias_add_string_attrib( ias_obj, ias_opt->irda_attrib_name, ias_opt->attribute.irda_attrib_string.string, IAS_USER_ATTR); break; default : kfree(ias_opt); |
61e44b481 [IrDA]: af_irda m... |
2024 2025 2026 2027 |
if (free_ias) { kfree(ias_obj->name); kfree(ias_obj); } |
5b40964ea irda: Remove BKL ... |
2028 2029 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2030 2031 2032 2033 2034 2035 2036 2037 2038 |
} irias_insert_object(ias_obj); kfree(ias_opt); break; case IRLMP_IAS_DEL: /* The user want to delete an object from our local IAS * database. We just need to query the IAS, check is the * object is not owned by the kernel and delete it. */ |
5b40964ea irda: Remove BKL ... |
2039 2040 2041 2042 |
if (optlen != sizeof(struct irda_ias_set)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2043 2044 |
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
5b40964ea irda: Remove BKL ... |
2045 2046 2047 2048 |
if (ias_opt == NULL) { err = -ENOMEM; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2049 2050 2051 2052 |
/* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2053 2054 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
} /* Find the object we target. * If the user gives us an empty string, we use the object * associated with this socket. This will workaround * duplicated class name - Jean II */ if(ias_opt->irda_class_name[0] == '\0') ias_obj = self->ias_obj; else ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2067 2068 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2069 2070 2071 2072 2073 2074 2075 2076 |
} /* Only ROOT can mess with the global IAS database. * Users can only del attributes from the object associated * with the socket they own - Jean II */ if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2077 2078 |
err = -EPERM; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2079 2080 2081 2082 2083 2084 2085 |
} /* Find the attribute (in the object) we target */ ias_attr = irias_find_attrib(ias_obj, ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2086 2087 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2088 2089 2090 2091 |
} /* Check is the user space own the object */ if(ias_attr->value->owner != IAS_USER_ATTR) { |
955a9d202 irda: Convert IRD... |
2092 2093 2094 |
pr_debug("%s(), attempting to delete a kernel attribute ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
2095 |
kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2096 2097 |
err = -EPERM; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2098 2099 2100 2101 2102 2103 2104 |
} /* Remove the attribute (and maybe the object) */ irias_delete_attrib(ias_obj, ias_attr, 1); kfree(ias_opt); break; case IRLMP_MAX_SDU_SIZE: |
5b40964ea irda: Remove BKL ... |
2105 2106 2107 2108 |
if (optlen < sizeof(int)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2109 |
|
5b40964ea irda: Remove BKL ... |
2110 2111 2112 2113 |
if (get_user(opt, (int __user *)optval)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2114 2115 2116 |
/* Only possible for a seqpacket service (TTP with SAR) */ if (sk->sk_type != SOCK_SEQPACKET) { |
955a9d202 irda: Convert IRD... |
2117 2118 2119 |
pr_debug("%s(), setting max_sdu_size = %d ", __func__, opt); |
1da177e4c Linux-2.6.12-rc2 |
2120 2121 |
self->max_sdu_size_rx = opt; } else { |
6c91023dc irda: Remove IRDA... |
2122 2123 2124 |
net_warn_ratelimited("%s: not allowed to set MAXSDUSIZE for this socket type! ", __func__); |
5b40964ea irda: Remove BKL ... |
2125 2126 |
err = -ENOPROTOOPT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2127 2128 2129 |
} break; case IRLMP_HINTS_SET: |
5b40964ea irda: Remove BKL ... |
2130 2131 2132 2133 |
if (optlen < sizeof(int)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2134 2135 |
/* The input is really a (__u8 hints[2]), easier as an int */ |
5b40964ea irda: Remove BKL ... |
2136 2137 2138 2139 |
if (get_user(opt, (int __user *)optval)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2140 2141 |
/* Unregister any old registration */ |
37b8e1ca0 irda: Delete an u... |
2142 |
irlmp_unregister_service(self->skey); |
1da177e4c Linux-2.6.12-rc2 |
2143 2144 2145 2146 2147 2148 2149 2150 2151 |
self->skey = irlmp_register_service((__u16) opt); break; case IRLMP_HINT_MASK_SET: /* As opposed to the previous case which set the hint bits * that we advertise, this one set the filter we use when * making a discovery (nodes which don't match any hint * bit in the mask are not reported). */ |
5b40964ea irda: Remove BKL ... |
2152 2153 2154 2155 |
if (optlen < sizeof(int)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2156 2157 |
/* The input is really a (__u8 hints[2]), easier as an int */ |
5b40964ea irda: Remove BKL ... |
2158 2159 2160 2161 |
if (get_user(opt, (int __user *)optval)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 |
/* Set the new hint mask */ self->mask.word = (__u16) opt; /* Mask out extension bits */ self->mask.word &= 0x7f7f; /* Check if no bits */ if(!self->mask.word) self->mask.word = 0xFFFF; break; default: |
5b40964ea irda: Remove BKL ... |
2173 2174 |
err = -ENOPROTOOPT; break; |
1da177e4c Linux-2.6.12-rc2 |
2175 |
} |
1da177e4c Linux-2.6.12-rc2 |
2176 |
|
5b40964ea irda: Remove BKL ... |
2177 2178 |
out: release_sock(sk); |
58a9d7320 net/irda: push BK... |
2179 2180 2181 |
return err; } |
1da177e4c Linux-2.6.12-rc2 |
2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 |
/* * Function irda_extract_ias_value(ias_opt, ias_value) * * Translate internal IAS value structure to the user space representation * * The external representation of IAS values, as we exchange them with * user space program is quite different from the internal representation, * as stored in the IAS database (because we need a flat structure for * crossing kernel boundary). * This function transform the former in the latter. We also check * that the value type is valid. */ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, struct ias_value *ias_value) { /* Look at the type */ switch (ias_value->type) { case IAS_INTEGER: /* Copy the integer */ ias_opt->attribute.irda_attrib_int = ias_value->t.integer; break; case IAS_OCT_SEQ: /* Set length */ ias_opt->attribute.irda_attrib_octet_seq.len = ias_value->len; /* Copy over */ memcpy(ias_opt->attribute.irda_attrib_octet_seq.octet_seq, ias_value->t.oct_seq, ias_value->len); break; case IAS_STRING: /* Set length */ ias_opt->attribute.irda_attrib_string.len = ias_value->len; ias_opt->attribute.irda_attrib_string.charset = ias_value->charset; /* Copy over */ memcpy(ias_opt->attribute.irda_attrib_string.string, ias_value->t.string, ias_value->len); /* NULL terminate the string (avoid troubles) */ ias_opt->attribute.irda_attrib_string.string[ias_value->len] = '\0'; break; case IAS_MISSING: default : return -EINVAL; } /* Copy type over */ ias_opt->irda_attrib_type = ias_value->type; return 0; } /* * Function irda_getsockopt (sock, level, optname, optval, optlen) */ |
5b40964ea irda: Remove BKL ... |
2234 |
static int irda_getsockopt(struct socket *sock, int level, int optname, |
1da177e4c Linux-2.6.12-rc2 |
2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 |
char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); struct irda_device_list list; struct irda_device_info *discoveries; struct irda_ias_set * ias_opt; /* IAS get/query params */ struct ias_object * ias_obj; /* Object in IAS */ struct ias_attrib * ias_attr; /* Attribute in IAS object */ int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ int val = 0; int len = 0; |
5b40964ea irda: Remove BKL ... |
2247 |
int err = 0; |
1da177e4c Linux-2.6.12-rc2 |
2248 |
int offset, total; |
955a9d202 irda: Convert IRD... |
2249 2250 |
pr_debug("%s(%p) ", __func__, self); |
1da177e4c Linux-2.6.12-rc2 |
2251 2252 2253 2254 2255 2256 2257 2258 2259 |
if (level != SOL_IRLMP) return -ENOPROTOOPT; if (get_user(len, optlen)) return -EFAULT; if(len < 0) return -EINVAL; |
5b40964ea irda: Remove BKL ... |
2260 |
lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
2261 2262 |
switch (optname) { case IRLMP_ENUMDEVICES: |
fdac1e069 irda: prevent int... |
2263 2264 2265 2266 2267 2268 2269 2270 2271 |
/* Offset to first device entry */ offset = sizeof(struct irda_device_list) - sizeof(struct irda_device_info); if (len < offset) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2272 2273 2274 2275 |
/* Ask lmp for the current discovery log */ discoveries = irlmp_get_discoveries(&list.len, self->mask.word, self->nslots); /* Check if the we got some results */ |
5b40964ea irda: Remove BKL ... |
2276 2277 2278 2279 |
if (discoveries == NULL) { err = -EAGAIN; goto out; /* Didn't find any devices */ } |
1da177e4c Linux-2.6.12-rc2 |
2280 2281 |
/* Write total list length back to client */ |
fdac1e069 irda: prevent int... |
2282 |
if (copy_to_user(optval, &list, offset)) |
1da177e4c Linux-2.6.12-rc2 |
2283 |
err = -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
2284 |
/* Copy the list itself - watch for overflow */ |
5b40964ea irda: Remove BKL ... |
2285 |
if (list.len > 2048) { |
1da177e4c Linux-2.6.12-rc2 |
2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 |
err = -EINVAL; goto bed; } total = offset + (list.len * sizeof(struct irda_device_info)); if (total > len) total = len; if (copy_to_user(optval+offset, discoveries, total - offset)) err = -EFAULT; /* Write total number of bytes used back to client */ if (put_user(total, optlen)) err = -EFAULT; bed: /* Free up our buffer */ kfree(discoveries); |
1da177e4c Linux-2.6.12-rc2 |
2301 2302 2303 2304 |
break; case IRLMP_MAX_SDU_SIZE: val = self->max_data_size; len = sizeof(int); |
5b40964ea irda: Remove BKL ... |
2305 2306 2307 2308 2309 2310 2311 2312 2313 |
if (put_user(len, optlen)) { err = -EFAULT; goto out; } if (copy_to_user(optval, &val, len)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2314 |
|
1da177e4c Linux-2.6.12-rc2 |
2315 2316 2317 2318 2319 2320 2321 |
break; case IRLMP_IAS_GET: /* The user want an object from our local IAS database. * We just need to query the IAS and return the value * that we found */ /* Check that the user has allocated the right space for us */ |
5b40964ea irda: Remove BKL ... |
2322 2323 2324 2325 |
if (len != sizeof(struct irda_ias_set)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2326 2327 |
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
5b40964ea irda: Remove BKL ... |
2328 2329 2330 2331 |
if (ias_opt == NULL) { err = -ENOMEM; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2332 2333 2334 2335 |
/* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2336 2337 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 |
} /* Find the object we target. * If the user gives us an empty string, we use the object * associated with this socket. This will workaround * duplicated class name - Jean II */ if(ias_opt->irda_class_name[0] == '\0') ias_obj = self->ias_obj; else ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2350 2351 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2352 2353 2354 2355 2356 2357 2358 |
} /* Find the attribute (in the object) we target */ ias_attr = irias_find_attrib(ias_obj, ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2359 2360 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2361 2362 2363 2364 2365 2366 |
} /* Translate from internal to user structure */ err = irda_extract_ias_value(ias_opt, ias_attr->value); if(err) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2367 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
2368 2369 2370 2371 2372 2373 |
} /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2374 2375 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 |
} /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); break; case IRLMP_IAS_QUERY: /* The user want an object from a remote IAS database. * We need to use IAP to query the remote database and * then wait for the answer to come back. */ /* Check that the user has allocated the right space for us */ |
5b40964ea irda: Remove BKL ... |
2386 2387 2388 2389 |
if (len != sizeof(struct irda_ias_set)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2390 2391 |
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
5b40964ea irda: Remove BKL ... |
2392 2393 2394 2395 |
if (ias_opt == NULL) { err = -ENOMEM; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2396 2397 2398 2399 |
/* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2400 2401 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 |
} /* At this point, there are two cases... * 1) the socket is connected - that's the easy case, we * just query the device we are connected to... * 2) the socket is not connected - the user doesn't want * to connect and/or may not have a valid service name * (so can't create a fake connection). In this case, * we assume that the user pass us a valid destination * address in the requesting structure... */ if(self->daddr != DEV_ADDR_ANY) { /* We are connected - reuse known daddr */ daddr = self->daddr; } else { /* We are not connected, we must specify a valid * destination address */ daddr = ias_opt->daddr; if((!daddr) || (daddr == DEV_ADDR_ANY)) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2422 2423 |
err = -EINVAL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2424 2425 2426 2427 2428 |
} } /* Check that we can proceed with IAP */ if (self->iriap) { |
6c91023dc irda: Remove IRDA... |
2429 2430 2431 |
net_warn_ratelimited("%s: busy with a previous query ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
2432 |
kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2433 2434 |
err = -EBUSY; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2435 2436 2437 2438 2439 2440 2441 |
} self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, irda_getvalue_confirm); if (self->iriap == NULL) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2442 2443 |
err = -ENOMEM; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 |
} /* Treat unexpected wakeup as disconnect */ self->errno = -EHOSTUNREACH; /* Query remote LM-IAS */ iriap_getvaluebyclass_request(self->iriap, self->saddr, daddr, ias_opt->irda_class_name, ias_opt->irda_attrib_name); /* Wait for answer, if not yet finished (or failed) */ if (wait_event_interruptible(self->query_wait, (self->iriap == NULL))) { /* pending request uses copy of ias_opt-content * we can free it regardless! */ kfree(ias_opt); /* Treat signals as disconnect */ |
5b40964ea irda: Remove BKL ... |
2462 2463 |
err = -EHOSTUNREACH; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2464 2465 2466 2467 2468 2469 2470 2471 2472 |
} /* Check what happened */ if (self->errno) { kfree(ias_opt); /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) |
5b40964ea irda: Remove BKL ... |
2473 |
err = -EADDRNOTAVAIL; |
1da177e4c Linux-2.6.12-rc2 |
2474 |
else |
5b40964ea irda: Remove BKL ... |
2475 2476 2477 |
err = -EHOSTUNREACH; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2478 2479 2480 2481 2482 2483 2484 2485 |
} /* Translate from internal to user structure */ err = irda_extract_ias_value(ias_opt, self->ias_result); if (self->ias_result) irias_delete_value(self->ias_result); if (err) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2486 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
2487 2488 2489 2490 2491 2492 |
} /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); |
5b40964ea irda: Remove BKL ... |
2493 2494 |
err = -EFAULT; goto out; |
1da177e4c Linux-2.6.12-rc2 |
2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 |
} /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); break; case IRLMP_WAITDEVICE: /* This function is just another way of seeing life ;-) * IRLMP_ENUMDEVICES assumes that you have a static network, * and that you just want to pick one of the devices present. * On the other hand, in here we assume that no device is * present and that at some point in the future a device will * come into range. When this device arrive, we just wake * up the caller, so that he has time to connect to it before * the device goes away... * Note : once the node has been discovered for more than a * few second, it won't trigger this function, unless it * goes away and come back changes its hint bits (so we * might call it IRLMP_WAITNEWDEVICE). */ /* Check that the user is passing us an int */ |
5b40964ea irda: Remove BKL ... |
2515 2516 2517 2518 |
if (len != sizeof(int)) { err = -EINVAL; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2519 |
/* Get timeout in ms (max time we block the caller) */ |
5b40964ea irda: Remove BKL ... |
2520 2521 2522 2523 |
if (get_user(val, (int __user *)optval)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 |
/* Tell IrLMP we want to be notified */ irlmp_update_client(self->ckey, self->mask.word, irda_selective_discovery_indication, NULL, (void *) self); /* Do some discovery (and also return cached results) */ irlmp_discovery_request(self->nslots); /* Wait until a node is discovered */ if (!self->cachedaddr) { |
955a9d202 irda: Convert IRD... |
2535 2536 2537 |
pr_debug("%s(), nothing discovered yet, going to sleep... ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
2538 2539 2540 |
/* Set watchdog timer to expire in <val> ms. */ self->errno = 0; |
b24b8a247 [NET]: Convert in... |
2541 2542 |
setup_timer(&self->watchdog, irda_discovery_timeout, (unsigned long)self); |
7d6c429b2 irda: use msecs_t... |
2543 2544 |
mod_timer(&self->watchdog, jiffies + msecs_to_jiffies(val)); |
1da177e4c Linux-2.6.12-rc2 |
2545 2546 |
/* Wait for IR-LMP to call us back */ |
35a2af94c sched/wait: Make ... |
2547 2548 |
err = __wait_event_interruptible(self->query_wait, (self->cachedaddr != 0 || self->errno == -ETIME)); |
1da177e4c Linux-2.6.12-rc2 |
2549 2550 |
/* If watchdog is still activated, kill it! */ |
25cc4ae91 net: remove redun... |
2551 |
del_timer(&(self->watchdog)); |
1da177e4c Linux-2.6.12-rc2 |
2552 |
|
955a9d202 irda: Convert IRD... |
2553 2554 |
pr_debug("%s(), ...waking up ! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
2555 |
|
5b40964ea irda: Remove BKL ... |
2556 2557 |
if (err != 0) goto out; |
1da177e4c Linux-2.6.12-rc2 |
2558 2559 |
} else |
955a9d202 irda: Convert IRD... |
2560 2561 2562 |
pr_debug("%s(), found immediately ! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
2563 2564 2565 2566 2567 2568 |
/* Tell IrLMP that we have been notified */ irlmp_update_client(self->ckey, self->mask.word, NULL, NULL, NULL); /* Check if the we got some results */ |
896ee0eee net/irda: add mis... |
2569 2570 2571 2572 |
if (!self->cachedaddr) { err = -EAGAIN; /* Didn't find any devices */ goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 |
daddr = self->cachedaddr; /* Cleanup */ self->cachedaddr = 0; /* We return the daddr of the device that trigger the * wakeup. As irlmp pass us only the new devices, we * are sure that it's not an old device. * If the user want more details, he should query * the whole discovery log and pick one device... */ |
5b40964ea irda: Remove BKL ... |
2583 2584 2585 2586 |
if (put_user(daddr, (int __user *)optval)) { err = -EFAULT; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2587 2588 2589 |
break; default: |
5b40964ea irda: Remove BKL ... |
2590 |
err = -ENOPROTOOPT; |
1da177e4c Linux-2.6.12-rc2 |
2591 |
} |
5b40964ea irda: Remove BKL ... |
2592 |
out: |
58a9d7320 net/irda: push BK... |
2593 |
|
5b40964ea irda: Remove BKL ... |
2594 |
release_sock(sk); |
58a9d7320 net/irda: push BK... |
2595 2596 2597 |
return err; } |
ec1b4cf74 net: mark net_pro... |
2598 |
static const struct net_proto_family irda_family_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2599 2600 2601 2602 |
.family = PF_IRDA, .create = irda_create, .owner = THIS_MODULE, }; |
58a9d7320 net/irda: push BK... |
2603 |
static const struct proto_ops irda_stream_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 |
.family = PF_IRDA, .owner = THIS_MODULE, .release = irda_release, .bind = irda_bind, .connect = irda_connect, .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, .poll = irda_poll, .ioctl = irda_ioctl, |
f6c90b71a [NET]: Fix ipx/ec... |
2614 2615 2616 |
#ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
2617 2618 2619 2620 2621 2622 2623 2624 2625 |
.listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, .getsockopt = irda_getsockopt, .sendmsg = irda_sendmsg, .recvmsg = irda_recvmsg_stream, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; |
58a9d7320 net/irda: push BK... |
2626 |
static const struct proto_ops irda_seqpacket_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2627 2628 2629 2630 2631 2632 2633 2634 |
.family = PF_IRDA, .owner = THIS_MODULE, .release = irda_release, .bind = irda_bind, .connect = irda_connect, .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, |
5b40964ea irda: Remove BKL ... |
2635 |
.poll = datagram_poll, |
1da177e4c Linux-2.6.12-rc2 |
2636 |
.ioctl = irda_ioctl, |
f6c90b71a [NET]: Fix ipx/ec... |
2637 2638 2639 |
#ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
2640 2641 2642 2643 2644 2645 2646 2647 2648 |
.listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, .getsockopt = irda_getsockopt, .sendmsg = irda_sendmsg, .recvmsg = irda_recvmsg_dgram, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; |
58a9d7320 net/irda: push BK... |
2649 |
static const struct proto_ops irda_dgram_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2650 2651 2652 2653 2654 2655 2656 2657 |
.family = PF_IRDA, .owner = THIS_MODULE, .release = irda_release, .bind = irda_bind, .connect = irda_connect, .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, |
5b40964ea irda: Remove BKL ... |
2658 |
.poll = datagram_poll, |
1da177e4c Linux-2.6.12-rc2 |
2659 |
.ioctl = irda_ioctl, |
f6c90b71a [NET]: Fix ipx/ec... |
2660 2661 2662 |
#ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 |
.listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, .getsockopt = irda_getsockopt, .sendmsg = irda_sendmsg_dgram, .recvmsg = irda_recvmsg_dgram, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; #ifdef CONFIG_IRDA_ULTRA |
58a9d7320 net/irda: push BK... |
2674 |
static const struct proto_ops irda_ultra_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2675 2676 2677 2678 2679 2680 2681 2682 |
.family = PF_IRDA, .owner = THIS_MODULE, .release = irda_release, .bind = irda_bind, .connect = sock_no_connect, .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = irda_getname, |
5b40964ea irda: Remove BKL ... |
2683 |
.poll = datagram_poll, |
1da177e4c Linux-2.6.12-rc2 |
2684 |
.ioctl = irda_ioctl, |
f6c90b71a [NET]: Fix ipx/ec... |
2685 2686 2687 |
#ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 |
.listen = sock_no_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, .getsockopt = irda_getsockopt, .sendmsg = irda_sendmsg_ultra, .recvmsg = irda_recvmsg_dgram, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; #endif /* CONFIG_IRDA_ULTRA */ |
1da177e4c Linux-2.6.12-rc2 |
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 |
/* * Function irsock_init (pro) * * Initialize IrDA protocol * */ int __init irsock_init(void) { int rc = proto_register(&irda_proto, 0); if (rc == 0) rc = sock_register(&irda_family_ops); return rc; } /* * Function irsock_cleanup (void) * * Remove IrDA protocol * */ |
75a69ac6d [IrDA]: Fix IrDA ... |
2720 |
void irsock_cleanup(void) |
1da177e4c Linux-2.6.12-rc2 |
2721 2722 2723 2724 |
{ sock_unregister(PF_IRDA); proto_unregister(&irda_proto); } |