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)
-                       goto out;
+                       return -ENOTCONN;
 
                saddr.sir_family = AF_IRDA;
                saddr.sir_lsap_sel = self->dtsap_sel;
        /* uaddr_len come to us uninitialised */
        *uaddr_len = sizeof (struct sockaddr_irda);
        memcpy(uaddr, &saddr, *uaddr_len);
-       err = 0;
-out:
-       unlock_kernel();
-       return err;
+
+       return 0;
 }
 
 /*
 
        IRDA_DEBUG(2, "%s()\n", __func__);
 
-       lock_kernel();
+       lock_sock(sk);
+
        if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
            (sk->sk_type != SOCK_DGRAM))
                goto out;
                err = 0;
        }
 out:
-       unlock_kernel();
+       release_sock(sk);
 
        return err;
 }
        if (addr_len != sizeof(struct sockaddr_irda))
                return -EINVAL;
 
-       lock_kernel();
+       lock_sock(sk);
 #ifdef CONFIG_IRDA_ULTRA
        /* Special care for Ultra sockets */
        if ((sk->sk_type == SOCK_DGRAM) &&
 
        err = 0;
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err;
 }
 
 
        IRDA_DEBUG(2, "%s()\n", __func__);
 
-       lock_kernel();
        err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
        if (err)
-               goto out;
+               return err;
 
        err = -EINVAL;
+
+       lock_sock(sk);
        if (sock->state != SS_UNCONNECTED)
                goto out;
 
        irda_connect_response(new);
        err = 0;
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err;
 }
 
 
        IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
-       lock_kernel();
+       lock_sock(sk);
        /* Don't allow connect for Ultra sockets */
        err = -ESOCKTNOSUPPORT;
        if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
 
        if (sk->sk_state != TCP_ESTABLISHED) {
                sock->state = SS_UNCONNECTED;
+               if (sk->sk_prot->disconnect(sk, flags))
+                       sock->state = SS_DISCONNECTING;
                err = sock_error(sk);
                if (!err)
                        err = -ECONNRESET;
        self->saddr = irttp_get_saddr(self->tsap);
        err = 0;
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err;
 }
 
        if (sk == NULL)
                return 0;
 
-       lock_kernel();
        lock_sock(sk);
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
        /* 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
 
        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)) {
                goto out;
        }
 
+       lock_sock(sk);
+
        if (sk->sk_shutdown & SEND_SHUTDOWN)
                goto out_err;
 
                goto out_err;
        }
 
-       unlock_kernel();
+       release_sock(sk);
        /* Tell client how much data we actually sent */
        return len;
 
 out_err:
        err = sk_stream_error(sk, msg->msg_flags, err);
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err;
 
 }
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
-       lock_kernel();
-       if ((err = sock_error(sk)) < 0)
-               goto out;
-
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
-               goto out;
+               return err;
 
        skb_reset_transport_header(skb);
        copied = skb->len;
                        irttp_flow_request(self->tsap, FLOW_START);
                }
        }
-       unlock_kernel();
-       return copied;
 
-out:
-       unlock_kernel();
-       return err;
+       return copied;
 }
 
 /*
 
        IRDA_DEBUG(3, "%s()\n", __func__);
 
-       lock_kernel();
        if ((err = sock_error(sk)) < 0)
-               goto out;
+               return err;
 
-       err = -EINVAL;
        if (sock->flags & __SO_ACCEPTCON)
-               goto out;
+               return -EINVAL;
 
        err =-EOPNOTSUPP;
        if (flags & MSG_OOB)
-               goto out;
+               return -EOPNOTSUPP;
 
        err = 0;
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
                        finish_wait(sk_sleep(sk), &wait);
 
                        if (err)
-                               goto out;
+                               return err;
                        if (sk->sk_shutdown & RCV_SHUTDOWN)
                                break;
 
                }
        }
 
-out:
-       unlock_kernel();
-       return err ? : copied;
+       return copied;
 }
 
 /*
        struct sk_buff *skb;
        int err;
 
-       lock_kernel();
-
        IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
 
-       err = -EINVAL;
        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
-               goto out;
+               return -EINVAL;
+
+       lock_sock(sk);
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
                send_sig(SIGPIPE, current, 0);
                IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
                goto out;
        }
-       unlock_kernel();
+
+       release_sock(sk);
        return len;
+
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err;
 }
 
 
        IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
 
-       lock_kernel();
        err = -EINVAL;
        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
-               goto out;
+               return -EINVAL;
+
+       lock_sock(sk);
 
        err = -EPIPE;
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
        if (err)
                IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
 out:
-       unlock_kernel();
+       release_sock(sk);
        return err ? : len;
 }
 #endif /* CONFIG_IRDA_ULTRA */
 
        IRDA_DEBUG(1, "%s(%p)\n", __func__, self);
 
-       lock_kernel();
+       lock_sock(sk);
 
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
        self->daddr = DEV_ADDR_ANY;     /* Until we get re-connected */
        self->saddr = 0x0;              /* so IrLMP assign us any link */
 
-       unlock_kernel();
+       release_sock(sk);
 
        return 0;
 }
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
-       lock_kernel();
        poll_wait(file, sk_sleep(sk), wait);
        mask = 0;
 
        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;
+       return mask;
 }
 
 /*
 
        IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd);
 
-       lock_kernel();
        err = -EINVAL;
        switch (cmd) {
        case TIOCOUTQ: {
                IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__);
                err = -ENOIOCTLCMD;
        }
-       unlock_kernel();
 
        return err;
 }
  *    Set some options for the socket
  *
  */
-static int __irda_setsockopt(struct socket *sock, int level, int optname,
+static int irda_setsockopt(struct socket *sock, int level, int optname,
                           char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct irda_ias_set    *ias_opt;
        struct ias_object      *ias_obj;
        struct ias_attrib *     ias_attr;       /* Attribute in IAS object */
-       int opt, free_ias = 0;
+       int opt, free_ias = 0, err = 0;
 
        IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
 
        if (level != SOL_IRLMP)
                return -ENOPROTOOPT;
 
+       lock_sock(sk);
+
        switch (optname) {
        case IRLMP_IAS_SET:
                /* The user want to add an attribute to an existing IAS object
                 * create the right attribute...
                 */
 
-               if (optlen != sizeof(struct irda_ias_set))
-                       return -EINVAL;
+               if (optlen != sizeof(struct irda_ias_set)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
-               if (ias_opt == NULL)
-                       return -ENOMEM;
+               if (ias_opt == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
 
                /* Copy query to the driver. */
                if (copy_from_user(ias_opt, optval, optlen)) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
 
                /* Find the object we target.
                if(ias_opt->irda_class_name[0] == '\0') {
                        if(self->ias_obj == NULL) {
                                kfree(ias_opt);
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto out;
                        }
                        ias_obj = self->ias_obj;
                } else
                if((!capable(CAP_NET_ADMIN)) &&
                   ((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
                        kfree(ias_opt);
-                       return -EPERM;
+                       err = -EPERM;
+                       goto out;
                }
 
                /* If the object doesn't exist, create it */
                                                   jiffies);
                        if (ias_obj == NULL) {
                                kfree(ias_opt);
-                               return -ENOMEM;
+                               err = -ENOMEM;
+                               goto out;
                        }
                        free_ias = 1;
                }
                                kfree(ias_obj->name);
                                kfree(ias_obj);
                        }
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                /* Look at the type */
                                        kfree(ias_obj);
                                }
 
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto out;
                        }
                        /* Add an octet sequence attribute */
                        irias_add_octseq_attrib(
                                kfree(ias_obj->name);
                                kfree(ias_obj);
                        }
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
                irias_insert_object(ias_obj);
                kfree(ias_opt);
                 * object is not owned by the kernel and delete it.
                 */
 
-               if (optlen != sizeof(struct irda_ias_set))
-                       return -EINVAL;
+               if (optlen != sizeof(struct irda_ias_set)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
-               if (ias_opt == NULL)
-                       return -ENOMEM;
+               if (ias_opt == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
 
                /* Copy query to the driver. */
                if (copy_from_user(ias_opt, optval, optlen)) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
 
                /* Find the object we target.
                        ias_obj = irias_find_object(ias_opt->irda_class_name);
                if(ias_obj == (struct ias_object *) NULL) {
                        kfree(ias_opt);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                /* Only ROOT can mess with the global IAS database.
                if((!capable(CAP_NET_ADMIN)) &&
                   ((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
                        kfree(ias_opt);
-                       return -EPERM;
+                       err = -EPERM;
+                       goto out;
                }
 
                /* Find the attribute (in the object) we target */
                                             ias_opt->irda_attrib_name);
                if(ias_attr == (struct ias_attrib *) NULL) {
                        kfree(ias_opt);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                /* 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", __func__);
                        kfree(ias_opt);
-                       return -EPERM;
+                       err = -EPERM;
+                       goto out;
                }
 
                /* Remove the attribute (and maybe the object) */
                kfree(ias_opt);
                break;
        case IRLMP_MAX_SDU_SIZE:
-               if (optlen < sizeof(int))
-                       return -EINVAL;
+               if (optlen < sizeof(int)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
-               if (get_user(opt, (int __user *)optval))
-                       return -EFAULT;
+               if (get_user(opt, (int __user *)optval)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
                /* Only possible for a seqpacket service (TTP with SAR) */
                if (sk->sk_type != SOCK_SEQPACKET) {
                } else {
                        IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
                                     __func__);
-                       return -ENOPROTOOPT;
+                       err = -ENOPROTOOPT;
+                       goto out;
                }
                break;
        case IRLMP_HINTS_SET:
-               if (optlen < sizeof(int))
-                       return -EINVAL;
+               if (optlen < sizeof(int)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                /* The input is really a (__u8 hints[2]), easier as an int */
-               if (get_user(opt, (int __user *)optval))
-                       return -EFAULT;
+               if (get_user(opt, (int __user *)optval)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
                /* Unregister any old registration */
                if (self->skey)
                 * making a discovery (nodes which don't match any hint
                 * bit in the mask are not reported).
                 */
-               if (optlen < sizeof(int))
-                       return -EINVAL;
+               if (optlen < sizeof(int)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                /* The input is really a (__u8 hints[2]), easier as an int */
-               if (get_user(opt, (int __user *)optval))
-                       return -EFAULT;
+               if (get_user(opt, (int __user *)optval)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
                /* Set the new hint mask */
                self->mask.word = (__u16) opt;
 
                break;
        default:
-               return -ENOPROTOOPT;
+               err = -ENOPROTOOPT;
+               break;
        }
-       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();
+out:
+       release_sock(sk);
 
        return err;
 }
 /*
  * 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;
        int daddr = DEV_ADDR_ANY;       /* Dest address for IAS queries */
        int val = 0;
        int len = 0;
-       int err;
+       int err = 0;
        int offset, total;
 
        IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
        if(len < 0)
                return -EINVAL;
 
+       lock_sock(sk);
+
        switch (optname) {
        case IRLMP_ENUMDEVICES:
                /* Ask lmp for the current discovery log */
                discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
                                                    self->nslots);
                /* Check if the we got some results */
-               if (discoveries == NULL)
-                       return -EAGAIN;         /* Didn't find any devices */
-               err = 0;
+               if (discoveries == NULL) {
+                       err = -EAGAIN;
+                       goto out;               /* Didn't find any devices */
+               }
 
                /* Write total list length back to client */
                if (copy_to_user(optval, &list,
                        sizeof(struct irda_device_info);
 
                /* Copy the list itself - watch for overflow */
-               if(list.len > 2048)
-               {
+               if (list.len > 2048) {
                        err = -EINVAL;
                        goto bed;
                }
 bed:
                /* Free up our buffer */
                kfree(discoveries);
-               if (err)
-                       return err;
                break;
        case IRLMP_MAX_SDU_SIZE:
                val = self->max_data_size;
                len = sizeof(int);
-               if (put_user(len, optlen))
-                       return -EFAULT;
+               if (put_user(len, optlen)) {
+                       err = -EFAULT;
+                       goto out;
+               }
+
+               if (copy_to_user(optval, &val, len)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
-               if (copy_to_user(optval, &val, len))
-                       return -EFAULT;
                break;
        case IRLMP_IAS_GET:
                /* The user want an object from our local IAS database.
                 * that we found */
 
                /* Check that the user has allocated the right space for us */
-               if (len != sizeof(struct irda_ias_set))
-                       return -EINVAL;
+               if (len != sizeof(struct irda_ias_set)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
-               if (ias_opt == NULL)
-                       return -ENOMEM;
+               if (ias_opt == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
 
                /* Copy query to the driver. */
                if (copy_from_user(ias_opt, optval, len)) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
 
                /* Find the object we target.
                        ias_obj = irias_find_object(ias_opt->irda_class_name);
                if(ias_obj == (struct ias_object *) NULL) {
                        kfree(ias_opt);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                /* Find the attribute (in the object) we target */
                                             ias_opt->irda_attrib_name);
                if(ias_attr == (struct ias_attrib *) NULL) {
                        kfree(ias_opt);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                /* Translate from internal to user structure */
                err = irda_extract_ias_value(ias_opt, ias_attr->value);
                if(err) {
                        kfree(ias_opt);
-                       return err;
+                       goto out;
                }
 
                /* Copy reply to the user */
                if (copy_to_user(optval, ias_opt,
                                 sizeof(struct irda_ias_set))) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
                /* Note : don't need to put optlen, we checked it */
                kfree(ias_opt);
                 * then wait for the answer to come back. */
 
                /* Check that the user has allocated the right space for us */
-               if (len != sizeof(struct irda_ias_set))
-                       return -EINVAL;
+               if (len != sizeof(struct irda_ias_set)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
-               if (ias_opt == NULL)
-                       return -ENOMEM;
+               if (ias_opt == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
 
                /* Copy query to the driver. */
                if (copy_from_user(ias_opt, optval, len)) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
 
                /* At this point, there are two cases...
                        daddr = ias_opt->daddr;
                        if((!daddr) || (daddr == DEV_ADDR_ANY)) {
                                kfree(ias_opt);
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto out;
                        }
                }
 
                        IRDA_WARNING("%s: busy with a previous query\n",
                                     __func__);
                        kfree(ias_opt);
-                       return -EBUSY;
+                       err = -EBUSY;
+                       goto out;
                }
 
                self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
 
                if (self->iriap == NULL) {
                        kfree(ias_opt);
-                       return -ENOMEM;
+                       err = -ENOMEM;
+                       goto out;
                }
 
                /* Treat unexpected wakeup as disconnect */
                         * we can free it regardless! */
                        kfree(ias_opt);
                        /* Treat signals as disconnect */
-                       return -EHOSTUNREACH;
+                       err = -EHOSTUNREACH;
+                       goto out;
                }
 
                /* Check what happened */
                        /* Requested object/attribute doesn't exist */
                        if((self->errno == IAS_CLASS_UNKNOWN) ||
                           (self->errno == IAS_ATTRIB_UNKNOWN))
-                               return -EADDRNOTAVAIL;
+                               err = -EADDRNOTAVAIL;
                        else
-                               return -EHOSTUNREACH;
+                               err = -EHOSTUNREACH;
+
+                       goto out;
                }
 
                /* Translate from internal to user structure */
                        irias_delete_value(self->ias_result);
                if (err) {
                        kfree(ias_opt);
-                       return err;
+                       goto out;
                }
 
                /* Copy reply to the user */
                if (copy_to_user(optval, ias_opt,
                                 sizeof(struct irda_ias_set))) {
                        kfree(ias_opt);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
                /* Note : don't need to put optlen, we checked it */
                kfree(ias_opt);
                 */
 
                /* Check that the user is passing us an int */
-               if (len != sizeof(int))
-                       return -EINVAL;
+               if (len != sizeof(int)) {
+                       err = -EINVAL;
+                       goto out;
+               }
                /* Get timeout in ms (max time we block the caller) */
-               if (get_user(val, (int __user *)optval))
-                       return -EFAULT;
+               if (get_user(val, (int __user *)optval)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
                /* Tell IrLMP we want to be notified */
                irlmp_update_client(self->ckey, self->mask.word,
 
                /* Wait until a node is discovered */
                if (!self->cachedaddr) {
-                       int ret = 0;
-
                        IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__);
 
                        /* Set watchdog timer to expire in <val> ms. */
                        /* Wait for IR-LMP to call us back */
                        __wait_event_interruptible(self->query_wait,
                              (self->cachedaddr != 0 || self->errno == -ETIME),
-                                                  ret);
+                                                  err);
 
                        /* If watchdog is still activated, kill it! */
                        if(timer_pending(&(self->watchdog)))
 
                        IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__);
 
-                       if (ret != 0)
-                               return ret;
+                       if (err != 0)
+                               goto out;
                }
                else
                        IRDA_DEBUG(1, "%s(), found immediately !\n",
                 * If the user want more details, he should query
                 * the whole discovery log and pick one device...
                 */
-               if (put_user(daddr, (int __user *)optval))
-                       return -EFAULT;
+               if (put_user(daddr, (int __user *)optval)) {
+                       err = -EFAULT;
+                       goto out;
+               }
 
                break;
        default:
-               return -ENOPROTOOPT;
+               err = -ENOPROTOOPT;
        }
 
-       return 0;
-}
-
-static int irda_getsockopt(struct socket *sock, int level, int optname,
-                          char __user *optval, int __user *optlen)
-{
-       int err;
+out:
 
-       lock_kernel();
-       err = __irda_getsockopt(sock, level, optname, optval, optlen);
-       unlock_kernel();
+       release_sock(sk);
 
        return err;
 }
        .socketpair =   sock_no_socketpair,
        .accept =       irda_accept,
        .getname =      irda_getname,
-       .poll =         irda_datagram_poll,
+       .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,
        .socketpair =   sock_no_socketpair,
        .accept =       irda_accept,
        .getname =      irda_getname,
-       .poll =         irda_datagram_poll,
+       .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,
        .socketpair =   sock_no_socketpair,
        .accept =       sock_no_accept,
        .getname =      irda_getname,
-       .poll =         irda_datagram_poll,
+       .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = irda_compat_ioctl,