Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[safe/jmp/linux-2.6] / drivers / scsi / iscsi_tcp.c
index 517da3f..7608310 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/types.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/blkdev.h>
 #include <linux/crypto.h>
@@ -205,8 +206,10 @@ static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
 }
 
 static void
-iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_sw_tcp_conn *tcp_sw_conn)
+iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
 {
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
        struct sock *sk = tcp_sw_conn->sock->sk;
 
        /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
@@ -554,7 +557,7 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
                return;
 
        sock_hold(sock->sk);
-       iscsi_sw_tcp_conn_restore_callbacks(tcp_sw_conn);
+       iscsi_sw_tcp_conn_restore_callbacks(conn);
        sock_put(sock->sk);
 
        spin_lock_bh(&session->lock);
@@ -584,9 +587,10 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        struct iscsi_conn *conn = cls_conn->dd_data;
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+       struct socket *sock = tcp_sw_conn->sock;
 
        /* userspace may have goofed up and not bound us */
-       if (!tcp_sw_conn->sock)
+       if (!sock)
                return;
        /*
         * Make sure our recv side is stopped.
@@ -597,6 +601,11 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
        write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
 
+       if (sk_sleep(sock->sk) && waitqueue_active(sk_sleep(sock->sk))) {
+               sock->sk->sk_err = EIO;
+               wake_up_interruptible(sk_sleep(sock->sk));
+       }
+
        iscsi_conn_stop(cls_conn, flag);
        iscsi_sw_tcp_release_conn(conn);
 }
@@ -868,7 +877,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler= iscsi_eh_device_reset,
-       .eh_target_reset_handler= iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .use_clustering         = DISABLE_CLUSTERING,
        .slave_alloc            = iscsi_sw_tcp_slave_alloc,
        .slave_configure        = iscsi_sw_tcp_slave_configure,