sky2: dont enable PME legacy mode
[safe/jmp/linux-2.6] / drivers / scsi / iscsi_tcp.c
index 79a706a..517da3f 100644 (file)
@@ -99,6 +99,27 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
        return total_consumed;
 }
 
+/**
+ * iscsi_sw_sk_state_check - check socket state
+ * @sk: socket
+ *
+ * If the socket is in CLOSE or CLOSE_WAIT we should
+ * not close the connection if there is still some
+ * data pending.
+ */
+static inline int iscsi_sw_sk_state_check(struct sock *sk)
+{
+       struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
+
+       if ((sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) &&
+           !atomic_read(&sk->sk_rmem_alloc)) {
+               ISCSI_SW_TCP_DBG(conn, "TCP_CLOSE|TCP_CLOSE_WAIT\n");
+               iscsi_conn_failure(conn, ISCSI_ERR_TCP_CONN_CLOSE);
+               return -ECONNRESET;
+       }
+       return 0;
+}
+
 static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag)
 {
        struct iscsi_conn *conn = sk->sk_user_data;
@@ -117,6 +138,8 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag)
        rd_desc.count = 1;
        tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv);
 
+       iscsi_sw_sk_state_check(sk);
+
        read_unlock(&sk->sk_callback_lock);
 
        /* If we had to (atomically) map a highmem page,
@@ -137,13 +160,7 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
        conn = (struct iscsi_conn*)sk->sk_user_data;
        session = conn->session;
 
-       if ((sk->sk_state == TCP_CLOSE_WAIT ||
-            sk->sk_state == TCP_CLOSE) &&
-           !atomic_read(&sk->sk_rmem_alloc)) {
-               ISCSI_SW_TCP_DBG(conn, "iscsi_tcp_state_change: "
-                                "TCP_CLOSE|TCP_CLOSE_WAIT\n");
-               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-       }
+       iscsi_sw_sk_state_check(sk);
 
        tcp_conn = conn->dd_data;
        tcp_sw_conn = tcp_conn->dd_data;
@@ -253,8 +270,6 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
 
                if (r < 0) {
                        iscsi_tcp_segment_unmap(segment);
-                       if (copied || r == -EAGAIN)
-                               break;
                        return r;
                }
                copied += r;
@@ -275,11 +290,17 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
 
        while (1) {
                rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment);
-               if (rc < 0) {
+               /*
+                * We may not have been able to send data because the conn
+                * is getting stopped. libiscsi will know so propogate err
+                * for it to do the right thing.
+                */
+               if (rc == -EAGAIN)
+                       return rc;
+               else if (rc < 0) {
                        rc = ISCSI_ERR_XMIT_FAILED;
                        goto error;
-               }
-               if (rc == 0)
+               } else if (rc == 0)
                        break;
 
                consumed += rc;
@@ -463,7 +484,7 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
        }
 
        if (err) {
-               iscsi_conn_failure(conn, err);
+               /* got invalid offset/len */
                return -EIO;
        }
        return 0;
@@ -765,8 +786,7 @@ iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 
 static struct iscsi_cls_session *
 iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
-                           uint16_t qdepth, uint32_t initial_cmdsn,
-                           uint32_t *hostno)
+                           uint16_t qdepth, uint32_t initial_cmdsn)
 {
        struct iscsi_cls_session *cls_session;
        struct iscsi_session *session;
@@ -777,10 +797,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
                return NULL;
        }
 
-       shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, qdepth, 1);
+       shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, 1);
        if (!shost)
                return NULL;
        shost->transportt = iscsi_sw_tcp_scsi_transport;
+       shost->cmd_per_lun = qdepth;
        shost->max_lun = iscsi_max_lun;
        shost->max_id = 0;
        shost->max_channel = 0;
@@ -788,10 +809,9 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
 
        if (iscsi_host_add(shost, NULL))
                goto free_host;
-       *hostno = shost->host_no;
 
        cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost,
-                                         cmds_max,
+                                         cmds_max, 0,
                                          sizeof(struct iscsi_tcp_task) +
                                          sizeof(struct iscsi_sw_tcp_hdrbuf),
                                          initial_cmdsn, 0);
@@ -852,6 +872,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
        .use_clustering         = DISABLE_CLUSTERING,
        .slave_alloc            = iscsi_sw_tcp_slave_alloc,
        .slave_configure        = iscsi_sw_tcp_slave_configure,
+       .target_alloc           = iscsi_target_alloc,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
 };
@@ -882,7 +903,7 @@ static struct iscsi_transport iscsi_sw_tcp_transport = {
                                  ISCSI_USERNAME | ISCSI_PASSWORD |
                                  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
                                  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-                                 ISCSI_LU_RESET_TMO |
+                                 ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
                                  ISCSI_PING_TMO | ISCSI_RECV_TMO |
                                  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
        .host_param_mask        = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |