diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
commit | d7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch) | |
tree | a43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/irda/af_irda.c | |
parent | ee1262dbc65ce0b6234a915d8432171e8d77f518 (diff) | |
parent | 28b4d5cc17c20786848cdc07b7ea237a309776bb (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1815 commits)
mac80211: fix reorder buffer release
iwmc3200wifi: Enable wimax core through module parameter
iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter
iwmc3200wifi: Coex table command does not expect a response
iwmc3200wifi: Update wiwi priority table
iwlwifi: driver version track kernel version
iwlwifi: indicate uCode type when fail dump error/event log
iwl3945: remove duplicated event logging code
b43: fix two warnings
ipw2100: fix rebooting hang with driver loaded
cfg80211: indent regulatory messages with spaces
iwmc3200wifi: fix NULL pointer dereference in pmkid update
mac80211: Fix TX status reporting for injected data frames
ath9k: enable 2GHz band only if the device supports it
airo: Fix integer overflow warning
rt2x00: Fix padding bug on L2PAD devices.
WE: Fix set events not propagated
b43legacy: avoid PPC fault during resume
b43: avoid PPC fault during resume
tcp: fix a timewait refcnt race
...
Fix up conflicts due to sysctl cleanups (dead sysctl_check code and
CTL_UNNUMBERED removed) in
kernel/sysctl_check.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/addrconf.c
net/sctp/sysctl.c
Diffstat (limited to 'net/irda/af_irda.c')
-rw-r--r-- | net/irda/af_irda.c | 340 |
1 files changed, 229 insertions, 111 deletions
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index dd35641835f4..10093aab6173 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -61,7 +61,7 @@ | |||
61 | 61 | ||
62 | #include <net/irda/af_irda.h> | 62 | #include <net/irda/af_irda.h> |
63 | 63 | ||
64 | static int irda_create(struct net *net, struct socket *sock, int protocol); | 64 | static int irda_create(struct net *net, struct socket *sock, int protocol, int kern); |
65 | 65 | ||
66 | static const struct proto_ops irda_stream_ops; | 66 | static const struct proto_ops irda_stream_ops; |
67 | static const struct proto_ops irda_seqpacket_ops; | 67 | static const struct proto_ops irda_seqpacket_ops; |
@@ -714,11 +714,14 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
714 | struct sockaddr_irda saddr; | 714 | struct sockaddr_irda saddr; |
715 | struct sock *sk = sock->sk; | 715 | struct sock *sk = sock->sk; |
716 | struct irda_sock *self = irda_sk(sk); | 716 | struct irda_sock *self = irda_sk(sk); |
717 | int err; | ||
717 | 718 | ||
719 | lock_kernel(); | ||
718 | memset(&saddr, 0, sizeof(saddr)); | 720 | memset(&saddr, 0, sizeof(saddr)); |
719 | if (peer) { | 721 | if (peer) { |
722 | err = -ENOTCONN; | ||
720 | if (sk->sk_state != TCP_ESTABLISHED) | 723 | if (sk->sk_state != TCP_ESTABLISHED) |
721 | return -ENOTCONN; | 724 | goto out; |
722 | 725 | ||
723 | saddr.sir_family = AF_IRDA; | 726 | saddr.sir_family = AF_IRDA; |
724 | saddr.sir_lsap_sel = self->dtsap_sel; | 727 | saddr.sir_lsap_sel = self->dtsap_sel; |
@@ -735,8 +738,10 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
735 | /* uaddr_len come to us uninitialised */ | 738 | /* uaddr_len come to us uninitialised */ |
736 | *uaddr_len = sizeof (struct sockaddr_irda); | 739 | *uaddr_len = sizeof (struct sockaddr_irda); |
737 | memcpy(uaddr, &saddr, *uaddr_len); | 740 | memcpy(uaddr, &saddr, *uaddr_len); |
738 | 741 | err = 0; | |
739 | return 0; | 742 | out: |
743 | unlock_kernel(); | ||
744 | return err; | ||
740 | } | 745 | } |
741 | 746 | ||
742 | /* | 747 | /* |
@@ -748,21 +753,25 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
748 | static int irda_listen(struct socket *sock, int backlog) | 753 | static int irda_listen(struct socket *sock, int backlog) |
749 | { | 754 | { |
750 | struct sock *sk = sock->sk; | 755 | struct sock *sk = sock->sk; |
756 | int err = -EOPNOTSUPP; | ||
751 | 757 | ||
752 | IRDA_DEBUG(2, "%s()\n", __func__); | 758 | IRDA_DEBUG(2, "%s()\n", __func__); |
753 | 759 | ||
760 | lock_kernel(); | ||
754 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && | 761 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && |
755 | (sk->sk_type != SOCK_DGRAM)) | 762 | (sk->sk_type != SOCK_DGRAM)) |
756 | return -EOPNOTSUPP; | 763 | goto out; |
757 | 764 | ||
758 | if (sk->sk_state != TCP_LISTEN) { | 765 | if (sk->sk_state != TCP_LISTEN) { |
759 | sk->sk_max_ack_backlog = backlog; | 766 | sk->sk_max_ack_backlog = backlog; |
760 | sk->sk_state = TCP_LISTEN; | 767 | sk->sk_state = TCP_LISTEN; |
761 | 768 | ||
762 | return 0; | 769 | err = 0; |
763 | } | 770 | } |
771 | out: | ||
772 | unlock_kernel(); | ||
764 | 773 | ||
765 | return -EOPNOTSUPP; | 774 | return err; |
766 | } | 775 | } |
767 | 776 | ||
768 | /* | 777 | /* |
@@ -783,36 +792,40 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
783 | if (addr_len != sizeof(struct sockaddr_irda)) | 792 | if (addr_len != sizeof(struct sockaddr_irda)) |
784 | return -EINVAL; | 793 | return -EINVAL; |
785 | 794 | ||
795 | lock_kernel(); | ||
786 | #ifdef CONFIG_IRDA_ULTRA | 796 | #ifdef CONFIG_IRDA_ULTRA |
787 | /* Special care for Ultra sockets */ | 797 | /* Special care for Ultra sockets */ |
788 | if ((sk->sk_type == SOCK_DGRAM) && | 798 | if ((sk->sk_type == SOCK_DGRAM) && |
789 | (sk->sk_protocol == IRDAPROTO_ULTRA)) { | 799 | (sk->sk_protocol == IRDAPROTO_ULTRA)) { |
790 | self->pid = addr->sir_lsap_sel; | 800 | self->pid = addr->sir_lsap_sel; |
801 | err = -EOPNOTSUPP; | ||
791 | if (self->pid & 0x80) { | 802 | if (self->pid & 0x80) { |
792 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); | 803 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); |
793 | return -EOPNOTSUPP; | 804 | goto out; |
794 | } | 805 | } |
795 | err = irda_open_lsap(self, self->pid); | 806 | err = irda_open_lsap(self, self->pid); |
796 | if (err < 0) | 807 | if (err < 0) |
797 | return err; | 808 | goto out; |
798 | 809 | ||
799 | /* Pretend we are connected */ | 810 | /* Pretend we are connected */ |
800 | sock->state = SS_CONNECTED; | 811 | sock->state = SS_CONNECTED; |
801 | sk->sk_state = TCP_ESTABLISHED; | 812 | sk->sk_state = TCP_ESTABLISHED; |
813 | err = 0; | ||
802 | 814 | ||
803 | return 0; | 815 | goto out; |
804 | } | 816 | } |
805 | #endif /* CONFIG_IRDA_ULTRA */ | 817 | #endif /* CONFIG_IRDA_ULTRA */ |
806 | 818 | ||
807 | self->ias_obj = irias_new_object(addr->sir_name, jiffies); | 819 | self->ias_obj = irias_new_object(addr->sir_name, jiffies); |
820 | err = -ENOMEM; | ||
808 | if (self->ias_obj == NULL) | 821 | if (self->ias_obj == NULL) |
809 | return -ENOMEM; | 822 | goto out; |
810 | 823 | ||
811 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); | 824 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
812 | if (err < 0) { | 825 | if (err < 0) { |
813 | kfree(self->ias_obj->name); | 826 | kfree(self->ias_obj->name); |
814 | kfree(self->ias_obj); | 827 | kfree(self->ias_obj); |
815 | return err; | 828 | goto out; |
816 | } | 829 | } |
817 | 830 | ||
818 | /* Register with LM-IAS */ | 831 | /* Register with LM-IAS */ |
@@ -820,7 +833,10 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
820 | self->stsap_sel, IAS_KERNEL_ATTR); | 833 | self->stsap_sel, IAS_KERNEL_ATTR); |
821 | irias_insert_object(self->ias_obj); | 834 | irias_insert_object(self->ias_obj); |
822 | 835 | ||
823 | return 0; | 836 | err = 0; |
837 | out: | ||
838 | unlock_kernel(); | ||
839 | return err; | ||
824 | } | 840 | } |
825 | 841 | ||
826 | /* | 842 | /* |
@@ -839,22 +855,26 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
839 | 855 | ||
840 | IRDA_DEBUG(2, "%s()\n", __func__); | 856 | IRDA_DEBUG(2, "%s()\n", __func__); |
841 | 857 | ||
842 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol); | 858 | lock_kernel(); |
859 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | ||
843 | if (err) | 860 | if (err) |
844 | return err; | 861 | goto out; |
845 | 862 | ||
863 | err = -EINVAL; | ||
846 | if (sock->state != SS_UNCONNECTED) | 864 | if (sock->state != SS_UNCONNECTED) |
847 | return -EINVAL; | 865 | goto out; |
848 | 866 | ||
849 | if ((sk = sock->sk) == NULL) | 867 | if ((sk = sock->sk) == NULL) |
850 | return -EINVAL; | 868 | goto out; |
851 | 869 | ||
870 | err = -EOPNOTSUPP; | ||
852 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && | 871 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && |
853 | (sk->sk_type != SOCK_DGRAM)) | 872 | (sk->sk_type != SOCK_DGRAM)) |
854 | return -EOPNOTSUPP; | 873 | goto out; |
855 | 874 | ||
875 | err = -EINVAL; | ||
856 | if (sk->sk_state != TCP_LISTEN) | 876 | if (sk->sk_state != TCP_LISTEN) |
857 | return -EINVAL; | 877 | goto out; |
858 | 878 | ||
859 | /* | 879 | /* |
860 | * The read queue this time is holding sockets ready to use | 880 | * The read queue this time is holding sockets ready to use |
@@ -875,18 +895,20 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
875 | break; | 895 | break; |
876 | 896 | ||
877 | /* Non blocking operation */ | 897 | /* Non blocking operation */ |
898 | err = -EWOULDBLOCK; | ||
878 | if (flags & O_NONBLOCK) | 899 | if (flags & O_NONBLOCK) |
879 | return -EWOULDBLOCK; | 900 | goto out; |
880 | 901 | ||
881 | err = wait_event_interruptible(*(sk->sk_sleep), | 902 | err = wait_event_interruptible(*(sk->sk_sleep), |
882 | skb_peek(&sk->sk_receive_queue)); | 903 | skb_peek(&sk->sk_receive_queue)); |
883 | if (err) | 904 | if (err) |
884 | return err; | 905 | goto out; |
885 | } | 906 | } |
886 | 907 | ||
887 | newsk = newsock->sk; | 908 | newsk = newsock->sk; |
909 | err = -EIO; | ||
888 | if (newsk == NULL) | 910 | if (newsk == NULL) |
889 | return -EIO; | 911 | goto out; |
890 | 912 | ||
891 | newsk->sk_state = TCP_ESTABLISHED; | 913 | newsk->sk_state = TCP_ESTABLISHED; |
892 | 914 | ||
@@ -894,10 +916,11 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
894 | 916 | ||
895 | /* Now attach up the new socket */ | 917 | /* Now attach up the new socket */ |
896 | new->tsap = irttp_dup(self->tsap, new); | 918 | new->tsap = irttp_dup(self->tsap, new); |
919 | err = -EPERM; /* value does not seem to make sense. -arnd */ | ||
897 | if (!new->tsap) { | 920 | if (!new->tsap) { |
898 | IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); | 921 | IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); |
899 | kfree_skb(skb); | 922 | kfree_skb(skb); |
900 | return -1; | 923 | goto out; |
901 | } | 924 | } |
902 | 925 | ||
903 | new->stsap_sel = new->tsap->stsap_sel; | 926 | new->stsap_sel = new->tsap->stsap_sel; |
@@ -921,8 +944,10 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
921 | newsock->state = SS_CONNECTED; | 944 | newsock->state = SS_CONNECTED; |
922 | 945 | ||
923 | irda_connect_response(new); | 946 | irda_connect_response(new); |
924 | 947 | err = 0; | |
925 | return 0; | 948 | out: |
949 | unlock_kernel(); | ||
950 | return err; | ||
926 | } | 951 | } |
927 | 952 | ||
928 | /* | 953 | /* |
@@ -955,28 +980,34 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
955 | 980 | ||
956 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); | 981 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); |
957 | 982 | ||
983 | lock_kernel(); | ||
958 | /* Don't allow connect for Ultra sockets */ | 984 | /* Don't allow connect for Ultra sockets */ |
985 | err = -ESOCKTNOSUPPORT; | ||
959 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) | 986 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) |
960 | return -ESOCKTNOSUPPORT; | 987 | goto out; |
961 | 988 | ||
962 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { | 989 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { |
963 | sock->state = SS_CONNECTED; | 990 | sock->state = SS_CONNECTED; |
964 | return 0; /* Connect completed during a ERESTARTSYS event */ | 991 | err = 0; |
992 | goto out; /* Connect completed during a ERESTARTSYS event */ | ||
965 | } | 993 | } |
966 | 994 | ||
967 | if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { | 995 | if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { |
968 | sock->state = SS_UNCONNECTED; | 996 | sock->state = SS_UNCONNECTED; |
969 | return -ECONNREFUSED; | 997 | err = -ECONNREFUSED; |
998 | goto out; | ||
970 | } | 999 | } |
971 | 1000 | ||
1001 | err = -EISCONN; /* No reconnect on a seqpacket socket */ | ||
972 | if (sk->sk_state == TCP_ESTABLISHED) | 1002 | if (sk->sk_state == TCP_ESTABLISHED) |
973 | return -EISCONN; /* No reconnect on a seqpacket socket */ | 1003 | goto out; |
974 | 1004 | ||
975 | sk->sk_state = TCP_CLOSE; | 1005 | sk->sk_state = TCP_CLOSE; |
976 | sock->state = SS_UNCONNECTED; | 1006 | sock->state = SS_UNCONNECTED; |
977 | 1007 | ||
1008 | err = -EINVAL; | ||
978 | if (addr_len != sizeof(struct sockaddr_irda)) | 1009 | if (addr_len != sizeof(struct sockaddr_irda)) |
979 | return -EINVAL; | 1010 | goto out; |
980 | 1011 | ||
981 | /* Check if user supplied any destination device address */ | 1012 | /* Check if user supplied any destination device address */ |
982 | if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { | 1013 | if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { |
@@ -984,7 +1015,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
984 | err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); | 1015 | err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); |
985 | if (err) { | 1016 | if (err) { |
986 | IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__); | 1017 | IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__); |
987 | return err; | 1018 | goto out; |
988 | } | 1019 | } |
989 | } else { | 1020 | } else { |
990 | /* Use the one provided by the user */ | 1021 | /* Use the one provided by the user */ |
@@ -1000,7 +1031,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1000 | err = irda_find_lsap_sel(self, addr->sir_name); | 1031 | err = irda_find_lsap_sel(self, addr->sir_name); |
1001 | if (err) { | 1032 | if (err) { |
1002 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); | 1033 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); |
1003 | return err; | 1034 | goto out; |
1004 | } | 1035 | } |
1005 | } else { | 1036 | } else { |
1006 | /* Directly connect to the remote LSAP | 1037 | /* Directly connect to the remote LSAP |
@@ -1025,29 +1056,35 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1025 | self->max_sdu_size_rx, NULL); | 1056 | self->max_sdu_size_rx, NULL); |
1026 | if (err) { | 1057 | if (err) { |
1027 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); | 1058 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); |
1028 | return err; | 1059 | goto out; |
1029 | } | 1060 | } |
1030 | 1061 | ||
1031 | /* Now the loop */ | 1062 | /* Now the loop */ |
1063 | err = -EINPROGRESS; | ||
1032 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) | 1064 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) |
1033 | return -EINPROGRESS; | 1065 | goto out; |
1034 | 1066 | ||
1067 | err = -ERESTARTSYS; | ||
1035 | if (wait_event_interruptible(*(sk->sk_sleep), | 1068 | if (wait_event_interruptible(*(sk->sk_sleep), |
1036 | (sk->sk_state != TCP_SYN_SENT))) | 1069 | (sk->sk_state != TCP_SYN_SENT))) |
1037 | return -ERESTARTSYS; | 1070 | goto out; |
1038 | 1071 | ||
1039 | if (sk->sk_state != TCP_ESTABLISHED) { | 1072 | if (sk->sk_state != TCP_ESTABLISHED) { |
1040 | sock->state = SS_UNCONNECTED; | 1073 | sock->state = SS_UNCONNECTED; |
1041 | err = sock_error(sk); | 1074 | err = sock_error(sk); |
1042 | return err? err : -ECONNRESET; | 1075 | if (!err) |
1076 | err = -ECONNRESET; | ||
1077 | goto out; | ||
1043 | } | 1078 | } |
1044 | 1079 | ||
1045 | sock->state = SS_CONNECTED; | 1080 | sock->state = SS_CONNECTED; |
1046 | 1081 | ||
1047 | /* At this point, IrLMP has assigned our source address */ | 1082 | /* At this point, IrLMP has assigned our source address */ |
1048 | self->saddr = irttp_get_saddr(self->tsap); | 1083 | self->saddr = irttp_get_saddr(self->tsap); |
1049 | 1084 | err = 0; | |
1050 | return 0; | 1085 | out: |
1086 | unlock_kernel(); | ||
1087 | return err; | ||
1051 | } | 1088 | } |
1052 | 1089 | ||
1053 | static struct proto irda_proto = { | 1090 | static struct proto irda_proto = { |
@@ -1062,7 +1099,8 @@ static struct proto irda_proto = { | |||
1062 | * Create IrDA socket | 1099 | * Create IrDA socket |
1063 | * | 1100 | * |
1064 | */ | 1101 | */ |
1065 | static int irda_create(struct net *net, struct socket *sock, int protocol) | 1102 | static int irda_create(struct net *net, struct socket *sock, int protocol, |
1103 | int kern) | ||
1066 | { | 1104 | { |
1067 | struct sock *sk; | 1105 | struct sock *sk; |
1068 | struct irda_sock *self; | 1106 | struct irda_sock *self; |
@@ -1192,6 +1230,7 @@ static int irda_release(struct socket *sock) | |||
1192 | if (sk == NULL) | 1230 | if (sk == NULL) |
1193 | return 0; | 1231 | return 0; |
1194 | 1232 | ||
1233 | lock_kernel(); | ||
1195 | lock_sock(sk); | 1234 | lock_sock(sk); |
1196 | sk->sk_state = TCP_CLOSE; | 1235 | sk->sk_state = TCP_CLOSE; |
1197 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1236 | sk->sk_shutdown |= SEND_SHUTDOWN; |
@@ -1210,6 +1249,7 @@ static int irda_release(struct socket *sock) | |||
1210 | /* Destroy networking socket if we are the last reference on it, | 1249 | /* Destroy networking socket if we are the last reference on it, |
1211 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ | 1250 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ |
1212 | sock_put(sk); | 1251 | sock_put(sk); |
1252 | unlock_kernel(); | ||
1213 | 1253 | ||
1214 | /* Notes on socket locking and deallocation... - Jean II | 1254 | /* Notes on socket locking and deallocation... - Jean II |
1215 | * In theory we should put pairs of sock_hold() / sock_put() to | 1255 | * In theory we should put pairs of sock_hold() / sock_put() to |
@@ -1257,28 +1297,37 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1257 | 1297 | ||
1258 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1298 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1259 | 1299 | ||
1300 | lock_kernel(); | ||
1260 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ | 1301 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ |
1261 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | | 1302 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | |
1262 | MSG_NOSIGNAL)) | 1303 | MSG_NOSIGNAL)) { |
1263 | return -EINVAL; | 1304 | err = -EINVAL; |
1305 | goto out; | ||
1306 | } | ||
1264 | 1307 | ||
1265 | if (sk->sk_shutdown & SEND_SHUTDOWN) | 1308 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
1266 | goto out_err; | 1309 | goto out_err; |
1267 | 1310 | ||
1268 | if (sk->sk_state != TCP_ESTABLISHED) | 1311 | if (sk->sk_state != TCP_ESTABLISHED) { |
1269 | return -ENOTCONN; | 1312 | err = -ENOTCONN; |
1313 | goto out; | ||
1314 | } | ||
1270 | 1315 | ||
1271 | self = irda_sk(sk); | 1316 | self = irda_sk(sk); |
1272 | 1317 | ||
1273 | /* Check if IrTTP is wants us to slow down */ | 1318 | /* Check if IrTTP is wants us to slow down */ |
1274 | 1319 | ||
1275 | if (wait_event_interruptible(*(sk->sk_sleep), | 1320 | if (wait_event_interruptible(*(sk->sk_sleep), |
1276 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) | 1321 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) { |
1277 | return -ERESTARTSYS; | 1322 | err = -ERESTARTSYS; |
1323 | goto out; | ||
1324 | } | ||
1278 | 1325 | ||
1279 | /* Check if we are still connected */ | 1326 | /* Check if we are still connected */ |
1280 | if (sk->sk_state != TCP_ESTABLISHED) | 1327 | if (sk->sk_state != TCP_ESTABLISHED) { |
1281 | return -ENOTCONN; | 1328 | err = -ENOTCONN; |
1329 | goto out; | ||
1330 | } | ||
1282 | 1331 | ||
1283 | /* Check that we don't send out too big frames */ | 1332 | /* Check that we don't send out too big frames */ |
1284 | if (len > self->max_data_size) { | 1333 | if (len > self->max_data_size) { |
@@ -1310,11 +1359,16 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1310 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1359 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
1311 | goto out_err; | 1360 | goto out_err; |
1312 | } | 1361 | } |
1362 | |||
1363 | unlock_kernel(); | ||
1313 | /* Tell client how much data we actually sent */ | 1364 | /* Tell client how much data we actually sent */ |
1314 | return len; | 1365 | return len; |
1315 | 1366 | ||
1316 | out_err: | 1367 | out_err: |
1317 | return sk_stream_error(sk, msg->msg_flags, err); | 1368 | err = sk_stream_error(sk, msg->msg_flags, err); |
1369 | out: | ||
1370 | unlock_kernel(); | ||
1371 | return err; | ||
1318 | 1372 | ||
1319 | } | 1373 | } |
1320 | 1374 | ||
@@ -1335,13 +1389,14 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1335 | 1389 | ||
1336 | IRDA_DEBUG(4, "%s()\n", __func__); | 1390 | IRDA_DEBUG(4, "%s()\n", __func__); |
1337 | 1391 | ||
1392 | lock_kernel(); | ||
1338 | if ((err = sock_error(sk)) < 0) | 1393 | if ((err = sock_error(sk)) < 0) |
1339 | return err; | 1394 | goto out; |
1340 | 1395 | ||
1341 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1396 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1342 | flags & MSG_DONTWAIT, &err); | 1397 | flags & MSG_DONTWAIT, &err); |
1343 | if (!skb) | 1398 | if (!skb) |
1344 | return err; | 1399 | goto out; |
1345 | 1400 | ||
1346 | skb_reset_transport_header(skb); | 1401 | skb_reset_transport_header(skb); |
1347 | copied = skb->len; | 1402 | copied = skb->len; |
@@ -1369,8 +1424,12 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1369 | irttp_flow_request(self->tsap, FLOW_START); | 1424 | irttp_flow_request(self->tsap, FLOW_START); |
1370 | } | 1425 | } |
1371 | } | 1426 | } |
1372 | 1427 | unlock_kernel(); | |
1373 | return copied; | 1428 | return copied; |
1429 | |||
1430 | out: | ||
1431 | unlock_kernel(); | ||
1432 | return err; | ||
1374 | } | 1433 | } |
1375 | 1434 | ||
1376 | /* | 1435 | /* |
@@ -1388,15 +1447,19 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1388 | 1447 | ||
1389 | IRDA_DEBUG(3, "%s()\n", __func__); | 1448 | IRDA_DEBUG(3, "%s()\n", __func__); |
1390 | 1449 | ||
1450 | lock_kernel(); | ||
1391 | if ((err = sock_error(sk)) < 0) | 1451 | if ((err = sock_error(sk)) < 0) |
1392 | return err; | 1452 | goto out; |
1393 | 1453 | ||
1454 | err = -EINVAL; | ||
1394 | if (sock->flags & __SO_ACCEPTCON) | 1455 | if (sock->flags & __SO_ACCEPTCON) |
1395 | return(-EINVAL); | 1456 | goto out; |
1396 | 1457 | ||
1458 | err =-EOPNOTSUPP; | ||
1397 | if (flags & MSG_OOB) | 1459 | if (flags & MSG_OOB) |
1398 | return -EOPNOTSUPP; | 1460 | goto out; |
1399 | 1461 | ||
1462 | err = 0; | ||
1400 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | 1463 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); |
1401 | timeo = sock_rcvtimeo(sk, noblock); | 1464 | timeo = sock_rcvtimeo(sk, noblock); |
1402 | 1465 | ||
@@ -1408,7 +1471,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1408 | 1471 | ||
1409 | if (skb == NULL) { | 1472 | if (skb == NULL) { |
1410 | DEFINE_WAIT(wait); | 1473 | DEFINE_WAIT(wait); |
1411 | int ret = 0; | 1474 | err = 0; |
1412 | 1475 | ||
1413 | if (copied >= target) | 1476 | if (copied >= target) |
1414 | break; | 1477 | break; |
@@ -1418,25 +1481,25 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1418 | /* | 1481 | /* |
1419 | * POSIX 1003.1g mandates this order. | 1482 | * POSIX 1003.1g mandates this order. |
1420 | */ | 1483 | */ |
1421 | ret = sock_error(sk); | 1484 | err = sock_error(sk); |
1422 | if (ret) | 1485 | if (err) |
1423 | ; | 1486 | ; |
1424 | else if (sk->sk_shutdown & RCV_SHUTDOWN) | 1487 | else if (sk->sk_shutdown & RCV_SHUTDOWN) |
1425 | ; | 1488 | ; |
1426 | else if (noblock) | 1489 | else if (noblock) |
1427 | ret = -EAGAIN; | 1490 | err = -EAGAIN; |
1428 | else if (signal_pending(current)) | 1491 | else if (signal_pending(current)) |
1429 | ret = sock_intr_errno(timeo); | 1492 | err = sock_intr_errno(timeo); |
1430 | else if (sk->sk_state != TCP_ESTABLISHED) | 1493 | else if (sk->sk_state != TCP_ESTABLISHED) |
1431 | ret = -ENOTCONN; | 1494 | err = -ENOTCONN; |
1432 | else if (skb_peek(&sk->sk_receive_queue) == NULL) | 1495 | else if (skb_peek(&sk->sk_receive_queue) == NULL) |
1433 | /* Wait process until data arrives */ | 1496 | /* Wait process until data arrives */ |
1434 | schedule(); | 1497 | schedule(); |
1435 | 1498 | ||
1436 | finish_wait(sk->sk_sleep, &wait); | 1499 | finish_wait(sk->sk_sleep, &wait); |
1437 | 1500 | ||
1438 | if (ret) | 1501 | if (err) |
1439 | return ret; | 1502 | goto out; |
1440 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1503 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1441 | break; | 1504 | break; |
1442 | 1505 | ||
@@ -1489,7 +1552,9 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1489 | } | 1552 | } |
1490 | } | 1553 | } |
1491 | 1554 | ||
1492 | return copied; | 1555 | out: |
1556 | unlock_kernel(); | ||
1557 | return err ? : copied; | ||
1493 | } | 1558 | } |
1494 | 1559 | ||
1495 | /* | 1560 | /* |
@@ -1507,18 +1572,23 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1507 | struct sk_buff *skb; | 1572 | struct sk_buff *skb; |
1508 | int err; | 1573 | int err; |
1509 | 1574 | ||
1575 | lock_kernel(); | ||
1576 | |||
1510 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1577 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1511 | 1578 | ||
1579 | err = -EINVAL; | ||
1512 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1580 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
1513 | return -EINVAL; | 1581 | goto out; |
1514 | 1582 | ||
1515 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1583 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
1516 | send_sig(SIGPIPE, current, 0); | 1584 | send_sig(SIGPIPE, current, 0); |
1517 | return -EPIPE; | 1585 | err = -EPIPE; |
1586 | goto out; | ||
1518 | } | 1587 | } |
1519 | 1588 | ||
1589 | err = -ENOTCONN; | ||
1520 | if (sk->sk_state != TCP_ESTABLISHED) | 1590 | if (sk->sk_state != TCP_ESTABLISHED) |
1521 | return -ENOTCONN; | 1591 | goto out; |
1522 | 1592 | ||
1523 | self = irda_sk(sk); | 1593 | self = irda_sk(sk); |
1524 | 1594 | ||
@@ -1535,8 +1605,9 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1535 | 1605 | ||
1536 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, | 1606 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, |
1537 | msg->msg_flags & MSG_DONTWAIT, &err); | 1607 | msg->msg_flags & MSG_DONTWAIT, &err); |
1608 | err = -ENOBUFS; | ||
1538 | if (!skb) | 1609 | if (!skb) |
1539 | return -ENOBUFS; | 1610 | goto out; |
1540 | 1611 | ||
1541 | skb_reserve(skb, self->max_header_size); | 1612 | skb_reserve(skb, self->max_header_size); |
1542 | skb_reset_transport_header(skb); | 1613 | skb_reset_transport_header(skb); |
@@ -1546,7 +1617,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1546 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1617 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); |
1547 | if (err) { | 1618 | if (err) { |
1548 | kfree_skb(skb); | 1619 | kfree_skb(skb); |
1549 | return err; | 1620 | goto out; |
1550 | } | 1621 | } |
1551 | 1622 | ||
1552 | /* | 1623 | /* |
@@ -1556,9 +1627,13 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1556 | err = irttp_udata_request(self->tsap, skb); | 1627 | err = irttp_udata_request(self->tsap, skb); |
1557 | if (err) { | 1628 | if (err) { |
1558 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1629 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
1559 | return err; | 1630 | goto out; |
1560 | } | 1631 | } |
1632 | unlock_kernel(); | ||
1561 | return len; | 1633 | return len; |
1634 | out: | ||
1635 | unlock_kernel(); | ||
1636 | return err; | ||
1562 | } | 1637 | } |
1563 | 1638 | ||
1564 | /* | 1639 | /* |
@@ -1580,12 +1655,15 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1580 | 1655 | ||
1581 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1656 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1582 | 1657 | ||
1658 | lock_kernel(); | ||
1659 | err = -EINVAL; | ||
1583 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1660 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
1584 | return -EINVAL; | 1661 | goto out; |
1585 | 1662 | ||
1663 | err = -EPIPE; | ||
1586 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1664 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
1587 | send_sig(SIGPIPE, current, 0); | 1665 | send_sig(SIGPIPE, current, 0); |
1588 | return -EPIPE; | 1666 | goto out; |
1589 | } | 1667 | } |
1590 | 1668 | ||
1591 | self = irda_sk(sk); | 1669 | self = irda_sk(sk); |
@@ -1593,16 +1671,18 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1593 | /* Check if an address was specified with sendto. Jean II */ | 1671 | /* Check if an address was specified with sendto. Jean II */ |
1594 | if (msg->msg_name) { | 1672 | if (msg->msg_name) { |
1595 | struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name; | 1673 | struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name; |
1674 | err = -EINVAL; | ||
1596 | /* Check address, extract pid. Jean II */ | 1675 | /* Check address, extract pid. Jean II */ |
1597 | if (msg->msg_namelen < sizeof(*addr)) | 1676 | if (msg->msg_namelen < sizeof(*addr)) |
1598 | return -EINVAL; | 1677 | goto out; |
1599 | if (addr->sir_family != AF_IRDA) | 1678 | if (addr->sir_family != AF_IRDA) |
1600 | return -EINVAL; | 1679 | goto out; |
1601 | 1680 | ||
1602 | pid = addr->sir_lsap_sel; | 1681 | pid = addr->sir_lsap_sel; |
1603 | if (pid & 0x80) { | 1682 | if (pid & 0x80) { |
1604 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); | 1683 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); |
1605 | return -EOPNOTSUPP; | 1684 | err = -EOPNOTSUPP; |
1685 | goto out; | ||
1606 | } | 1686 | } |
1607 | } else { | 1687 | } else { |
1608 | /* Check that the socket is properly bound to an Ultra | 1688 | /* Check that the socket is properly bound to an Ultra |
@@ -1611,7 +1691,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1611 | (sk->sk_state != TCP_ESTABLISHED)) { | 1691 | (sk->sk_state != TCP_ESTABLISHED)) { |
1612 | IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n", | 1692 | IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n", |
1613 | __func__); | 1693 | __func__); |
1614 | return -ENOTCONN; | 1694 | err = -ENOTCONN; |
1695 | goto out; | ||
1615 | } | 1696 | } |
1616 | /* Use PID from socket */ | 1697 | /* Use PID from socket */ |
1617 | bound = 1; | 1698 | bound = 1; |
@@ -1630,8 +1711,9 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1630 | 1711 | ||
1631 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, | 1712 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, |
1632 | msg->msg_flags & MSG_DONTWAIT, &err); | 1713 | msg->msg_flags & MSG_DONTWAIT, &err); |
1714 | err = -ENOBUFS; | ||
1633 | if (!skb) | 1715 | if (!skb) |
1634 | return -ENOBUFS; | 1716 | goto out; |
1635 | 1717 | ||
1636 | skb_reserve(skb, self->max_header_size); | 1718 | skb_reserve(skb, self->max_header_size); |
1637 | skb_reset_transport_header(skb); | 1719 | skb_reset_transport_header(skb); |
@@ -1641,16 +1723,16 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1641 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1723 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); |
1642 | if (err) { | 1724 | if (err) { |
1643 | kfree_skb(skb); | 1725 | kfree_skb(skb); |
1644 | return err; | 1726 | goto out; |
1645 | } | 1727 | } |
1646 | 1728 | ||
1647 | err = irlmp_connless_data_request((bound ? self->lsap : NULL), | 1729 | err = irlmp_connless_data_request((bound ? self->lsap : NULL), |
1648 | skb, pid); | 1730 | skb, pid); |
1649 | if (err) { | 1731 | if (err) |
1650 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1732 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
1651 | return err; | 1733 | out: |
1652 | } | 1734 | unlock_kernel(); |
1653 | return len; | 1735 | return err ? : len; |
1654 | } | 1736 | } |
1655 | #endif /* CONFIG_IRDA_ULTRA */ | 1737 | #endif /* CONFIG_IRDA_ULTRA */ |
1656 | 1738 | ||
@@ -1664,6 +1746,8 @@ static int irda_shutdown(struct socket *sock, int how) | |||
1664 | 1746 | ||
1665 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); | 1747 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); |
1666 | 1748 | ||
1749 | lock_kernel(); | ||
1750 | |||
1667 | sk->sk_state = TCP_CLOSE; | 1751 | sk->sk_state = TCP_CLOSE; |
1668 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1752 | sk->sk_shutdown |= SEND_SHUTDOWN; |
1669 | sk->sk_state_change(sk); | 1753 | sk->sk_state_change(sk); |
@@ -1684,6 +1768,8 @@ static int irda_shutdown(struct socket *sock, int how) | |||
1684 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ | 1768 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ |
1685 | self->saddr = 0x0; /* so IrLMP assign us any link */ | 1769 | self->saddr = 0x0; /* so IrLMP assign us any link */ |
1686 | 1770 | ||
1771 | unlock_kernel(); | ||
1772 | |||
1687 | return 0; | 1773 | return 0; |
1688 | } | 1774 | } |
1689 | 1775 | ||
@@ -1699,6 +1785,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
1699 | 1785 | ||
1700 | IRDA_DEBUG(4, "%s()\n", __func__); | 1786 | IRDA_DEBUG(4, "%s()\n", __func__); |
1701 | 1787 | ||
1788 | lock_kernel(); | ||
1702 | poll_wait(file, sk->sk_sleep, wait); | 1789 | poll_wait(file, sk->sk_sleep, wait); |
1703 | mask = 0; | 1790 | mask = 0; |
1704 | 1791 | ||
@@ -1746,18 +1833,34 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
1746 | default: | 1833 | default: |
1747 | break; | 1834 | break; |
1748 | } | 1835 | } |
1836 | unlock_kernel(); | ||
1749 | return mask; | 1837 | return mask; |
1750 | } | 1838 | } |
1751 | 1839 | ||
1840 | static unsigned int irda_datagram_poll(struct file *file, struct socket *sock, | ||
1841 | poll_table *wait) | ||
1842 | { | ||
1843 | int err; | ||
1844 | |||
1845 | lock_kernel(); | ||
1846 | err = datagram_poll(file, sock, wait); | ||
1847 | unlock_kernel(); | ||
1848 | |||
1849 | return err; | ||
1850 | } | ||
1851 | |||
1752 | /* | 1852 | /* |
1753 | * Function irda_ioctl (sock, cmd, arg) | 1853 | * Function irda_ioctl (sock, cmd, arg) |
1754 | */ | 1854 | */ |
1755 | static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1855 | static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
1756 | { | 1856 | { |
1757 | struct sock *sk = sock->sk; | 1857 | struct sock *sk = sock->sk; |
1858 | int err; | ||
1758 | 1859 | ||
1759 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); | 1860 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); |
1760 | 1861 | ||
1862 | lock_kernel(); | ||
1863 | err = -EINVAL; | ||
1761 | switch (cmd) { | 1864 | switch (cmd) { |
1762 | case TIOCOUTQ: { | 1865 | case TIOCOUTQ: { |
1763 | long amount; | 1866 | long amount; |
@@ -1765,9 +1868,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1765 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | 1868 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1766 | if (amount < 0) | 1869 | if (amount < 0) |
1767 | amount = 0; | 1870 | amount = 0; |
1768 | if (put_user(amount, (unsigned int __user *)arg)) | 1871 | err = put_user(amount, (unsigned int __user *)arg); |
1769 | return -EFAULT; | 1872 | break; |
1770 | return 0; | ||
1771 | } | 1873 | } |
1772 | 1874 | ||
1773 | case TIOCINQ: { | 1875 | case TIOCINQ: { |
@@ -1776,15 +1878,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1776 | /* These two are safe on a single CPU system as only user tasks fiddle here */ | 1878 | /* These two are safe on a single CPU system as only user tasks fiddle here */ |
1777 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) | 1879 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) |
1778 | amount = skb->len; | 1880 | amount = skb->len; |
1779 | if (put_user(amount, (unsigned int __user *)arg)) | 1881 | err = put_user(amount, (unsigned int __user *)arg); |
1780 | return -EFAULT; | 1882 | break; |
1781 | return 0; | ||
1782 | } | 1883 | } |
1783 | 1884 | ||
1784 | case SIOCGSTAMP: | 1885 | case SIOCGSTAMP: |
1785 | if (sk != NULL) | 1886 | if (sk != NULL) |
1786 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | 1887 | err = sock_get_timestamp(sk, (struct timeval __user *)arg); |
1787 | return -EINVAL; | 1888 | break; |
1788 | 1889 | ||
1789 | case SIOCGIFADDR: | 1890 | case SIOCGIFADDR: |
1790 | case SIOCSIFADDR: | 1891 | case SIOCSIFADDR: |
@@ -1796,14 +1897,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1796 | case SIOCSIFNETMASK: | 1897 | case SIOCSIFNETMASK: |
1797 | case SIOCGIFMETRIC: | 1898 | case SIOCGIFMETRIC: |
1798 | case SIOCSIFMETRIC: | 1899 | case SIOCSIFMETRIC: |
1799 | return -EINVAL; | 1900 | break; |
1800 | default: | 1901 | default: |
1801 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); | 1902 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); |
1802 | return -ENOIOCTLCMD; | 1903 | err = -ENOIOCTLCMD; |
1803 | } | 1904 | } |
1905 | unlock_kernel(); | ||
1804 | 1906 | ||
1805 | /*NOTREACHED*/ | 1907 | return err; |
1806 | return 0; | ||
1807 | } | 1908 | } |
1808 | 1909 | ||
1809 | #ifdef CONFIG_COMPAT | 1910 | #ifdef CONFIG_COMPAT |
@@ -1825,7 +1926,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon | |||
1825 | * Set some options for the socket | 1926 | * Set some options for the socket |
1826 | * | 1927 | * |
1827 | */ | 1928 | */ |
1828 | static int irda_setsockopt(struct socket *sock, int level, int optname, | 1929 | static int __irda_setsockopt(struct socket *sock, int level, int optname, |
1829 | char __user *optval, unsigned int optlen) | 1930 | char __user *optval, unsigned int optlen) |
1830 | { | 1931 | { |
1831 | struct sock *sk = sock->sk; | 1932 | struct sock *sk = sock->sk; |
@@ -2083,6 +2184,18 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, | |||
2083 | return 0; | 2184 | return 0; |
2084 | } | 2185 | } |
2085 | 2186 | ||
2187 | static int irda_setsockopt(struct socket *sock, int level, int optname, | ||
2188 | char __user *optval, unsigned int optlen) | ||
2189 | { | ||
2190 | int err; | ||
2191 | |||
2192 | lock_kernel(); | ||
2193 | err = __irda_setsockopt(sock, level, optname, optval, optlen); | ||
2194 | unlock_kernel(); | ||
2195 | |||
2196 | return err; | ||
2197 | } | ||
2198 | |||
2086 | /* | 2199 | /* |
2087 | * Function irda_extract_ias_value(ias_opt, ias_value) | 2200 | * Function irda_extract_ias_value(ias_opt, ias_value) |
2088 | * | 2201 | * |
@@ -2135,7 +2248,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, | |||
2135 | /* | 2248 | /* |
2136 | * Function irda_getsockopt (sock, level, optname, optval, optlen) | 2249 | * Function irda_getsockopt (sock, level, optname, optval, optlen) |
2137 | */ | 2250 | */ |
2138 | static int irda_getsockopt(struct socket *sock, int level, int optname, | 2251 | static int __irda_getsockopt(struct socket *sock, int level, int optname, |
2139 | char __user *optval, int __user *optlen) | 2252 | char __user *optval, int __user *optlen) |
2140 | { | 2253 | { |
2141 | struct sock *sk = sock->sk; | 2254 | struct sock *sk = sock->sk; |
@@ -2463,13 +2576,25 @@ bed: | |||
2463 | return 0; | 2576 | return 0; |
2464 | } | 2577 | } |
2465 | 2578 | ||
2466 | static struct net_proto_family irda_family_ops = { | 2579 | static int irda_getsockopt(struct socket *sock, int level, int optname, |
2580 | char __user *optval, int __user *optlen) | ||
2581 | { | ||
2582 | int err; | ||
2583 | |||
2584 | lock_kernel(); | ||
2585 | err = __irda_getsockopt(sock, level, optname, optval, optlen); | ||
2586 | unlock_kernel(); | ||
2587 | |||
2588 | return err; | ||
2589 | } | ||
2590 | |||
2591 | static const struct net_proto_family irda_family_ops = { | ||
2467 | .family = PF_IRDA, | 2592 | .family = PF_IRDA, |
2468 | .create = irda_create, | 2593 | .create = irda_create, |
2469 | .owner = THIS_MODULE, | 2594 | .owner = THIS_MODULE, |
2470 | }; | 2595 | }; |
2471 | 2596 | ||
2472 | static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | 2597 | static const struct proto_ops irda_stream_ops = { |
2473 | .family = PF_IRDA, | 2598 | .family = PF_IRDA, |
2474 | .owner = THIS_MODULE, | 2599 | .owner = THIS_MODULE, |
2475 | .release = irda_release, | 2600 | .release = irda_release, |
@@ -2493,7 +2618,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | |||
2493 | .sendpage = sock_no_sendpage, | 2618 | .sendpage = sock_no_sendpage, |
2494 | }; | 2619 | }; |
2495 | 2620 | ||
2496 | static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | 2621 | static const struct proto_ops irda_seqpacket_ops = { |
2497 | .family = PF_IRDA, | 2622 | .family = PF_IRDA, |
2498 | .owner = THIS_MODULE, | 2623 | .owner = THIS_MODULE, |
2499 | .release = irda_release, | 2624 | .release = irda_release, |
@@ -2502,7 +2627,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | |||
2502 | .socketpair = sock_no_socketpair, | 2627 | .socketpair = sock_no_socketpair, |
2503 | .accept = irda_accept, | 2628 | .accept = irda_accept, |
2504 | .getname = irda_getname, | 2629 | .getname = irda_getname, |
2505 | .poll = datagram_poll, | 2630 | .poll = irda_datagram_poll, |
2506 | .ioctl = irda_ioctl, | 2631 | .ioctl = irda_ioctl, |
2507 | #ifdef CONFIG_COMPAT | 2632 | #ifdef CONFIG_COMPAT |
2508 | .compat_ioctl = irda_compat_ioctl, | 2633 | .compat_ioctl = irda_compat_ioctl, |
@@ -2517,7 +2642,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | |||
2517 | .sendpage = sock_no_sendpage, | 2642 | .sendpage = sock_no_sendpage, |
2518 | }; | 2643 | }; |
2519 | 2644 | ||
2520 | static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | 2645 | static const struct proto_ops irda_dgram_ops = { |
2521 | .family = PF_IRDA, | 2646 | .family = PF_IRDA, |
2522 | .owner = THIS_MODULE, | 2647 | .owner = THIS_MODULE, |
2523 | .release = irda_release, | 2648 | .release = irda_release, |
@@ -2526,7 +2651,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | |||
2526 | .socketpair = sock_no_socketpair, | 2651 | .socketpair = sock_no_socketpair, |
2527 | .accept = irda_accept, | 2652 | .accept = irda_accept, |
2528 | .getname = irda_getname, | 2653 | .getname = irda_getname, |
2529 | .poll = datagram_poll, | 2654 | .poll = irda_datagram_poll, |
2530 | .ioctl = irda_ioctl, | 2655 | .ioctl = irda_ioctl, |
2531 | #ifdef CONFIG_COMPAT | 2656 | #ifdef CONFIG_COMPAT |
2532 | .compat_ioctl = irda_compat_ioctl, | 2657 | .compat_ioctl = irda_compat_ioctl, |
@@ -2542,7 +2667,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | |||
2542 | }; | 2667 | }; |
2543 | 2668 | ||
2544 | #ifdef CONFIG_IRDA_ULTRA | 2669 | #ifdef CONFIG_IRDA_ULTRA |
2545 | static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | 2670 | static const struct proto_ops irda_ultra_ops = { |
2546 | .family = PF_IRDA, | 2671 | .family = PF_IRDA, |
2547 | .owner = THIS_MODULE, | 2672 | .owner = THIS_MODULE, |
2548 | .release = irda_release, | 2673 | .release = irda_release, |
@@ -2551,7 +2676,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | |||
2551 | .socketpair = sock_no_socketpair, | 2676 | .socketpair = sock_no_socketpair, |
2552 | .accept = sock_no_accept, | 2677 | .accept = sock_no_accept, |
2553 | .getname = irda_getname, | 2678 | .getname = irda_getname, |
2554 | .poll = datagram_poll, | 2679 | .poll = irda_datagram_poll, |
2555 | .ioctl = irda_ioctl, | 2680 | .ioctl = irda_ioctl, |
2556 | #ifdef CONFIG_COMPAT | 2681 | #ifdef CONFIG_COMPAT |
2557 | .compat_ioctl = irda_compat_ioctl, | 2682 | .compat_ioctl = irda_compat_ioctl, |
@@ -2567,13 +2692,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | |||
2567 | }; | 2692 | }; |
2568 | #endif /* CONFIG_IRDA_ULTRA */ | 2693 | #endif /* CONFIG_IRDA_ULTRA */ |
2569 | 2694 | ||
2570 | SOCKOPS_WRAP(irda_stream, PF_IRDA); | ||
2571 | SOCKOPS_WRAP(irda_seqpacket, PF_IRDA); | ||
2572 | SOCKOPS_WRAP(irda_dgram, PF_IRDA); | ||
2573 | #ifdef CONFIG_IRDA_ULTRA | ||
2574 | SOCKOPS_WRAP(irda_ultra, PF_IRDA); | ||
2575 | #endif /* CONFIG_IRDA_ULTRA */ | ||
2576 | |||
2577 | /* | 2695 | /* |
2578 | * Function irsock_init (pro) | 2696 | * Function irsock_init (pro) |
2579 | * | 2697 | * |