static int l2cap_sock_shutdown(struct socket *sock, int how)
{
	struct sock *sk = sock->sk;
	struct l2cap_chan *chan;
	struct l2cap_conn *conn;
	int err = 0;

	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);

	/* 'how' parameter is mapped to sk_shutdown as follows:
	 * SHUT_RD   (0) --> RCV_SHUTDOWN  (1)
	 * SHUT_WR   (1) --> SEND_SHUTDOWN (2)
	 * SHUT_RDWR (2) --> SHUTDOWN_MASK (3)
	 */
	how++;

	if (!sk)
		return 0;

	lock_sock(sk);

	if ((sk->sk_shutdown & how) == how)
		goto shutdown_already;

	BT_DBG("Handling sock shutdown");

	/* prevent sk structure from being freed whilst unlocked */
	sock_hold(sk);

	chan = l2cap_pi(sk)->chan;
	/* prevent chan structure from being freed whilst unlocked */
	l2cap_chan_hold(chan);

	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));

	if (chan->mode == L2CAP_MODE_ERTM &&
	    chan->unacked_frames > 0 &&
	    chan->state == BT_CONNECTED) {
		err = __l2cap_wait_ack(sk, chan);

		/* After waiting for ACKs, check whether shutdown
		 * has already been actioned to close the L2CAP
		 * link such as by l2cap_disconnection_req().
		 */
		if ((sk->sk_shutdown & how) == how)
			goto shutdown_matched;
	}

	/* Try setting the RCV_SHUTDOWN bit, return early if SEND_SHUTDOWN
	 * is already set
	 */
	if ((how & RCV_SHUTDOWN) && !(sk->sk_shutdown & RCV_SHUTDOWN)) {
		sk->sk_shutdown |= RCV_SHUTDOWN;
		if ((sk->sk_shutdown & how) == how)
			goto shutdown_matched;
	}

	sk->sk_shutdown |= SEND_SHUTDOWN;
	release_sock(sk);

	l2cap_chan_lock(chan);
	conn = chan->conn;
	if (conn)
		/* prevent conn structure from being freed */
		l2cap_conn_get(conn);
	l2cap_chan_unlock(chan);

	if (conn)
		/* mutex lock must be taken before l2cap_chan_lock() */
		mutex_lock(&conn->chan_lock);

	l2cap_chan_lock(chan);
	l2cap_chan_close(chan, 0);
	l2cap_chan_unlock(chan);

	if (conn) {
		mutex_unlock(&conn->chan_lock);
		l2cap_conn_put(conn);
	}

	lock_sock(sk);

	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
	    !(current->flags & PF_EXITING))
		err = bt_sock_wait_state(sk, BT_CLOSED,
					 sk->sk_lingertime);

shutdown_matched:
	l2cap_chan_put(chan);
	sock_put(sk);

shutdown_already:
	if (!err && sk->sk_err)
		err = -sk->sk_err;

	release_sock(sk);

	BT_DBG("Sock shutdown complete err: %d", err);

	return err;
}
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
	struct sock *sk = sock->sk;
	struct l2cap_chan *chan;
	struct l2cap_conn *conn;
	int err = 0;

	BT_DBG("sock %p, sk %p, how %d", sock, sk, how);

	 
	how++;

	if (!sk)
		return 0;

	lock_sock(sk);

	if ((sk->sk_shutdown & how) == how)
		goto shutdown_already;

	BT_DBG("Handling sock shutdown");

	 
	sock_hold(sk);

	chan = l2cap_pi(sk)->chan;
	 
	l2cap_chan_hold(chan);

	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));

	if (chan->mode == L2CAP_MODE_ERTM &&
	    chan->unacked_frames > 0 &&
	    chan->state == BT_CONNECTED) {
		err = __l2cap_wait_ack(sk, chan);

		 
		if ((sk->sk_shutdown & how) == how)
			goto shutdown_matched;
	}

	 
	if ((how & RCV_SHUTDOWN) && !(sk->sk_shutdown & RCV_SHUTDOWN)) {
		sk->sk_shutdown |= RCV_SHUTDOWN;
		if ((sk->sk_shutdown & how) == how)
			goto shutdown_matched;
	}

	sk->sk_shutdown |= SEND_SHUTDOWN;
	release_sock(sk);

	l2cap_chan_lock(chan);
	conn = chan->conn;
	if (conn)
		 
		l2cap_conn_get(conn);
	l2cap_chan_unlock(chan);

	if (conn)
		 
		mutex_lock(&conn->chan_lock);

	l2cap_chan_lock(chan);
	l2cap_chan_close(chan, 0);
	l2cap_chan_unlock(chan);

	if (conn) {
		mutex_unlock(&conn->chan_lock);
		l2cap_conn_put(conn);
	}

	lock_sock(sk);

	if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
	    !(current->flags & PF_EXITING))
		err = bt_sock_wait_state(sk, BT_CLOSED,
					 sk->sk_lingertime);

shutdown_matched:
	l2cap_chan_put(chan);
	sock_put(sk);

shutdown_already:
	if (!err && sk->sk_err)
		err = -sk->sk_err;

	release_sock(sk);

	BT_DBG("Sock shutdown complete err: %d", err);

	return err;
}