diff options
Diffstat (limited to 'drivers/isdn/mISDN/socket.c')
-rw-r--r-- | drivers/isdn/mISDN/socket.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 37a2de18cfd0..508945d1b9c1 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c | |||
@@ -381,7 +381,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
381 | memcpy(di.channelmap, dev->channelmap, | 381 | memcpy(di.channelmap, dev->channelmap, |
382 | sizeof(di.channelmap)); | 382 | sizeof(di.channelmap)); |
383 | di.nrbchan = dev->nrbchan; | 383 | di.nrbchan = dev->nrbchan; |
384 | strcpy(di.name, dev->name); | 384 | strcpy(di.name, dev_name(&dev->dev)); |
385 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) | 385 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) |
386 | err = -EFAULT; | 386 | err = -EFAULT; |
387 | } else | 387 | } else |
@@ -460,6 +460,8 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
460 | { | 460 | { |
461 | struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; | 461 | struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; |
462 | struct sock *sk = sock->sk; | 462 | struct sock *sk = sock->sk; |
463 | struct hlist_node *node; | ||
464 | struct sock *csk; | ||
463 | int err = 0; | 465 | int err = 0; |
464 | 466 | ||
465 | if (*debug & DEBUG_SOCKET) | 467 | if (*debug & DEBUG_SOCKET) |
@@ -480,6 +482,26 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
480 | err = -ENODEV; | 482 | err = -ENODEV; |
481 | goto done; | 483 | goto done; |
482 | } | 484 | } |
485 | |||
486 | if (sk->sk_protocol < ISDN_P_B_START) { | ||
487 | read_lock_bh(&data_sockets.lock); | ||
488 | sk_for_each(csk, node, &data_sockets.head) { | ||
489 | if (sk == csk) | ||
490 | continue; | ||
491 | if (_pms(csk)->dev != _pms(sk)->dev) | ||
492 | continue; | ||
493 | if (csk->sk_protocol >= ISDN_P_B_START) | ||
494 | continue; | ||
495 | if (IS_ISDN_P_TE(csk->sk_protocol) | ||
496 | == IS_ISDN_P_TE(sk->sk_protocol)) | ||
497 | continue; | ||
498 | read_unlock_bh(&data_sockets.lock); | ||
499 | err = -EBUSY; | ||
500 | goto done; | ||
501 | } | ||
502 | read_unlock_bh(&data_sockets.lock); | ||
503 | } | ||
504 | |||
483 | _pms(sk)->ch.send = mISDN_send; | 505 | _pms(sk)->ch.send = mISDN_send; |
484 | _pms(sk)->ch.ctrl = mISDN_ctrl; | 506 | _pms(sk)->ch.ctrl = mISDN_ctrl; |
485 | 507 | ||
@@ -639,12 +661,27 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
639 | memcpy(di.channelmap, dev->channelmap, | 661 | memcpy(di.channelmap, dev->channelmap, |
640 | sizeof(di.channelmap)); | 662 | sizeof(di.channelmap)); |
641 | di.nrbchan = dev->nrbchan; | 663 | di.nrbchan = dev->nrbchan; |
642 | strcpy(di.name, dev->name); | 664 | strcpy(di.name, dev_name(&dev->dev)); |
643 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) | 665 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) |
644 | err = -EFAULT; | 666 | err = -EFAULT; |
645 | } else | 667 | } else |
646 | err = -ENODEV; | 668 | err = -ENODEV; |
647 | break; | 669 | break; |
670 | case IMSETDEVNAME: | ||
671 | { | ||
672 | struct mISDN_devrename dn; | ||
673 | if (copy_from_user(&dn, (void __user *)arg, | ||
674 | sizeof(dn))) { | ||
675 | err = -EFAULT; | ||
676 | break; | ||
677 | } | ||
678 | dev = get_mdevice(dn.id); | ||
679 | if (dev) | ||
680 | err = device_rename(&dev->dev, dn.name); | ||
681 | else | ||
682 | err = -ENODEV; | ||
683 | } | ||
684 | break; | ||
648 | default: | 685 | default: |
649 | err = -EINVAL; | 686 | err = -EINVAL; |
650 | } | 687 | } |