NFS: Don't use GFP_KERNEL in rpcsec_gss downcalls
[safe/jmp/linux-2.6] / net / irda / af_irda.c
index c80949a..2a4efce 100644 (file)
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/net.h>
 #include <linux/irda.h>
@@ -60,7 +62,7 @@
 
 #include <net/irda/af_irda.h>
 
-static int irda_create(struct socket *sock, int protocol);
+static int irda_create(struct net *net, struct socket *sock, int protocol, int kern);
 
 static const struct proto_ops irda_stream_ops;
 static const struct proto_ops irda_seqpacket_ops;
@@ -85,14 +87,14 @@ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb)
        struct sock *sk;
        int err;
 
-       IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(3, "%s()\n", __func__);
 
        self = instance;
        sk = instance;
 
        err = sock_queue_rcv_skb(sk, skb);
        if (err) {
-               IRDA_DEBUG(1, "%s(), error: no more mem!\n", __FUNCTION__);
+               IRDA_DEBUG(1, "%s(), error: no more mem!\n", __func__);
                self->rx_flow = FLOW_STOP;
 
                /* When we return error, TTP will need to requeue the skb */
@@ -116,7 +118,7 @@ static void irda_disconnect_indication(void *instance, void *sap,
 
        self = instance;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        /* Don't care about it, but let's not leak it */
        if(skb)
@@ -125,7 +127,7 @@ static void irda_disconnect_indication(void *instance, void *sap,
        sk = instance;
        if (sk == NULL) {
                IRDA_DEBUG(0, "%s(%p) : BUG : sk is NULL\n",
-                          __FUNCTION__, self);
+                          __func__, self);
                return;
        }
 
@@ -181,7 +183,7 @@ static void irda_connect_confirm(void *instance, void *sap,
 
        self = instance;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        sk = instance;
        if (sk == NULL) {
@@ -203,7 +205,7 @@ static void irda_connect_confirm(void *instance, void *sap,
        case SOCK_STREAM:
                if (max_sdu_size != 0) {
                        IRDA_ERROR("%s: max_sdu_size must be 0\n",
-                                  __FUNCTION__);
+                                  __func__);
                        return;
                }
                self->max_data_size = irttp_get_max_seg_size(self->tsap);
@@ -211,7 +213,7 @@ static void irda_connect_confirm(void *instance, void *sap,
        case SOCK_SEQPACKET:
                if (max_sdu_size == 0) {
                        IRDA_ERROR("%s: max_sdu_size cannot be 0\n",
-                                  __FUNCTION__);
+                                  __func__);
                        return;
                }
                self->max_data_size = max_sdu_size;
@@ -220,7 +222,7 @@ static void irda_connect_confirm(void *instance, void *sap,
                self->max_data_size = irttp_get_max_seg_size(self->tsap);
        }
 
-       IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
+       IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __func__,
                   self->max_data_size);
 
        memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
@@ -245,7 +247,7 @@ static void irda_connect_indication(void *instance, void *sap,
 
        self = instance;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        sk = instance;
        if (sk == NULL) {
@@ -264,7 +266,7 @@ static void irda_connect_indication(void *instance, void *sap,
        case SOCK_STREAM:
                if (max_sdu_size != 0) {
                        IRDA_ERROR("%s: max_sdu_size must be 0\n",
-                                  __FUNCTION__);
+                                  __func__);
                        kfree_skb(skb);
                        return;
                }
@@ -273,7 +275,7 @@ static void irda_connect_indication(void *instance, void *sap,
        case SOCK_SEQPACKET:
                if (max_sdu_size == 0) {
                        IRDA_ERROR("%s: max_sdu_size cannot be 0\n",
-                                  __FUNCTION__);
+                                  __func__);
                        kfree_skb(skb);
                        return;
                }
@@ -283,7 +285,7 @@ static void irda_connect_indication(void *instance, void *sap,
                self->max_data_size = irttp_get_max_seg_size(self->tsap);
        }
 
-       IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
+       IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __func__,
                   self->max_data_size);
 
        memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
@@ -302,13 +304,13 @@ static void irda_connect_response(struct irda_sock *self)
 {
        struct sk_buff *skb;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
        skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
                        GFP_ATOMIC);
        if (skb == NULL) {
                IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
-                          __FUNCTION__);
+                          __func__);
                return;
        }
 
@@ -329,7 +331,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
        struct irda_sock *self;
        struct sock *sk;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
        self = instance;
        sk = instance;
@@ -338,17 +340,17 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
        switch (flow) {
        case FLOW_STOP:
                IRDA_DEBUG(1, "%s(), IrTTP wants us to slow down\n",
-                          __FUNCTION__);
+                          __func__);
                self->tx_flow = flow;
                break;
        case FLOW_START:
                self->tx_flow = flow;
                IRDA_DEBUG(1, "%s(), IrTTP wants us to start again\n",
-                          __FUNCTION__);
+                          __func__);
                wake_up_interruptible(sk->sk_sleep);
                break;
        default:
-               IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __FUNCTION__);
+               IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __func__);
                /* Unknown flow command, better stop */
                self->tx_flow = flow;
                break;
@@ -370,11 +372,11 @@ static void irda_getvalue_confirm(int result, __u16 obj_id,
 
        self = (struct irda_sock *) priv;
        if (!self) {
-               IRDA_WARNING("%s: lost myself!\n", __FUNCTION__);
+               IRDA_WARNING("%s: lost myself!\n", __func__);
                return;
        }
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        /* We probably don't need to make any more queries */
        iriap_close(self->iriap);
@@ -382,7 +384,7 @@ static void irda_getvalue_confirm(int result, __u16 obj_id,
 
        /* Check if request succeeded */
        if (result != IAS_SUCCESS) {
-               IRDA_DEBUG(1, "%s(), IAS query failed! (%d)\n", __FUNCTION__,
+               IRDA_DEBUG(1, "%s(), IAS query failed! (%d)\n", __func__,
                           result);
 
                self->errno = result;   /* We really need it later */
@@ -415,11 +417,11 @@ static void irda_selective_discovery_indication(discinfo_t *discovery,
 {
        struct irda_sock *self;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
        self = (struct irda_sock *) priv;
        if (!self) {
-               IRDA_WARNING("%s: lost myself!\n", __FUNCTION__);
+               IRDA_WARNING("%s: lost myself!\n", __func__);
                return;
        }
 
@@ -442,7 +444,7 @@ static void irda_discovery_timeout(u_long priv)
 {
        struct irda_sock *self;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
        self = (struct irda_sock *) priv;
        BUG_ON(self == NULL);
@@ -467,7 +469,7 @@ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name)
        notify_t notify;
 
        if (self->tsap) {
-               IRDA_WARNING("%s: busy!\n", __FUNCTION__);
+               IRDA_WARNING("%s: busy!\n", __func__);
                return -EBUSY;
        }
 
@@ -486,7 +488,7 @@ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name)
                                     &notify);
        if (self->tsap == NULL) {
                IRDA_DEBUG(0, "%s(), Unable to allocate TSAP!\n",
-                          __FUNCTION__);
+                          __func__);
                return -ENOMEM;
        }
        /* Remember which TSAP selector we actually got */
@@ -507,7 +509,7 @@ static int irda_open_lsap(struct irda_sock *self, int pid)
        notify_t notify;
 
        if (self->lsap) {
-               IRDA_WARNING("%s(), busy!\n", __FUNCTION__);
+               IRDA_WARNING("%s(), busy!\n", __func__);
                return -EBUSY;
        }
 
@@ -519,7 +521,7 @@ static int irda_open_lsap(struct irda_sock *self, int pid)
 
        self->lsap = irlmp_open_lsap(LSAP_CONNLESS, &notify, pid);
        if (self->lsap == NULL) {
-               IRDA_DEBUG( 0, "%s(), Unable to allocate LSAP!\n", __FUNCTION__);
+               IRDA_DEBUG( 0, "%s(), Unable to allocate LSAP!\n", __func__);
                return -ENOMEM;
        }
 
@@ -540,11 +542,11 @@ static int irda_open_lsap(struct irda_sock *self, int pid)
  */
 static int irda_find_lsap_sel(struct irda_sock *self, char *name)
 {
-       IRDA_DEBUG(2, "%s(%p, %s)\n", __FUNCTION__, self, name);
+       IRDA_DEBUG(2, "%s(%p, %s)\n", __func__, self, name);
 
        if (self->iriap) {
                IRDA_WARNING("%s(): busy with a previous query\n",
-                            __FUNCTION__);
+                            __func__);
                return -EBUSY;
        }
 
@@ -580,7 +582,7 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
        switch (self->ias_result->type) {
        case IAS_INTEGER:
                IRDA_DEBUG(4, "%s() int=%d\n",
-                          __FUNCTION__, self->ias_result->t.integer);
+                          __func__, self->ias_result->t.integer);
 
                if (self->ias_result->t.integer != -1)
                        self->dtsap_sel = self->ias_result->t.integer;
@@ -589,7 +591,7 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
                break;
        default:
                self->dtsap_sel = 0;
-               IRDA_DEBUG(0, "%s(), bad type!\n", __FUNCTION__);
+               IRDA_DEBUG(0, "%s(), bad type!\n", __func__);
                break;
        }
        if (self->ias_result)
@@ -627,7 +629,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
        __u32   daddr = DEV_ADDR_ANY;   /* Address we found the service on */
        __u8    dtsap_sel = 0x0;        /* TSAP associated with it */
 
-       IRDA_DEBUG(2, "%s(), name=%s\n", __FUNCTION__, name);
+       IRDA_DEBUG(2, "%s(), name=%s\n", __func__, name);
 
        /* Ask lmp for the current discovery log
         * Note : we have to use irlmp_get_discoveries(), as opposed
@@ -649,7 +651,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
                self->daddr = discoveries[i].daddr;
                self->saddr = 0x0;
                IRDA_DEBUG(1, "%s(), trying daddr = %08x\n",
-                          __FUNCTION__, self->daddr);
+                          __func__, self->daddr);
 
                /* Query remote LM-IAS for this service */
                err = irda_find_lsap_sel(self, name);
@@ -658,7 +660,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
                        /* We found the requested service */
                        if(daddr != DEV_ADDR_ANY) {
                                IRDA_DEBUG(1, "%s(), discovered service ''%s'' in two different devices !!!\n",
-                                          __FUNCTION__, name);
+                                          __func__, name);
                                self->daddr = DEV_ADDR_ANY;
                                kfree(discoveries);
                                return(-ENOTUNIQ);
@@ -672,7 +674,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
                        break;
                default:
                        /* Something bad did happen :-( */
-                       IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __FUNCTION__);
+                       IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __func__);
                        self->daddr = DEV_ADDR_ANY;
                        kfree(discoveries);
                        return(-EHOSTUNREACH);
@@ -685,7 +687,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
        /* Check out what we found */
        if(daddr == DEV_ADDR_ANY) {
                IRDA_DEBUG(1, "%s(), cannot discover service ''%s'' in any device !!!\n",
-                          __FUNCTION__, name);
+                          __func__, name);
                self->daddr = DEV_ADDR_ANY;
                return(-EADDRNOTAVAIL);
        }
@@ -696,7 +698,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
        self->dtsap_sel = dtsap_sel;
 
        IRDA_DEBUG(1, "%s(), discovered requested service ''%s'' at address %08x\n",
-                  __FUNCTION__, name, self->daddr);
+                  __func__, name, self->daddr);
 
        return 0;
 }
@@ -713,10 +715,14 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
        struct sockaddr_irda saddr;
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
+       int err;
 
+       lock_kernel();
+       memset(&saddr, 0, sizeof(saddr));
        if (peer) {
+               err  = -ENOTCONN;
                if (sk->sk_state != TCP_ESTABLISHED)
-                       return -ENOTCONN;
+                       goto out;
 
                saddr.sir_family = AF_IRDA;
                saddr.sir_lsap_sel = self->dtsap_sel;
@@ -727,14 +733,16 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
                saddr.sir_addr = self->saddr;
        }
 
-       IRDA_DEBUG(1, "%s(), tsap_sel = %#x\n", __FUNCTION__, saddr.sir_lsap_sel);
-       IRDA_DEBUG(1, "%s(), addr = %08x\n", __FUNCTION__, saddr.sir_addr);
+       IRDA_DEBUG(1, "%s(), tsap_sel = %#x\n", __func__, saddr.sir_lsap_sel);
+       IRDA_DEBUG(1, "%s(), addr = %08x\n", __func__, saddr.sir_addr);
 
        /* uaddr_len come to us uninitialised */
        *uaddr_len = sizeof (struct sockaddr_irda);
        memcpy(uaddr, &saddr, *uaddr_len);
-
-       return 0;
+       err = 0;
+out:
+       unlock_kernel();
+       return err;
 }
 
 /*
@@ -746,21 +754,25 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
 static int irda_listen(struct socket *sock, int backlog)
 {
        struct sock *sk = sock->sk;
+       int err = -EOPNOTSUPP;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
+       lock_kernel();
        if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
            (sk->sk_type != SOCK_DGRAM))
-               return -EOPNOTSUPP;
+               goto out;
 
        if (sk->sk_state != TCP_LISTEN) {
                sk->sk_max_ack_backlog = backlog;
                sk->sk_state           = TCP_LISTEN;
 
-               return 0;
+               err = 0;
        }
+out:
+       unlock_kernel();
 
-       return -EOPNOTSUPP;
+       return err;
 }
 
 /*
@@ -776,43 +788,56 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct irda_sock *self = irda_sk(sk);
        int err;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        if (addr_len != sizeof(struct sockaddr_irda))
                return -EINVAL;
 
+       lock_kernel();
 #ifdef CONFIG_IRDA_ULTRA
        /* Special care for Ultra sockets */
        if ((sk->sk_type == SOCK_DGRAM) &&
            (sk->sk_protocol == IRDAPROTO_ULTRA)) {
                self->pid = addr->sir_lsap_sel;
+               err = -EOPNOTSUPP;
                if (self->pid & 0x80) {
-                       IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __FUNCTION__);
-                       return -EOPNOTSUPP;
+                       IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
+                       goto out;
                }
                err = irda_open_lsap(self, self->pid);
                if (err < 0)
-                       return err;
+                       goto out;
 
                /* Pretend we are connected */
                sock->state = SS_CONNECTED;
                sk->sk_state   = TCP_ESTABLISHED;
+               err = 0;
 
-               return 0;
+               goto out;
        }
 #endif /* CONFIG_IRDA_ULTRA */
 
+       self->ias_obj = irias_new_object(addr->sir_name, jiffies);
+       err = -ENOMEM;
+       if (self->ias_obj == NULL)
+               goto out;
+
        err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
-       if (err < 0)
-               return err;
+       if (err < 0) {
+               kfree(self->ias_obj->name);
+               kfree(self->ias_obj);
+               goto out;
+       }
 
        /*  Register with LM-IAS */
-       self->ias_obj = irias_new_object(addr->sir_name, jiffies);
        irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
                                 self->stsap_sel, IAS_KERNEL_ATTR);
        irias_insert_object(self->ias_obj);
 
-       return 0;
+       err = 0;
+out:
+       unlock_kernel();
+       return err;
 }
 
 /*
@@ -829,24 +854,28 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
        struct sk_buff *skb;
        int err;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
-       err = irda_create(newsock, sk->sk_protocol);
+       lock_kernel();
+       err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
        if (err)
-               return err;
+               goto out;
 
+       err = -EINVAL;
        if (sock->state != SS_UNCONNECTED)
-               return -EINVAL;
+               goto out;
 
        if ((sk = sock->sk) == NULL)
-               return -EINVAL;
+               goto out;
 
+       err = -EOPNOTSUPP;
        if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
            (sk->sk_type != SOCK_DGRAM))
-               return -EOPNOTSUPP;
+               goto out;
 
+       err = -EINVAL;
        if (sk->sk_state != TCP_LISTEN)
-               return -EINVAL;
+               goto out;
 
        /*
         *      The read queue this time is holding sockets ready to use
@@ -867,18 +896,20 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
                        break;
 
                /* Non blocking operation */
+               err = -EWOULDBLOCK;
                if (flags & O_NONBLOCK)
-                       return -EWOULDBLOCK;
+                       goto out;
 
                err = wait_event_interruptible(*(sk->sk_sleep),
                                        skb_peek(&sk->sk_receive_queue));
                if (err)
-                       return err;
+                       goto out;
        }
 
        newsk = newsock->sk;
+       err = -EIO;
        if (newsk == NULL)
-               return -EIO;
+               goto out;
 
        newsk->sk_state = TCP_ESTABLISHED;
 
@@ -886,10 +917,11 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
 
        /* Now attach up the new socket */
        new->tsap = irttp_dup(self->tsap, new);
+       err = -EPERM; /* value does not seem to make sense. -arnd */
        if (!new->tsap) {
-               IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
+               IRDA_DEBUG(0, "%s(), dup failed!\n", __func__);
                kfree_skb(skb);
-               return -1;
+               goto out;
        }
 
        new->stsap_sel = new->tsap->stsap_sel;
@@ -907,17 +939,16 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
        /* Clean up the original one to keep it in listen state */
        irttp_listen(self->tsap);
 
-       /* Wow ! What is that ? Jean II */
-       skb->sk = NULL;
-       skb->destructor = NULL;
        kfree_skb(skb);
        sk->sk_ack_backlog--;
 
        newsock->state = SS_CONNECTED;
 
        irda_connect_response(new);
-
-       return 0;
+       err = 0;
+out:
+       unlock_kernel();
+       return err;
 }
 
 /*
@@ -948,43 +979,49 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
        struct irda_sock *self = irda_sk(sk);
        int err;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
+       lock_kernel();
        /* Don't allow connect for Ultra sockets */
+       err = -ESOCKTNOSUPPORT;
        if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
-               return -ESOCKTNOSUPPORT;
+               goto out;
 
        if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
                sock->state = SS_CONNECTED;
-               return 0;   /* Connect completed during a ERESTARTSYS event */
+               err = 0;
+               goto out;   /* Connect completed during a ERESTARTSYS event */
        }
 
        if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
                sock->state = SS_UNCONNECTED;
-               return -ECONNREFUSED;
+               err = -ECONNREFUSED;
+               goto out;
        }
 
+       err = -EISCONN;      /* No reconnect on a seqpacket socket */
        if (sk->sk_state == TCP_ESTABLISHED)
-               return -EISCONN;      /* No reconnect on a seqpacket socket */
+               goto out;
 
        sk->sk_state   = TCP_CLOSE;
        sock->state = SS_UNCONNECTED;
 
+       err = -EINVAL;
        if (addr_len != sizeof(struct sockaddr_irda))
-               return -EINVAL;
+               goto out;
 
        /* Check if user supplied any destination device address */
        if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) {
                /* Try to find one suitable */
                err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
                if (err) {
-                       IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __FUNCTION__);
-                       return err;
+                       IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__);
+                       goto out;
                }
        } else {
                /* Use the one provided by the user */
                self->daddr = addr->sir_addr;
-               IRDA_DEBUG(1, "%s(), daddr = %08x\n", __FUNCTION__, self->daddr);
+               IRDA_DEBUG(1, "%s(), daddr = %08x\n", __func__, self->daddr);
 
                /* If we don't have a valid service name, we assume the
                 * user want to connect on a specific LSAP. Prevent
@@ -994,8 +1031,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
                        /* Query remote LM-IAS using service name */
                        err = irda_find_lsap_sel(self, addr->sir_name);
                        if (err) {
-                               IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
-                               return err;
+                               IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
+                               goto out;
                        }
                } else {
                        /* Directly connect to the remote LSAP
@@ -1019,30 +1056,36 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
                                    self->saddr, self->daddr, NULL,
                                    self->max_sdu_size_rx, NULL);
        if (err) {
-               IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
-               return err;
+               IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
+               goto out;
        }
 
        /* Now the loop */
+       err = -EINPROGRESS;
        if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
-               return -EINPROGRESS;
+               goto out;
 
+       err = -ERESTARTSYS;
        if (wait_event_interruptible(*(sk->sk_sleep),
                                     (sk->sk_state != TCP_SYN_SENT)))
-               return -ERESTARTSYS;
+               goto out;
 
        if (sk->sk_state != TCP_ESTABLISHED) {
                sock->state = SS_UNCONNECTED;
                err = sock_error(sk);
-               return err? err : -ECONNRESET;
+               if (!err)
+                       err = -ECONNRESET;
+               goto out;
        }
 
        sock->state = SS_CONNECTED;
 
        /* At this point, IrLMP has assigned our source address */
        self->saddr = irttp_get_saddr(self->tsap);
-
-       return 0;
+       err = 0;
+out:
+       unlock_kernel();
+       return err;
 }
 
 static struct proto irda_proto = {
@@ -1057,12 +1100,16 @@ static struct proto irda_proto = {
  *    Create IrDA socket
  *
  */
-static int irda_create(struct socket *sock, int protocol)
+static int irda_create(struct net *net, struct socket *sock, int protocol,
+                      int kern)
 {
        struct sock *sk;
        struct irda_sock *self;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
+
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
 
        /* Check for valid socket type */
        switch (sock->type) {
@@ -1075,20 +1122,15 @@ static int irda_create(struct socket *sock, int protocol)
        }
 
        /* Allocate networking socket */
-       sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
+       sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto);
        if (sk == NULL)
                return -ENOMEM;
 
        self = irda_sk(sk);
-       IRDA_DEBUG(2, "%s() : self is %p\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s() : self is %p\n", __func__, self);
 
        init_waitqueue_head(&self->query_wait);
 
-       /* Initialise networking socket struct */
-       sock_init_data(sock, sk);       /* Note : set sk->sk_refcnt to 1 */
-       sk->sk_family = PF_IRDA;
-       sk->sk_protocol = protocol;
-
        switch (sock->type) {
        case SOCK_STREAM:
                sock->ops = &irda_stream_ops;
@@ -1115,15 +1157,20 @@ static int irda_create(struct socket *sock, int protocol)
                        self->max_sdu_size_rx = TTP_SAR_UNBOUND;
                        break;
                default:
-                       IRDA_ERROR("%s: protocol not supported!\n",
-                                  __FUNCTION__);
+                       sk_free(sk);
                        return -ESOCKTNOSUPPORT;
                }
                break;
        default:
+               sk_free(sk);
                return -ESOCKTNOSUPPORT;
        }
 
+       /* Initialise networking socket struct */
+       sock_init_data(sock, sk);       /* Note : set sk->sk_refcnt to 1 */
+       sk->sk_family = PF_IRDA;
+       sk->sk_protocol = protocol;
+
        /* Register as a client with IrLMP */
        self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
        self->mask.word = 0xffff;
@@ -1142,7 +1189,7 @@ static int irda_create(struct socket *sock, int protocol)
  */
 static void irda_destroy_socket(struct irda_sock *self)
 {
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        /* Unregister with IrLMP */
        irlmp_unregister_client(self->ckey);
@@ -1179,11 +1226,12 @@ static int irda_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
 
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(2, "%s()\n", __func__);
 
        if (sk == NULL)
                return 0;
 
+       lock_kernel();
        lock_sock(sk);
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
@@ -1202,6 +1250,7 @@ static int irda_release(struct socket *sock)
        /* Destroy networking socket if we are the last reference on it,
         * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */
        sock_put(sk);
+       unlock_kernel();
 
        /* Notes on socket locking and deallocation... - Jean II
         * In theory we should put pairs of sock_hold() / sock_put() to
@@ -1247,35 +1296,44 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        struct sk_buff *skb;
        int err = -EPIPE;
 
-       IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
+       IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
 
+       lock_kernel();
        /* Note : socket.c set MSG_EOR on SEQPACKET sockets */
        if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT |
-                              MSG_NOSIGNAL))
-               return -EINVAL;
+                              MSG_NOSIGNAL)) {
+               err = -EINVAL;
+               goto out;
+       }
 
        if (sk->sk_shutdown & SEND_SHUTDOWN)
                goto out_err;
 
-       if (sk->sk_state != TCP_ESTABLISHED)
-               return -ENOTCONN;
+       if (sk->sk_state != TCP_ESTABLISHED) {
+               err = -ENOTCONN;
+               goto out;
+       }
 
        self = irda_sk(sk);
 
        /* Check if IrTTP is wants us to slow down */
 
        if (wait_event_interruptible(*(sk->sk_sleep),
-           (self->tx_flow != FLOW_STOP  ||  sk->sk_state != TCP_ESTABLISHED)))
-               return -ERESTARTSYS;
+           (self->tx_flow != FLOW_STOP  ||  sk->sk_state != TCP_ESTABLISHED))) {
+               err = -ERESTARTSYS;
+               goto out;
+       }
 
        /* Check if we are still connected */
-       if (sk->sk_state != TCP_ESTABLISHED)
-               return -ENOTCONN;
+       if (sk->sk_state != TCP_ESTABLISHED) {
+               err = -ENOTCONN;
+               goto out;
+       }
 
        /* Check that we don't send out too big frames */
        if (len > self->max_data_size) {
                IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n",
-                          __FUNCTION__, len, self->max_data_size);
+                          __func__, len, self->max_data_size);
                len = self->max_data_size;
        }
 
@@ -1299,14 +1357,19 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
         */
        err = irttp_data_request(self->tsap, skb);
        if (err) {
-               IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
+               IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
                goto out_err;
        }
+
+       unlock_kernel();
        /* Tell client how much data we actually sent */
        return len;
 
- out_err:
-       return sk_stream_error(sk, msg->msg_flags, err);
+out_err:
+       err = sk_stream_error(sk, msg->msg_flags, err);
+out:
+       unlock_kernel();
+       return err;
 
 }
 
@@ -1325,22 +1388,23 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
        size_t copied;
        int err;
 
-       IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(4, "%s()\n", __func__);
 
+       lock_kernel();
        if ((err = sock_error(sk)) < 0)
-               return err;
+               goto out;
 
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
-               return err;
+               goto out;
 
        skb_reset_transport_header(skb);
        copied = skb->len;
 
        if (copied > size) {
                IRDA_DEBUG(2, "%s(), Received truncated frame (%zd < %zd)!\n",
-                          __FUNCTION__, copied, size);
+                          __func__, copied, size);
                copied = size;
                msg->msg_flags |= MSG_TRUNC;
        }
@@ -1356,13 +1420,17 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
         */
        if (self->rx_flow == FLOW_STOP) {
                if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) {
-                       IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
+                       IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __func__);
                        self->rx_flow = FLOW_START;
                        irttp_flow_request(self->tsap, FLOW_START);
                }
        }
-
+       unlock_kernel();
        return copied;
+
+out:
+       unlock_kernel();
+       return err;
 }
 
 /*
@@ -1378,17 +1446,21 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        int target, err;
        long timeo;
 
-       IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(3, "%s()\n", __func__);
 
+       lock_kernel();
        if ((err = sock_error(sk)) < 0)
-               return err;
+               goto out;
 
+       err = -EINVAL;
        if (sock->flags & __SO_ACCEPTCON)
-               return(-EINVAL);
+               goto out;
 
+       err =-EOPNOTSUPP;
        if (flags & MSG_OOB)
-               return -EOPNOTSUPP;
+               goto out;
 
+       err = 0;
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
        timeo = sock_rcvtimeo(sk, noblock);
 
@@ -1400,7 +1472,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
 
                if (skb == NULL) {
                        DEFINE_WAIT(wait);
-                       int ret = 0;
+                       err = 0;
 
                        if (copied >= target)
                                break;
@@ -1410,25 +1482,25 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
-                       ret = sock_error(sk);
-                       if (ret)
+                       err = sock_error(sk);
+                       if (err)
                                ;
                        else if (sk->sk_shutdown & RCV_SHUTDOWN)
                                ;
                        else if (noblock)
-                               ret = -EAGAIN;
+                               err = -EAGAIN;
                        else if (signal_pending(current))
-                               ret = sock_intr_errno(timeo);
+                               err = sock_intr_errno(timeo);
                        else if (sk->sk_state != TCP_ESTABLISHED)
-                               ret = -ENOTCONN;
+                               err = -ENOTCONN;
                        else if (skb_peek(&sk->sk_receive_queue) == NULL)
                                /* Wait process until data arrives */
                                schedule();
 
                        finish_wait(sk->sk_sleep, &wait);
 
-                       if (ret)
-                               return ret;
+                       if (err)
+                               goto out;
                        if (sk->sk_shutdown & RCV_SHUTDOWN)
                                break;
 
@@ -1452,14 +1524,14 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
                        /* put the skb back if we didn't use it up.. */
                        if (skb->len) {
                                IRDA_DEBUG(1, "%s(), back on q!\n",
-                                          __FUNCTION__);
+                                          __func__);
                                skb_queue_head(&sk->sk_receive_queue, skb);
                                break;
                        }
 
                        kfree_skb(skb);
                } else {
-                       IRDA_DEBUG(0, "%s() questionable!?\n", __FUNCTION__);
+                       IRDA_DEBUG(0, "%s() questionable!?\n", __func__);
 
                        /* put message back and return */
                        skb_queue_head(&sk->sk_receive_queue, skb);
@@ -1475,13 +1547,15 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
         */
        if (self->rx_flow == FLOW_STOP) {
                if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) {
-                       IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
+                       IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __func__);
                        self->rx_flow = FLOW_START;
                        irttp_flow_request(self->tsap, FLOW_START);
                }
        }
 
-       return copied;
+out:
+       unlock_kernel();
+       return err ? : copied;
 }
 
 /*
@@ -1499,18 +1573,23 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
        struct sk_buff *skb;
        int err;
 
-       IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
+       lock_kernel();
+
+       IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
 
+       err = -EINVAL;
        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
-               return -EINVAL;
+               goto out;
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
                send_sig(SIGPIPE, current, 0);
-               return -EPIPE;
+               err = -EPIPE;
+               goto out;
        }
 
+       err = -ENOTCONN;
        if (sk->sk_state != TCP_ESTABLISHED)
-               return -ENOTCONN;
+               goto out;
 
        self = irda_sk(sk);
 
@@ -1521,24 +1600,25 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
        if (len > self->max_data_size) {
                IRDA_DEBUG(0, "%s(), Warning to much data! "
                           "Chopping frame from %zd to %d bytes!\n",
-                          __FUNCTION__, len, self->max_data_size);
+                          __func__, len, self->max_data_size);
                len = self->max_data_size;
        }
 
        skb = sock_alloc_send_skb(sk, len + self->max_header_size,
                                  msg->msg_flags & MSG_DONTWAIT, &err);
+       err = -ENOBUFS;
        if (!skb)
-               return -ENOBUFS;
+               goto out;
 
        skb_reserve(skb, self->max_header_size);
        skb_reset_transport_header(skb);
 
-       IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
+       IRDA_DEBUG(4, "%s(), appending user data\n", __func__);
        skb_put(skb, len);
        err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
        if (err) {
                kfree_skb(skb);
-               return err;
+               goto out;
        }
 
        /*
@@ -1547,10 +1627,14 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
         */
        err = irttp_udata_request(self->tsap, skb);
        if (err) {
-               IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
-               return err;
+               IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
+               goto out;
        }
+       unlock_kernel();
        return len;
+out:
+       unlock_kernel();
+       return err;
 }
 
 /*
@@ -1570,14 +1654,17 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        struct sk_buff *skb;
        int err;
 
-       IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
+       IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
 
+       lock_kernel();
+       err = -EINVAL;
        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
-               return -EINVAL;
+               goto out;
 
+       err = -EPIPE;
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
                send_sig(SIGPIPE, current, 0);
-               return -EPIPE;
+               goto out;
        }
 
        self = irda_sk(sk);
@@ -1585,16 +1672,18 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        /* Check if an address was specified with sendto. Jean II */
        if (msg->msg_name) {
                struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name;
+               err = -EINVAL;
                /* Check address, extract pid. Jean II */
                if (msg->msg_namelen < sizeof(*addr))
-                       return -EINVAL;
+                       goto out;
                if (addr->sir_family != AF_IRDA)
-                       return -EINVAL;
+                       goto out;
 
                pid = addr->sir_lsap_sel;
                if (pid & 0x80) {
-                       IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __FUNCTION__);
-                       return -EOPNOTSUPP;
+                       IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
+                       err = -EOPNOTSUPP;
+                       goto out;
                }
        } else {
                /* Check that the socket is properly bound to an Ultra
@@ -1602,8 +1691,9 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
                if ((self->lsap == NULL) ||
                    (sk->sk_state != TCP_ESTABLISHED)) {
                        IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n",
-                                  __FUNCTION__);
-                       return -ENOTCONN;
+                                  __func__);
+                       err = -ENOTCONN;
+                       goto out;
                }
                /* Use PID from socket */
                bound = 1;
@@ -1616,33 +1706,34 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        if (len > self->max_data_size) {
                IRDA_DEBUG(0, "%s(), Warning to much data! "
                           "Chopping frame from %zd to %d bytes!\n",
-                          __FUNCTION__, len, self->max_data_size);
+                          __func__, len, self->max_data_size);
                len = self->max_data_size;
        }
 
        skb = sock_alloc_send_skb(sk, len + self->max_header_size,
                                  msg->msg_flags & MSG_DONTWAIT, &err);
+       err = -ENOBUFS;
        if (!skb)
-               return -ENOBUFS;
+               goto out;
 
        skb_reserve(skb, self->max_header_size);
        skb_reset_transport_header(skb);
 
-       IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
+       IRDA_DEBUG(4, "%s(), appending user data\n", __func__);
        skb_put(skb, len);
        err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
        if (err) {
                kfree_skb(skb);
-               return err;
+               goto out;
        }
 
        err = irlmp_connless_data_request((bound ? self->lsap : NULL),
                                          skb, pid);
-       if (err) {
-               IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
-               return err;
-       }
-       return len;
+       if (err)
+               IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
+out:
+       unlock_kernel();
+       return err ? : len;
 }
 #endif /* CONFIG_IRDA_ULTRA */
 
@@ -1654,7 +1745,9 @@ static int irda_shutdown(struct socket *sock, int how)
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
 
-       IRDA_DEBUG(1, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(1, "%s(%p)\n", __func__, self);
+
+       lock_kernel();
 
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
@@ -1676,6 +1769,8 @@ static int irda_shutdown(struct socket *sock, int how)
        self->daddr = DEV_ADDR_ANY;     /* Until we get re-connected */
        self->saddr = 0x0;              /* so IrLMP assign us any link */
 
+       unlock_kernel();
+
        return 0;
 }
 
@@ -1689,8 +1784,9 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
        struct irda_sock *self = irda_sk(sk);
        unsigned int mask;
 
-       IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+       IRDA_DEBUG(4, "%s()\n", __func__);
 
+       lock_kernel();
        poll_wait(file, sk->sk_sleep, wait);
        mask = 0;
 
@@ -1698,7 +1794,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
        if (sk->sk_err)
                mask |= POLLERR;
        if (sk->sk_shutdown & RCV_SHUTDOWN) {
-               IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
+               IRDA_DEBUG(0, "%s(), POLLHUP\n", __func__);
                mask |= POLLHUP;
        }
 
@@ -1712,7 +1808,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
        switch (sk->sk_type) {
        case SOCK_STREAM:
                if (sk->sk_state == TCP_CLOSE) {
-                       IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
+                       IRDA_DEBUG(0, "%s(), POLLHUP\n", __func__);
                        mask |= POLLHUP;
                }
 
@@ -1738,27 +1834,43 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
        default:
                break;
        }
+       unlock_kernel();
        return mask;
 }
 
+static unsigned int irda_datagram_poll(struct file *file, struct socket *sock,
+                          poll_table *wait)
+{
+       int err;
+
+       lock_kernel();
+       err = datagram_poll(file, sock, wait);
+       unlock_kernel();
+
+       return err;
+}
+
 /*
  * Function irda_ioctl (sock, cmd, arg)
  */
 static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
+       int err;
 
-       IRDA_DEBUG(4, "%s(), cmd=%#x\n", __FUNCTION__, cmd);
+       IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd);
 
+       lock_kernel();
+       err = -EINVAL;
        switch (cmd) {
        case TIOCOUTQ: {
                long amount;
-               amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
+
+               amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
                if (amount < 0)
                        amount = 0;
-               if (put_user(amount, (unsigned int __user *)arg))
-                       return -EFAULT;
-               return 0;
+               err = put_user(amount, (unsigned int __user *)arg);
+               break;
        }
 
        case TIOCINQ: {
@@ -1767,15 +1879,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                /* These two are safe on a single CPU system as only user tasks fiddle here */
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
-               if (put_user(amount, (unsigned int __user *)arg))
-                       return -EFAULT;
-               return 0;
+               err = put_user(amount, (unsigned int __user *)arg);
+               break;
        }
 
        case SIOCGSTAMP:
                if (sk != NULL)
-                       return sock_get_timestamp(sk, (struct timeval __user *)arg);
-               return -EINVAL;
+                       err = sock_get_timestamp(sk, (struct timeval __user *)arg);
+               break;
 
        case SIOCGIFADDR:
        case SIOCSIFADDR:
@@ -1787,14 +1898,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCSIFNETMASK:
        case SIOCGIFMETRIC:
        case SIOCSIFMETRIC:
-               return -EINVAL;
+               break;
        default:
-               IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
-               return -ENOIOCTLCMD;
+               IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__);
+               err = -ENOIOCTLCMD;
        }
+       unlock_kernel();
 
-       /*NOTREACHED*/
-       return 0;
+       return err;
 }
 
 #ifdef CONFIG_COMPAT
@@ -1816,17 +1927,17 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
  *    Set some options for the socket
  *
  */
-static int irda_setsockopt(struct socket *sock, int level, int optname,
-                          char __user *optval, int optlen)
+static int __irda_setsockopt(struct socket *sock, int level, int optname,
+                          char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
        struct irda_ias_set    *ias_opt;
        struct ias_object      *ias_obj;
        struct ias_attrib *     ias_attr;       /* Attribute in IAS object */
-       int opt;
+       int opt, free_ias = 0;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        if (level != SOL_IRLMP)
                return -ENOPROTOOPT;
@@ -1880,11 +1991,20 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        /* Create a new object */
                        ias_obj = irias_new_object(ias_opt->irda_class_name,
                                                   jiffies);
+                       if (ias_obj == NULL) {
+                               kfree(ias_opt);
+                               return -ENOMEM;
+                       }
+                       free_ias = 1;
                }
 
                /* Do we have the attribute already ? */
                if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
                        kfree(ias_opt);
+                       if (free_ias) {
+                               kfree(ias_obj->name);
+                               kfree(ias_obj);
+                       }
                        return -EINVAL;
                }
 
@@ -1903,6 +2023,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        if(ias_opt->attribute.irda_attrib_octet_seq.len >
                           IAS_MAX_OCTET_STRING) {
                                kfree(ias_opt);
+                               if (free_ias) {
+                                       kfree(ias_obj->name);
+                                       kfree(ias_obj);
+                               }
+
                                return -EINVAL;
                        }
                        /* Add an octet sequence attribute */
@@ -1931,6 +2056,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        break;
                default :
                        kfree(ias_opt);
+                       if (free_ias) {
+                               kfree(ias_obj->name);
+                               kfree(ias_obj);
+                       }
                        return -EINVAL;
                }
                irias_insert_object(ias_obj);
@@ -1987,7 +2116,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
 
                /* Check is the user space own the object */
                if(ias_attr->value->owner != IAS_USER_ATTR) {
-                       IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __FUNCTION__);
+                       IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__);
                        kfree(ias_opt);
                        return -EPERM;
                }
@@ -2006,11 +2135,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                /* Only possible for a seqpacket service (TTP with SAR) */
                if (sk->sk_type != SOCK_SEQPACKET) {
                        IRDA_DEBUG(2, "%s(), setting max_sdu_size = %d\n",
-                                  __FUNCTION__, opt);
+                                  __func__, opt);
                        self->max_sdu_size_rx = opt;
                } else {
                        IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
-                                    __FUNCTION__);
+                                    __func__);
                        return -ENOPROTOOPT;
                }
                break;
@@ -2056,6 +2185,18 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
        return 0;
 }
 
+static int irda_setsockopt(struct socket *sock, int level, int optname,
+                          char __user *optval, unsigned int optlen)
+{
+       int err;
+
+       lock_kernel();
+       err = __irda_setsockopt(sock, level, optname, optval, optlen);
+       unlock_kernel();
+
+       return err;
+}
+
 /*
  * Function irda_extract_ias_value(ias_opt, ias_value)
  *
@@ -2108,7 +2249,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
 /*
  * Function irda_getsockopt (sock, level, optname, optval, optlen)
  */
-static int irda_getsockopt(struct socket *sock, int level, int optname,
+static int __irda_getsockopt(struct socket *sock, int level, int optname,
                           char __user *optval, int __user *optlen)
 {
        struct sock *sk = sock->sk;
@@ -2124,7 +2265,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
        int err;
        int offset, total;
 
-       IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
+       IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        if (level != SOL_IRLMP)
                return -ENOPROTOOPT;
@@ -2285,7 +2426,7 @@ bed:
                /* Check that we can proceed with IAP */
                if (self->iriap) {
                        IRDA_WARNING("%s: busy with a previous query\n",
-                                    __FUNCTION__);
+                                    __func__);
                        kfree(ias_opt);
                        return -EBUSY;
                }
@@ -2381,13 +2522,12 @@ bed:
                if (!self->cachedaddr) {
                        int ret = 0;
 
-                       IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __FUNCTION__);
+                       IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__);
 
                        /* Set watchdog timer to expire in <val> ms. */
                        self->errno = 0;
-                       init_timer(&self->watchdog);
-                       self->watchdog.function = irda_discovery_timeout;
-                       self->watchdog.data = (unsigned long) self;
+                       setup_timer(&self->watchdog, irda_discovery_timeout,
+                                       (unsigned long)self);
                        self->watchdog.expires = jiffies + (val * HZ/1000);
                        add_timer(&(self->watchdog));
 
@@ -2400,14 +2540,14 @@ bed:
                        if(timer_pending(&(self->watchdog)))
                                del_timer(&(self->watchdog));
 
-                       IRDA_DEBUG(1, "%s(), ...waking up !\n", __FUNCTION__);
+                       IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__);
 
                        if (ret != 0)
                                return ret;
                }
                else
                        IRDA_DEBUG(1, "%s(), found immediately !\n",
-                                  __FUNCTION__);
+                                  __func__);
 
                /* Tell IrLMP that we have been notified */
                irlmp_update_client(self->ckey, self->mask.word,
@@ -2437,13 +2577,25 @@ bed:
        return 0;
 }
 
-static struct net_proto_family irda_family_ops = {
+static int irda_getsockopt(struct socket *sock, int level, int optname,
+                          char __user *optval, int __user *optlen)
+{
+       int err;
+
+       lock_kernel();
+       err = __irda_getsockopt(sock, level, optname, optval, optlen);
+       unlock_kernel();
+
+       return err;
+}
+
+static const struct net_proto_family irda_family_ops = {
        .family = PF_IRDA,
        .create = irda_create,
        .owner  = THIS_MODULE,
 };
 
-static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
+static const struct proto_ops irda_stream_ops = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2467,7 +2619,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
        .sendpage =     sock_no_sendpage,
 };
 
-static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
+static const struct proto_ops irda_seqpacket_ops = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2476,7 +2628,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
        .socketpair =   sock_no_socketpair,
        .accept =       irda_accept,
        .getname =      irda_getname,
-       .poll =         datagram_poll,
+       .poll =         irda_datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,
@@ -2491,7 +2643,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
        .sendpage =     sock_no_sendpage,
 };
 
-static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
+static const struct proto_ops irda_dgram_ops = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2500,7 +2652,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
        .socketpair =   sock_no_socketpair,
        .accept =       irda_accept,
        .getname =      irda_getname,
-       .poll =         datagram_poll,
+       .poll =         irda_datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,
@@ -2516,7 +2668,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
 };
 
 #ifdef CONFIG_IRDA_ULTRA
-static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
+static const struct proto_ops irda_ultra_ops = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2525,7 +2677,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
        .socketpair =   sock_no_socketpair,
        .accept =       sock_no_accept,
        .getname =      irda_getname,
-       .poll =         datagram_poll,
+       .poll =         irda_datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,
@@ -2541,13 +2693,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
 };
 #endif /* CONFIG_IRDA_ULTRA */
 
-SOCKOPS_WRAP(irda_stream, PF_IRDA);
-SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
-SOCKOPS_WRAP(irda_dgram, PF_IRDA);
-#ifdef CONFIG_IRDA_ULTRA
-SOCKOPS_WRAP(irda_ultra, PF_IRDA);
-#endif /* CONFIG_IRDA_ULTRA */
-
 /*
  * Function irsock_init (pro)
  *