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