]> xenbits.xensource.com Git - xenclient/kernel.git/commitdiff
Apply kernel parts of open-iscsi-2.0.865.13.tar.gz git-44a1d2e5c5c935fff3a093a1bcede32912c76421
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:59 +0000 (12:05 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:59 +0000 (12:05 +0000)
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/libiscsi.c
drivers/scsi/scsi_transport_iscsi.c
include/scsi/iscsi_if.h
include/scsi/iscsi_proto.h
include/scsi/libiscsi.h
include/scsi/scsi_transport_iscsi.h

index 86a7aeaae8982c5c79a394473df72e523acc113a..7e6b94922d621bcec122d63e07390d2187588858 100644 (file)
@@ -40,7 +40,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi.h>
-#include <scsi/scsi_transport_iscsi.h>
+#include "scsi_transport_iscsi.h"
 
 #include "iscsi_tcp.h"
 
@@ -109,8 +109,8 @@ iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
 {
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
 
-       crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc);
-       buf->sg.length = tcp_conn->hdr_size;
+       crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
+       buf->sg.length += sizeof(u32);
 }
 
 static inline int
@@ -200,7 +200,7 @@ iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        if (unlikely(!sc))
                return;
 
-       tcp_ctask->xmstate = XMSTATE_VALUE_IDLE;
+       tcp_ctask->xmstate = XMSTATE_IDLE;
        tcp_ctask->r2t = NULL;
 }
 
@@ -237,8 +237,12 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        tcp_ctask->exp_datasn++;
 
        tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
-       if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
+       if (tcp_ctask->data_offset + tcp_conn->in.datalen > sc->request_bufflen) {
+               debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
+                         __FUNCTION__, tcp_ctask->data_offset,
+                         tcp_conn->in.datalen, sc->request_bufflen);
                return ISCSI_ERR_DATA_OFFSET;
+       }
 
        if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
                conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
@@ -375,8 +379,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        spin_lock(&session->lock);
        iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
 
-       if (!ctask->sc || ctask->mtask ||
-            session->state != ISCSI_STATE_LOGGED_IN) {
+       if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
                printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in "
                       "recovery...\n", ctask->itt);
                spin_unlock(&session->lock);
@@ -400,11 +403,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                            r2t->data_length, session->max_burst);
 
        r2t->data_offset = be32_to_cpu(rhdr->data_offset);
-       if (r2t->data_offset + r2t->data_length > ctask->total_length) {
+       if (r2t->data_offset + r2t->data_length > ctask->sc->request_bufflen) {
                spin_unlock(&session->lock);
                printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at "
                       "offset %u and total length %d\n", r2t->data_length,
-                      r2t->data_offset, ctask->total_length);
+                      r2t->data_offset, ctask->sc->request_bufflen);
                return ISCSI_ERR_DATALEN;
        }
 
@@ -415,11 +418,10 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 
        tcp_ctask->exp_datasn = r2tsn + 1;
        __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
-       set_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate);
-       list_move_tail(&ctask->running, &conn->xmitqueue);
-
-       scsi_queue_work(session->host, &conn->xmitwork);
+       tcp_ctask->xmstate |= XMSTATE_SOL_HDR_INIT;
        conn->r2t_pdus_cnt++;
+
+       iscsi_requeue_ctask(ctask);
        spin_unlock(&session->lock);
 
        return 0;
@@ -467,7 +469,8 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
 
                sg_init_one(&sg, (u8 *)hdr,
                            sizeof(struct iscsi_hdr) + ahslen);
-               crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
+               crypto_hash_digest(&tcp_conn->rx_hash, &sg, sg.length,
+                                  (u8 *)&cdgst);
                rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
                                     ahslen);
                if (cdgst != rdgst) {
@@ -598,7 +601,7 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
 {
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
        int buf_left = buf_size - (tcp_conn->data_copied + offset);
-       int size = min(tcp_conn->in.copy, buf_left);
+       unsigned size = min(tcp_conn->in.copy, buf_left);
        int rc;
 
        size = min(size, ctask->data_count);
@@ -607,7 +610,7 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
               size, tcp_conn->in.offset, tcp_conn->in.copied);
 
        BUG_ON(size <= 0);
-       BUG_ON(tcp_ctask->sent + size > ctask->total_length);
+       BUG_ON(tcp_ctask->sent + size > ctask->sc->request_bufflen);
 
        rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
                           (char*)buf + (offset + tcp_conn->data_copied), size);
@@ -674,7 +677,7 @@ iscsi_tcp_copy(struct iscsi_conn *conn, int buf_size)
 }
 
 static inline void
-partial_sg_digest_update(struct crypto_tfm *tfm, struct scatterlist *sg,
+partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg,
                         int offset, int length)
 {
        struct scatterlist temp;
@@ -682,7 +685,7 @@ partial_sg_digest_update(struct crypto_tfm *tfm, struct scatterlist *sg,
        memcpy(&temp, sg, sizeof(struct scatterlist));
        temp.offset = offset;
        temp.length = length;
-       crypto_digest_update(tfm, &temp, 1);
+       crypto_hash_update(desc, &temp, length);
 }
 
 static void
@@ -691,7 +694,7 @@ iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
        struct scatterlist tmp;
 
        sg_init_one(&tmp, buf, len);
-       crypto_digest_update(tcp_conn->rx_tfm, &tmp, 1);
+       crypto_hash_update(&tcp_conn->rx_hash, &tmp, len);
 }
 
 static int iscsi_scsi_data_in(struct iscsi_conn *conn)
@@ -745,12 +748,12 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
                if (!rc) {
                        if (conn->datadgst_en) {
                                if (!offset)
-                                       crypto_digest_update(
-                                                       tcp_conn->rx_tfm,
-                                                       &sg[i], 1);
+                                       crypto_hash_update(
+                                                       &tcp_conn->rx_hash,
+                                                       &sg[i], sg[i].length);
                                else
                                        partial_sg_digest_update(
-                                                       tcp_conn->rx_tfm,
+                                                       &tcp_conn->rx_hash,
                                                        &sg[i],
                                                        sg[i].offset + offset,
                                                        sg[i].length - offset);
@@ -764,9 +767,10 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
                                /*
                                 * data-in is complete, but buffer not...
                                 */
-                               partial_sg_digest_update(tcp_conn->rx_tfm,
-                                               &sg[i],
-                                               sg[i].offset, sg[i].length-rc);
+                               partial_sg_digest_update(&tcp_conn->rx_hash,
+                                                        &sg[i],
+                                                        sg[i].offset,
+                                                        sg[i].length-rc);
                        rc = 0;
                        break;
                }
@@ -884,7 +888,7 @@ more:
                rc = iscsi_tcp_hdr_recv(conn);
                if (!rc && tcp_conn->in.datalen) {
                        if (conn->datadgst_en)
-                               crypto_digest_init(tcp_conn->rx_tfm);
+                               crypto_hash_init(&tcp_conn->rx_hash);
                        tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
                } else if (rc) {
                        iscsi_conn_failure(conn, rc);
@@ -905,10 +909,10 @@ more:
                                          tcp_conn->in.padding);
                                memset(pad, 0, tcp_conn->in.padding);
                                sg_init_one(&sg, pad, tcp_conn->in.padding);
-                               crypto_digest_update(tcp_conn->rx_tfm,
-                                                    &sg, 1);
+                               crypto_hash_update(&tcp_conn->rx_hash,
+                                                  &sg, sg.length);
                        }
-                       crypto_digest_final(tcp_conn->rx_tfm,
+                       crypto_hash_final(&tcp_conn->rx_hash,
                                          (u8 *) &tcp_conn->in.datadgst);
                        debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
                }
@@ -1213,7 +1217,7 @@ static inline void
 iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
                      struct iscsi_tcp_cmd_task *tcp_ctask)
 {
-       crypto_digest_init(tcp_conn->tx_tfm);
+       crypto_hash_init(&tcp_conn->tx_hash);
        tcp_ctask->digest_count = 4;
 }
 
@@ -1285,7 +1289,7 @@ static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
 
        tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count;
        debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count);
-       set_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate);
+       tcp_ctask->xmstate |= XMSTATE_W_PAD;
 }
 
 /**
@@ -1300,7 +1304,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
 
        BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
-       tcp_ctask->xmstate = 1 << XMSTATE_BIT_CMD_HDR_INIT;
+       tcp_ctask->xmstate = XMSTATE_CMD_HDR_INIT;
 }
 
 /**
@@ -1314,10 +1318,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
  *     xmit.
  *
  *     Management xmit state machine consists of these states:
- *             XMSTATE_BIT_IMM_HDR_INIT - calculate digest of PDU Header
- *             XMSTATE_BIT_IMM_HDR      - PDU Header xmit in progress
- *             XMSTATE_BIT_IMM_DATA     - PDU Data xmit in progress
- *             XMSTATE_VALUE_IDLE       - management PDU is done
+ *             XMSTATE_IMM_HDR_INIT    - calculate digest of PDU Header
+ *             XMSTATE_IMM_HDR         - PDU Header xmit in progress
+ *             XMSTATE_IMM_DATA        - PDU Data xmit in progress
+ *             XMSTATE_IDLE            - management PDU is done
  **/
 static int
 iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
@@ -1328,12 +1332,12 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
        debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
                conn->id, tcp_mtask->xmstate, mtask->itt);
 
-       if (test_bit(XMSTATE_BIT_IMM_HDR_INIT, &tcp_mtask->xmstate)) {
+       if (tcp_mtask->xmstate & XMSTATE_IMM_HDR_INIT) {
                iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
                                   sizeof(struct iscsi_hdr));
 
                if (mtask->data_count) {
-                       set_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate);
+                       tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
                        iscsi_buf_init_iov(&tcp_mtask->sendbuf,
                                           (char*)mtask->data,
                                           mtask->data_count);
@@ -1346,20 +1350,21 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
                                        (u8*)tcp_mtask->hdrext);
 
                tcp_mtask->sent = 0;
-               clear_bit(XMSTATE_BIT_IMM_HDR_INIT, &tcp_mtask->xmstate);
-               set_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate);
+               tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR_INIT;
+               tcp_mtask->xmstate |= XMSTATE_IMM_HDR;
        }
 
-       if (test_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate)) {
+       if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) {
                rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf,
                                   mtask->data_count);
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate);
+               tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR;
        }
 
-       if (test_and_clear_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate)) {
+       if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) {
                BUG_ON(!mtask->data_count);
+               tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
                /* FIXME: implement.
                 * Virtual buffer could be spreaded across multiple pages...
                 */
@@ -1369,18 +1374,20 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
                        rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf,
                                        &mtask->data_count, &tcp_mtask->sent);
                        if (rc) {
-                               set_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate);
+                               tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
                                return rc;
                        }
                } while (mtask->data_count);
        }
 
-       BUG_ON(tcp_mtask->xmstate != XMSTATE_VALUE_IDLE);
+       BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE);
        if (mtask->hdr->itt == RESERVED_ITT) {
                struct iscsi_session *session = conn->session;
 
                spin_lock_bh(&session->lock);
-               iscsi_free_mgmt_task(conn, mtask);
+               list_del(&conn->mtask->running);
+               __kfifo_put(session->mgmtpool.queue, (void*)&conn->mtask,
+                           sizeof(void*));
                spin_unlock_bh(&session->lock);
        }
        return 0;
@@ -1393,7 +1400,7 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
        int rc = 0;
 
-       if (test_bit(XMSTATE_BIT_CMD_HDR_INIT, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_INIT) {
                tcp_ctask->sent = 0;
                tcp_ctask->sg_count = 0;
                tcp_ctask->exp_datasn = 0;
@@ -1421,26 +1428,26 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                }
 
                iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr,
-                                 sizeof(struct iscsi_hdr));
+                                 sizeof(struct iscsi_hdr));               
 
                if (conn->hdrdgst_en)
                        iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
                                         (u8*)tcp_ctask->hdrext);
-               clear_bit(XMSTATE_BIT_CMD_HDR_INIT, &tcp_ctask->xmstate);
-               set_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_INIT;
+               tcp_ctask->xmstate |= XMSTATE_CMD_HDR_XMIT;
        }
 
-       if (test_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_XMIT) {
                rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_XMIT;
 
                if (sc->sc_data_direction != DMA_TO_DEVICE)
                        return 0;
 
                if (ctask->imm_count) {
-                       set_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate);
+                       tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
                        iscsi_set_padding(tcp_ctask, ctask->imm_count);
 
                        if (ctask->conn->datadgst_en) {
@@ -1450,10 +1457,9 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                        }
                }
 
-               if (ctask->unsol_count) {
-                       set_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate);
-                       set_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
-               }
+               if (ctask->unsol_count)
+                       tcp_ctask->xmstate |=
+                                       XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
        }
        return rc;
 }
@@ -1465,24 +1471,25 @@ iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        int sent = 0, rc;
 
-       if (test_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_W_PAD) {
                iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
                                   tcp_ctask->pad_count);
                if (conn->datadgst_en)
-                       crypto_digest_update(tcp_conn->tx_tfm,
-                                            &tcp_ctask->sendbuf.sg, 1);
-       } else if (!test_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate))
+                       crypto_hash_update(&tcp_conn->tx_hash,
+                                          &tcp_ctask->sendbuf.sg,
+                                          tcp_ctask->sendbuf.sg.length);
+       } else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
                return 0;
 
-       clear_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate);
-       clear_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate);
+       tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
+       tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD;
        debug_scsi("sending %d pad bytes for itt 0x%x\n",
-                  tcp_ctask->pad_count, ctask->itt); 
+                  tcp_ctask->pad_count, ctask->itt);
        rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
                           &sent);
        if (rc) {
                debug_scsi("padding send failed %d\n", rc);
-               set_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
        }
        return rc;
 }
@@ -1501,12 +1508,12 @@ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
        tcp_ctask = ctask->dd_data;
        tcp_conn = conn->dd_data;
 
-       if (!test_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate)) {
-               crypto_digest_final(tcp_conn->tx_tfm, (u8*)digest);
+       if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
+               crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
                iscsi_buf_init_iov(buf, (char*)digest, 4);
        }
-       clear_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate);
-       
+       tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
+
        rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
        if (!rc)
                debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest,
@@ -1514,7 +1521,7 @@ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
        else {
                debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
                          *digest, ctask->itt);
-               set_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST;
        }
        return rc;
 }
@@ -1536,7 +1543,7 @@ iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
                rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
                *sent = *sent + buf_sent;
                if (buf_sent && conn->datadgst_en)
-                       partial_sg_digest_update(tcp_conn->tx_tfm,
+                       partial_sg_digest_update(&tcp_conn->tx_hash,
                                &sendbuf->sg, sendbuf->sg.offset + offset,
                                buf_sent);
                if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
@@ -1562,8 +1569,8 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        struct iscsi_data_task *dtask;
        int rc;
 
-       set_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
-       if (test_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate)) {
+       tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
+       if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
                dtask = &tcp_ctask->unsol_dtask;
 
                iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
@@ -1573,14 +1580,14 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
                        iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
                                        (u8*)dtask->hdrext);
 
-               clear_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
                iscsi_set_padding(tcp_ctask, ctask->data_count);
        }
 
        rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
        if (rc) {
-               clear_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
-               set_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
+               tcp_ctask->xmstate |= XMSTATE_UNS_HDR;
                return rc;
        }
 
@@ -1601,15 +1608,16 @@ iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
        int rc;
 
-       if (test_and_clear_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) {
                BUG_ON(!ctask->unsol_count);
+               tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
 send_hdr:
                rc = iscsi_send_unsol_hdr(conn, ctask);
                if (rc)
                        return rc;
        }
 
-       if (test_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
                struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask;
                int start = tcp_ctask->sent;
 
@@ -1619,14 +1627,14 @@ send_hdr:
                ctask->unsol_count -= tcp_ctask->sent - start;
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
                /*
                 * Done with the Data-Out. Next, check if we need
                 * to send another unsolicited Data-Out.
                 */
                if (ctask->unsol_count) {
                        debug_scsi("sending more uns\n");
-                       set_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
+                       tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
                        goto send_hdr;
                }
        }
@@ -1642,7 +1650,7 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
        struct iscsi_data_task *dtask;
        int left, rc;
 
-       if (test_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_SOL_HDR_INIT) {
                if (!tcp_ctask->r2t) {
                        spin_lock_bh(&session->lock);
                        __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
@@ -1656,19 +1664,19 @@ send_hdr:
                if (conn->hdrdgst_en)
                        iscsi_hdr_digest(conn, &r2t->headbuf,
                                        (u8*)dtask->hdrext);
-               clear_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate);
-               set_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR_INIT;
+               tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
        }
 
-       if (test_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
                r2t = tcp_ctask->r2t;
                dtask = &r2t->dtask;
 
                rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate);
-               set_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
+               tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
 
                if (conn->datadgst_en) {
                        iscsi_data_digest_init(conn->dd_data, tcp_ctask);
@@ -1681,7 +1689,7 @@ send_hdr:
                        r2t->sent);
        }
 
-       if (test_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
                r2t = tcp_ctask->r2t;
                dtask = &r2t->dtask;
 
@@ -1690,7 +1698,7 @@ send_hdr:
                                     &dtask->digestbuf, &dtask->digest);
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
 
                /*
                 * Done with this Data-Out. Next, check if we have
@@ -1735,32 +1743,32 @@ send_hdr:
  *     xmit stages.
  *
  *iscsi_send_cmd_hdr()
- *     XMSTATE_BIT_CMD_HDR_INIT - prepare Header and Data buffers Calculate
- *                                Header Digest
- *     XMSTATE_BIT_CMD_HDR_XMIT - Transmit header in progress
+ *     XMSTATE_CMD_HDR_INIT - prepare Header and Data buffers Calculate
+ *                            Header Digest
+ *     XMSTATE_CMD_HDR_XMIT - Transmit header in progress
  *
  *iscsi_send_padding
- *     XMSTATE_BIT_W_PAD        - Prepare and send pading
- *     XMSTATE_BIT_W_RESEND_PAD - retry send pading
+ *     XMSTATE_W_PAD        - Prepare and send pading
+ *     XMSTATE_W_RESEND_PAD - retry send pading
  *
  *iscsi_send_digest
- *     XMSTATE_BIT_W_RESEND_DATA_DIGEST - Finalize and send Data Digest
- *     XMSTATE_BIT_W_RESEND_DATA_DIGEST - retry sending digest
+ *     XMSTATE_W_RESEND_DATA_DIGEST - Finalize and send Data Digest
+ *     XMSTATE_W_RESEND_DATA_DIGEST - retry sending digest
  *
  *iscsi_send_unsol_hdr
- *     XMSTATE_BIT_UNS_INIT     - prepare un-solicit data header and digest
- *     XMSTATE_BIT_UNS_HDR      - send un-solicit header
+ *     XMSTATE_UNS_INIT     - prepare un-solicit data header and digest
+ *     XMSTATE_UNS_HDR      - send un-solicit header
  *
  *iscsi_send_unsol_pdu
- *     XMSTATE_BIT_UNS_DATA     - send un-solicit data in progress
+ *     XMSTATE_UNS_DATA     - send un-solicit data in progress
  *
  *iscsi_send_sol_pdu
- *     XMSTATE_BIT_SOL_HDR_INIT - solicit data header and digest initialize
- *     XMSTATE_BIT_SOL_HDR      - send solicit header
- *     XMSTATE_BIT_SOL_DATA     - send solicit data
+ *     XMSTATE_SOL_HDR_INIT - solicit data header and digest initialize
+ *     XMSTATE_SOL_HDR      - send solicit header
+ *     XMSTATE_SOL_DATA     - send solicit data
  *
  *iscsi_tcp_ctask_xmit
- *     XMSTATE_BIT_IMM_DATA     - xmit managment data (??)
+ *     XMSTATE_IMM_DATA     - xmit managment data (??)
  **/
 static int
 iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
@@ -1777,20 +1785,24 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        if (ctask->sc->sc_data_direction != DMA_TO_DEVICE)
                return 0;
 
-       if (test_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate)) {
+       if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
                rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
                                     &tcp_ctask->sent, &ctask->imm_count,
                                     &tcp_ctask->immbuf, &tcp_ctask->immdigest);
                if (rc)
                        return rc;
-               clear_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate);
+               tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
        }
 
        rc = iscsi_send_unsol_pdu(conn, ctask);
        if (rc)
                return rc;
 
-       return iscsi_send_sol_pdu(conn, ctask);
+       rc = iscsi_send_sol_pdu(conn, ctask);
+       if (rc)
+               return rc;
+
+       return rc;
 }
 
 static struct iscsi_cls_conn *
@@ -1820,26 +1832,32 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
        /* initial operational parameters */
        tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
 
-       tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", 0);
-       if (!tcp_conn->tx_tfm) {
+       tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+                                                 CRYPTO_ALG_ASYNC);
+       tcp_conn->tx_hash.flags = 0;
+       if (IS_ERR(tcp_conn->tx_hash.tfm)) {
                printk(KERN_ERR "Could not create connection due to crc32c "
-                       "loading error. Make sure the crc32c module is "
-                       "built as a module or into the kernel.\n");
+                      "loading error %ld. Make sure the crc32c module is "
+                      "built as a module or into the kernel\n",
+                       PTR_ERR(tcp_conn->tx_hash.tfm));
                goto free_tcp_conn;
        }
 
-       tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", 0);
-       if (!tcp_conn->rx_tfm) {
+       tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+                                                 CRYPTO_ALG_ASYNC);
+       tcp_conn->rx_hash.flags = 0;
+       if (IS_ERR(tcp_conn->rx_hash.tfm)) {
                printk(KERN_ERR "Could not create connection due to crc32c "
-                       "loading error. Make sure the crc32c module is "
-                       "built as a module or into the kernel.\n");
+                      "loading error %ld. Make sure the crc32c module is "
+                      "built as a module or into the kernel\n",
+                       PTR_ERR(tcp_conn->rx_hash.tfm));
                goto free_tx_tfm;
        }
 
        return cls_conn;
 
 free_tx_tfm:
-       crypto_free_tfm(tcp_conn->tx_tfm);
+       crypto_free_hash(tcp_conn->tx_hash.tfm);
 free_tcp_conn:
        kfree(tcp_conn);
 tcp_conn_alloc_fail:
@@ -1877,10 +1895,10 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
        iscsi_tcp_release_conn(conn);
        iscsi_conn_teardown(cls_conn);
 
-       if (tcp_conn->tx_tfm)
-               crypto_free_tfm(tcp_conn->tx_tfm);
-       if (tcp_conn->rx_tfm)
-               crypto_free_tfm(tcp_conn->rx_tfm);
+       if (tcp_conn->tx_hash.tfm)
+               crypto_free_hash(tcp_conn->tx_hash.tfm);
+       if (tcp_conn->rx_hash.tfm)
+               crypto_free_hash(tcp_conn->rx_hash.tfm);
 
        kfree(tcp_conn);
 }
@@ -1906,7 +1924,7 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock,
        struct sockaddr_in *sin;
        int rc = 0, len;
 
-       addr = kmalloc(sizeof(*addr), GFP_KERNEL);
+       addr = kmalloc(GFP_KERNEL, sizeof(*addr));
        if (!addr)
                return -ENOMEM;
 
@@ -2003,11 +2021,10 @@ free_socket:
 
 /* called with host lock */
 static void
-iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask,
-                   char *data, uint32_t data_size)
+iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
 {
        struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
-       tcp_mtask->xmstate = 1 << XMSTATE_BIT_IMM_HDR_INIT;
+       tcp_mtask->xmstate = XMSTATE_IMM_HDR_INIT;
 }
 
 static int
@@ -2186,10 +2203,26 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
        stats->custom[2].value = conn->eh_abort_cnt;
 }
 
-static int iscsi_tcp_setup_tasks(struct iscsi_session *session)
+static struct iscsi_cls_session *
+iscsi_tcp_session_create(struct iscsi_transport *iscsit,
+                        struct scsi_transport_template *scsit,
+                        uint16_t cmds_max, uint16_t qdepth,
+                        uint32_t initial_cmdsn, uint32_t *hostno)
 {
+       struct iscsi_cls_session *cls_session;
+       struct iscsi_session *session;
+       uint32_t hn;
        int cmd_i;
 
+       cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
+                                        sizeof(struct iscsi_tcp_cmd_task),
+                                        sizeof(struct iscsi_tcp_mgmt_task),
+                                        initial_cmdsn, &hn);
+       if (!cls_session)
+               return NULL;
+       *hostno = hn;
+
+       session = class_to_transport_session(cls_session);
        for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
                struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
                struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
@@ -2204,66 +2237,12 @@ static int iscsi_tcp_setup_tasks(struct iscsi_session *session)
                mtask->hdr = &tcp_mtask->hdr;
        }
 
-       if (iscsi_r2tpool_alloc(session))
-               return -ENOMEM;
-
-       return 0;
-}
-
-/*
- * iscsi_tcp_session_create2 is a KABI work around. For the new version
- * we pass in the session and default device queue depth.
- */
-static struct iscsi_cls_session *
-iscsi_tcp_session_create2(struct iscsi_transport *iscsit,
-                         struct scsi_transport_template *scsit,
-                         uint16_t cmds_max, uint16_t qdepth,
-                         uint32_t initial_cmdsn, uint32_t *hostno)
-{
-       struct iscsi_cls_session *cls_session;
-       uint32_t hn;
-
-       cls_session = iscsi_session_setup2(iscsit, scsit, cmds_max, qdepth,
-                                         sizeof(struct iscsi_tcp_cmd_task),
-                                         sizeof(struct iscsi_tcp_mgmt_task),
-                                         initial_cmdsn, &hn);
-       if (!cls_session)
-               return NULL;
-       *hostno = hn;
-
-       if (iscsi_tcp_setup_tasks(class_to_transport_session(cls_session)))
-               goto task_setup_fail;
-
-       return cls_session;
-
-task_setup_fail:
-       iscsi_session_teardown(cls_session);
-       return NULL;
-}
-
-static struct iscsi_cls_session *
-iscsi_tcp_session_create(struct iscsi_transport *iscsit,
-                        struct scsi_transport_template *scsit,
-                        uint32_t initial_cmdsn, uint32_t *hostno)
-{
-       struct iscsi_cls_session *cls_session;
-       uint32_t hn;
-
-       cls_session = iscsi_session_setup2(iscsit, scsit, ISCSI_XMIT_CMDS_MAX,
-                                          ISCSI_DEF_CMD_PER_LUN,
-                                          sizeof(struct iscsi_tcp_cmd_task),
-                                          sizeof(struct iscsi_tcp_mgmt_task),
-                                          initial_cmdsn, &hn);
-       if (!cls_session)
-               return NULL;
-       *hostno = hn;
-
-       if (iscsi_tcp_setup_tasks(class_to_transport_session(cls_session)))
-               goto task_setup_fail;
+       if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
+               goto r2tpool_alloc_fail;
 
        return cls_session;
 
-task_setup_fail:
+r2tpool_alloc_fail:
        iscsi_session_teardown(cls_session);
        return NULL;
 }
@@ -2286,14 +2265,15 @@ static struct scsi_host_template iscsi_sht = {
        .name                   = "iSCSI Initiator over TCP/IP",
        .queuecommand           = iscsi_queuecommand,
        .change_queue_depth     = iscsi_change_queue_depth,
-       .can_queue              = ISCSI_XMIT_CMDS_MAX - 1,
+       .can_queue              = ISCSI_DEF_XMIT_CMDS_MAX - 1,
        .sg_tablesize           = ISCSI_SG_TABLESIZE,
        .max_sectors            = 0xFFFF,
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
+       .eh_device_reset_handler= iscsi_eh_device_reset,
        .eh_host_reset_handler  = iscsi_eh_host_reset,
        .use_clustering         = DISABLE_CLUSTERING,
-       .slave_configure        = iscsi_tcp_slave_configure,
+       .slave_configure        = iscsi_tcp_slave_configure,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
 };
@@ -2323,7 +2303,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
                                  ISCSI_TARGET_NAME | ISCSI_TPGT |
                                  ISCSI_USERNAME | ISCSI_PASSWORD |
                                  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
-                                 ISCSI_PING_TMO | ISCSI_RECV_TMO,
+                                 ISCSI_FAST_ABORT,
        .host_param_mask        = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
                                  ISCSI_HOST_INITIATOR_NAME |
                                  ISCSI_HOST_NETDEV_NAME,
@@ -2333,7 +2313,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
        .max_cmd_len            = ISCSI_TCP_MAX_CMD_LEN,
        /* session management */
        .create_session         = iscsi_tcp_session_create,
-       .create_session2        = iscsi_tcp_session_create2,
        .destroy_session        = iscsi_tcp_session_destroy,
        /* connection management */
        .create_conn            = iscsi_tcp_conn_create,
index b91b486b7bdad29504181e036e0bc6ca34c6b66a..4b86fe4d00b6e08f5d661589a3468602e595f79f 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef ISCSI_TCP_H
 #define ISCSI_TCP_H
 
-#include <scsi/libiscsi.h>
+#include "libiscsi.h"
 
 /* Socket's Receive state machine */
 #define IN_PROGRESS_WAIT_HEADER                0x0
 #define IN_PROGRESS_PAD_RECV           0x4
 
 /* xmit state machine */
-#define XMSTATE_VALUE_IDLE                     0
-#define XMSTATE_BIT_CMD_HDR_INIT               0
-#define XMSTATE_BIT_CMD_HDR_XMIT               1
-#define XMSTATE_BIT_IMM_HDR                    2
-#define XMSTATE_BIT_IMM_DATA                   3
-#define XMSTATE_BIT_UNS_INIT                   4
-#define XMSTATE_BIT_UNS_HDR                    5
-#define XMSTATE_BIT_UNS_DATA                   6
-#define XMSTATE_BIT_SOL_HDR                    7
-#define XMSTATE_BIT_SOL_DATA                   8
-#define XMSTATE_BIT_W_PAD                      9
-#define XMSTATE_BIT_W_RESEND_PAD               10
-#define XMSTATE_BIT_W_RESEND_DATA_DIGEST       11
-#define XMSTATE_BIT_IMM_HDR_INIT               12
-#define XMSTATE_BIT_SOL_HDR_INIT               13
+#define XMSTATE_IDLE                   0x0
+#define XMSTATE_CMD_HDR_INIT           0x1
+#define XMSTATE_CMD_HDR_XMIT           0x2
+#define XMSTATE_IMM_HDR                        0x4
+#define XMSTATE_IMM_DATA               0x8
+#define XMSTATE_UNS_INIT               0x10
+#define XMSTATE_UNS_HDR                        0x20
+#define XMSTATE_UNS_DATA               0x40
+#define XMSTATE_SOL_HDR                        0x80
+#define XMSTATE_SOL_DATA               0x100
+#define XMSTATE_W_PAD                  0x200
+#define XMSTATE_W_RESEND_PAD           0x400
+#define XMSTATE_W_RESEND_DATA_DIGEST   0x800
+#define XMSTATE_IMM_HDR_INIT           0x1000
+#define XMSTATE_SOL_HDR_INIT           0x2000
 
 #define ISCSI_PAD_LEN                  4
 #define ISCSI_SG_TABLESIZE             SG_ALL
 #define ISCSI_TCP_MAX_CMD_LEN          16
 
+struct crypto_hash;
 struct socket;
 
 /* Socket connection recieve helper */
@@ -95,8 +96,8 @@ struct iscsi_tcp_conn {
        void                    (*old_write_space)(struct sock *);
 
        /* data and header digests */
-       struct crypto_tfm       *tx_tfm;        /* CRC32C (Tx) */
-       struct crypto_tfm       *rx_tfm;        /* CRC32C (Rx) */
+       struct hash_desc        tx_hash;        /* CRC32C (Tx) */
+       struct hash_desc        rx_hash;        /* CRC32C (Rx) */
 
        /* MIB custom statistics */
        uint32_t                sendpage_failures_cnt;
@@ -121,7 +122,7 @@ struct iscsi_data_task {
 struct iscsi_tcp_mgmt_task {
        struct iscsi_hdr        hdr;
        char                    hdrext[sizeof(__u32)]; /* Header-Digest */
-       unsigned long           xmstate;        /* mgmt xmit progress */
+       int                     xmstate;        /* mgmt xmit progress */
        struct iscsi_buf        headbuf;        /* header buffer */
        struct iscsi_buf        sendbuf;        /* in progress buffer */
        int                     sent;
@@ -149,7 +150,7 @@ struct iscsi_tcp_cmd_task {
        int                     pad_count;              /* padded bytes */
        struct iscsi_buf        headbuf;                /* header buf (xmit) */
        struct iscsi_buf        sendbuf;                /* in progress buffer*/
-       unsigned long           xmstate;                /* xmit xtate machine */
+       int                     xmstate;                /* xmit xtate machine */
        int                     sent;
        struct scatterlist      *sg;                    /* per-cmd SG list  */
        struct scatterlist      *bad_sg;                /* assert statement */
index 6af7606f8cc7c02a2c667df15dc12f109640de1d..0a64150677c28efd617f5fb7c15ec269b2e7d02c 100644 (file)
@@ -22,7 +22,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/types.h>
-#include <linux/mutex.h>
 #include <linux/kfifo.h>
 #include <linux/delay.h>
 #include <asm/unaligned.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi.h>
-#include <scsi/iscsi_proto.h>
 #include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_iscsi.h>
-#include <scsi/libiscsi.h>
+#include "iscsi_proto.h"
+#include "scsi_transport_iscsi.h"
+#include "libiscsi.h"
 
 struct iscsi_session *
 class_to_transport_session(struct iscsi_cls_session *cls_session)
@@ -87,21 +86,13 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
                 * xmit thread
                 */
                if (!list_empty(&session->leadconn->xmitqueue) ||
-                   __kfifo_len(session->leadconn->mgmtqueue))
+                   !list_empty(&session->leadconn->mgmtqueue))
                        scsi_queue_work(session->host,
                                        &session->leadconn->xmitwork);
        }
 }
 EXPORT_SYMBOL_GPL(iscsi_update_cmdsn);
 
-int iscsi_check_assign_cmdsn(struct iscsi_session *session,
-                            struct iscsi_nopin *hdr)
-{
-       iscsi_update_cmdsn(session, hdr);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn);
-
 void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
                                   struct iscsi_data *hdr)
 {
@@ -181,19 +172,19 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
                ctask->unsol_datasn = 0;
 
                if (session->imm_data_en) {
-                       if (ctask->total_length >= session->first_burst)
+                       if (sc->request_bufflen >= session->first_burst)
                                ctask->imm_count = min(session->first_burst,
                                                        conn->max_xmit_dlength);
                        else
-                               ctask->imm_count = min(ctask->total_length,
+                               ctask->imm_count = min(sc->request_bufflen,
                                                        conn->max_xmit_dlength);
                        hton24(ctask->hdr->dlength, ctask->imm_count);
                } else
                        zero_data(ctask->hdr->dlength);
 
                if (!session->initial_r2t_en) {
-                       ctask->unsol_count = min(session->first_burst,
-                               ctask->total_length) - ctask->imm_count;
+                       ctask->unsol_count = min((session->first_burst),
+                               (sc->request_bufflen)) - ctask->imm_count;
                        ctask->unsol_offset = ctask->imm_count;
                }
 
@@ -201,11 +192,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
                        /* No unsolicit Data-Out's */
                        ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
        } else {
-               /*
-                * this has been moved to the iscsi_tcp mode upstream
-                * since it is only used there
-                */
-               ctask->datasn = 0;
                hdr->flags |= ISCSI_FLAG_CMD_FINAL;
                zero_data(hdr->dlength);
 
@@ -221,7 +207,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
                 conn->id, sc, sc->cmnd[0], ctask->itt, sc->request_bufflen,
                 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
 }
-EXPORT_SYMBOL_GPL(iscsi_prep_scsi_cmd_pdu);
 
 /**
  * iscsi_complete_command - return command back to scsi-ml
@@ -256,86 +241,6 @@ static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask)
                iscsi_complete_command(ctask);
 }
 
-/**
- * iscsi_free_mgmt_task - return mgmt task back to pool
- * @conn: iscsi connection
- * @mtask: mtask
- *
- * Must be called with session lock.
- */
-void iscsi_free_mgmt_task(struct iscsi_conn *conn,
-                         struct iscsi_mgmt_task *mtask)
-{
-       list_del_init(&mtask->running);
-       if (conn->login_mtask == mtask)
-               return;
-
-       if (conn->ping_mtask == mtask)
-               conn->ping_mtask = NULL;
-       __kfifo_put(conn->session->mgmtpool.queue,
-                   (void*)&mtask, sizeof(void*));
-}
-EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task);
-
-static struct iscsi_mgmt_task *
-__iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-                     char *data, uint32_t data_size)
-{
-       struct iscsi_session *session = conn->session;
-       struct iscsi_mgmt_task *mtask;
-
-       if (session->state == ISCSI_STATE_TERMINATE)
-               return NULL;
-
-       if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
-           hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
-               /*
-                * Login and Text are sent serially, in
-                * request-followed-by-response sequence.
-                * Same mtask can be used. Same ITT must be used.
-                * Note that login_mtask is preallocated at conn_create().
-                */
-               mtask = conn->login_mtask;
-       else {
-               BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
-               BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
-
-               if (!__kfifo_get(session->mgmtpool.queue,
-                                (void*)&mtask, sizeof(void*)))
-                       return NULL;
-       }
-
-       if (data_size) {
-               memcpy(mtask->data, data, data_size);
-               mtask->data_count = data_size;
-       } else
-               mtask->data_count = 0;
-
-       INIT_LIST_HEAD(&mtask->running);
-       memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr));
-       __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
-       return mtask;
-}
-
-int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
-                       char *data, uint32_t data_size)
-{
-       struct iscsi_conn *conn = cls_conn->dd_data;
-       struct iscsi_session *session = conn->session;
-       int err = 0;
-
-       spin_lock_bh(&session->lock);
-       if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size)) {
-               err = -EPERM;
-               spin_unlock_bh(&session->lock);
-               return err;
-       }
-       spin_unlock_bh(&session->lock);
-       scsi_queue_work(session->host, &conn->xmitwork);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
-
 /**
  * iscsi_cmd_rsp - SCSI Command Response processing
  * @conn: iscsi connection
@@ -347,7 +252,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
  * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and
  * then completes the command and task.
  **/
-static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                               struct iscsi_cmd_task *ctask, char *data,
                               int datalen)
 {
@@ -386,6 +291,9 @@ invalid_datalen:
                           min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
        }
 
+       if (sc->sc_data_direction == DMA_TO_DEVICE)
+               goto out;
+
        if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
                int res_count = be32_to_cpu(rhdr->residual_count);
 
@@ -404,7 +312,6 @@ out:
        conn->scsirsp_pdus_cnt++;
 
        __iscsi_put_ctask(ctask);
-       return 0;
 }
 
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
@@ -414,51 +321,18 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
        conn->tmfrsp_pdus_cnt++;
 
-       if (conn->tmabort_state != TMABORT_INITIAL)
+       if (conn->tmf_state != TMF_QUEUED)
                return;
 
        if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-               conn->tmabort_state = TMABORT_SUCCESS;
+               conn->tmf_state = TMF_SUCCESS;
        else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-               conn->tmabort_state = TMABORT_NOT_FOUND;
+               conn->tmf_state = TMF_NOT_FOUND;
        else
-               conn->tmabort_state = TMABORT_FAILED;
+               conn->tmf_state = TMF_FAILED;
        wake_up(&conn->ehwait);
 }
 
-static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
-{
-       struct iscsi_nopout hdr;
-       struct iscsi_mgmt_task *mtask;
-
-       if (!rhdr && conn->ping_mtask)
-               return;
-
-       memset(&hdr, 0, sizeof(struct iscsi_nopout));
-       hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
-       hdr.flags = ISCSI_FLAG_CMD_FINAL;
-
-       if (rhdr) {
-               memcpy(hdr.lun, rhdr->lun, 8);
-               hdr.ttt = rhdr->ttt;
-               hdr.itt = RESERVED_ITT;
-       } else
-               hdr.ttt = RESERVED_ITT;
-
-       mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-       if (!mtask) {
-               printk(KERN_ERR "Could not send nopout\n");
-               return;
-       }
-
-       /* only track our nops */
-       if (!rhdr) {
-               conn->ping_mtask = mtask;
-               conn->last_ping = jiffies;
-       }
-       scsi_queue_work(conn->session->host, &conn->xmitwork);
-}
-
 static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                               char *data, int datalen)
 {
@@ -503,7 +377,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
        struct iscsi_mgmt_task *mtask;
        uint32_t itt;
 
-       conn->last_recv = jiffies;
        if (hdr->itt != RESERVED_ITT)
                itt = get_itt(hdr->itt);
        else
@@ -559,7 +432,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                         */
                        if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
                                rc = ISCSI_ERR_CONN_FAILED;
-                       iscsi_free_mgmt_task(conn, mtask);
+                       list_del_init(&mtask->running);
+                       if (conn->login_mtask != mtask)
+                               __kfifo_put(session->mgmtpool.queue,
+                                           (void*)&mtask, sizeof(void*));
                        break;
                case ISCSI_OP_SCSI_TMFUNC_RSP:
                        if (datalen) {
@@ -576,16 +452,11 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                        }
                        conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
 
-                       if (conn->ping_mtask != mtask) {
-                               /*
-                                * If this is not in response to one of our
-                                * nops then it must be from userspace.
-                                */
-                               if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
-                                                  datalen))
-                                       rc = ISCSI_ERR_CONN_FAILED;
-                       }
-                       iscsi_free_mgmt_task(conn, mtask);
+                       if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
+                               rc = ISCSI_ERR_CONN_FAILED;
+                       list_del_init(&mtask->running);
+                       __kfifo_put(session->mgmtpool.queue,
+                                   (void*)&mtask, sizeof(void*));
                        break;
                default:
                        rc = ISCSI_ERR_BAD_OPCODE;
@@ -604,7 +475,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                        if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG))
                                break;
 
-                       iscsi_send_nopout(conn, (struct iscsi_nopin*)hdr);
+                       if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0))
+                               rc = ISCSI_ERR_CONN_FAILED;
                        break;
                case ISCSI_OP_REJECT:
                        rc = iscsi_handle_reject(conn, hdr, data, datalen);
@@ -731,11 +603,11 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn,
        }
 
        if (session->tt->init_mgmt_task)
-               session->tt->init_mgmt_task(conn, mtask, mtask->data,
-                                           mtask->data_count);
+               session->tt->init_mgmt_task(conn, mtask);
 
        debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
-                  hdr->opcode, hdr->itt, mtask->data_count);
+                  hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
+                  mtask->data_count);
 }
 
 static int iscsi_xmit_mtask(struct iscsi_conn *conn)
@@ -784,27 +656,35 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
 static int iscsi_xmit_ctask(struct iscsi_conn *conn)
 {
        struct iscsi_cmd_task *ctask = conn->ctask;
-       int rc = 0;
-
-       /*
-        * serialize with TMF AbortTask
-        */
-       if (ctask->state == ISCSI_TASK_ABORTING)
-               goto done;
+       int rc;
 
        __iscsi_get_ctask(ctask);
        spin_unlock_bh(&conn->session->lock);
        rc = conn->session->tt->xmit_cmd_task(conn, ctask);
        spin_lock_bh(&conn->session->lock);
        __iscsi_put_ctask(ctask);
-
-done:
        if (!rc)
                /* done with this ctask */
                conn->ctask = NULL;
        return rc;
 }
 
+/**
+ * iscsi_requeue_ctask - requeue ctask to run from session workqueue
+ * @ctask: ctask to requeue
+ *
+ * LLDs that need to run a ctask from the session workqueue should call
+ * this. The session lock must be held.
+ */
+void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask)
+{
+       struct iscsi_conn *conn = ctask->conn;
+
+       list_move_tail(&ctask->running, &conn->requeue);
+       scsi_queue_work(conn->session->host, &conn->xmitwork);
+}
+EXPORT_SYMBOL_GPL(iscsi_requeue_ctask);
+
 /**
  * iscsi_data_xmit - xmit any command into the scheduled connection
  * @conn: iscsi connection
@@ -843,36 +723,27 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
         * overflow us with nop-ins
         */
 check_mgmt:
-       while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask,
-                          sizeof(void*))) {
+       while (!list_empty(&conn->mgmtqueue)) {
+               conn->mtask = list_entry(conn->mgmtqueue.next,
+                                        struct iscsi_mgmt_task, running);
                iscsi_prep_mtask(conn, conn->mtask);
-               list_add_tail(&conn->mtask->running, &conn->mgmt_run_list);
+               list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list);
                rc = iscsi_xmit_mtask(conn);
                if (rc)
                        goto again;
        }
 
-       /* process command queue */
+       /* process pending command queue */
        while (!list_empty(&conn->xmitqueue)) {
-               /*
-                * iscsi tcp may readd the task to the xmitqueue to send
-                * write data
-                */
+               if (conn->tmf_state == TMF_QUEUED)
+                       break;
+
                conn->ctask = list_entry(conn->xmitqueue.next,
                                         struct iscsi_cmd_task, running);
-               switch (conn->ctask->state) {
-               case ISCSI_TASK_ABORTING:
-                       break;
-               case ISCSI_TASK_PENDING:
-                       iscsi_prep_scsi_cmd_pdu(conn->ctask);
-                       conn->session->tt->init_cmd_task(conn->ctask);
-                       /* fall through */
-               default:
-                       conn->ctask->state = ISCSI_TASK_RUNNING;
-                       break;
-               }
+               iscsi_prep_scsi_cmd_pdu(conn->ctask);
+               conn->session->tt->init_cmd_task(conn->ctask);
+               conn->ctask->state = ISCSI_TASK_RUNNING;
                list_move_tail(conn->xmitqueue.next, &conn->run_list);
-
                rc = iscsi_xmit_ctask(conn);
                if (rc)
                        goto again;
@@ -881,7 +752,22 @@ check_mgmt:
                 * we need to check the mgmt queue for nops that need to
                 * be sent to aviod starvation
                 */
-               if (__kfifo_len(conn->mgmtqueue))
+               if (!list_empty(&conn->mgmtqueue))
+                       goto check_mgmt;
+       }
+
+       while (!list_empty(&conn->requeue)) {
+               if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL)
+                       break;
+
+               conn->ctask = list_entry(conn->requeue.next,
+                                        struct iscsi_cmd_task, running);
+               conn->ctask->state = ISCSI_TASK_RUNNING;
+               list_move_tail(conn->requeue.next, &conn->run_list);
+               rc = iscsi_xmit_ctask(conn);
+               if (rc)
+                       goto again;
+               if (!list_empty(&conn->mgmtqueue))
                        goto check_mgmt;
        }
        spin_unlock_bh(&conn->session->lock);
@@ -894,9 +780,10 @@ again:
        return rc;
 }
 
-static void iscsi_xmitworker(void *data)
+static void iscsi_xmitworker(struct work_struct *work)
 {
-       struct iscsi_conn *conn = data;
+       struct iscsi_conn *conn =
+               container_of(work, struct iscsi_conn, xmitwork);
        int rc;
        /*
         * serialize Xmit worker on a per-connection basis.
@@ -984,10 +871,8 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 
        atomic_set(&ctask->refcount, 1);
        ctask->state = ISCSI_TASK_PENDING;
-       ctask->mtask = NULL;
        ctask->conn = conn;
        ctask->sc = sc;
-       ctask->total_length = sc->request_bufflen;
        INIT_LIST_HEAD(&ctask->running);
 
        list_add_tail(&ctask->running, &conn->xmitqueue);
@@ -1021,16 +906,71 @@ int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
 }
 EXPORT_SYMBOL_GPL(iscsi_change_queue_depth);
 
+static struct iscsi_mgmt_task *
+__iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+                     char *data, uint32_t data_size)
+{
+       struct iscsi_session *session = conn->session;
+       struct iscsi_mgmt_task *mtask;
+
+       if (session->state == ISCSI_STATE_TERMINATE)
+               return NULL;
+
+       if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
+           hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+               /*
+                * Login and Text are sent serially, in
+                * request-followed-by-response sequence.
+                * Same mtask can be used. Same ITT must be used.
+                * Note that login_mtask is preallocated at conn_create().
+                */
+               mtask = conn->login_mtask;
+       else {
+               BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
+               BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
+
+               if (!__kfifo_get(session->mgmtpool.queue,
+                                (void*)&mtask, sizeof(void*)))
+                       return NULL;
+       }
+
+       if (data_size) {
+               memcpy(mtask->data, data, data_size);
+               mtask->data_count = data_size;
+       } else
+               mtask->data_count = 0;
+
+       memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr));
+       INIT_LIST_HEAD(&mtask->running);
+       list_add_tail(&mtask->running, &conn->mgmtqueue);
+       return mtask;
+}
+
+int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
+                       char *data, uint32_t data_size)
+{
+       struct iscsi_conn *conn = cls_conn->dd_data;
+       struct iscsi_session *session = conn->session;
+       int err = 0;
+
+       spin_lock_bh(&session->lock);
+       if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
+               err = -EPERM;
+       spin_unlock_bh(&session->lock);
+       scsi_queue_work(session->host, &conn->xmitwork);
+       return err;
+}
+EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
+
 void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
 {
        struct iscsi_session *session = class_to_transport_session(cls_session);
-       struct iscsi_conn *conn = session->leadconn;
 
        spin_lock_bh(&session->lock);
        if (session->state != ISCSI_STATE_LOGGED_IN) {
                session->state = ISCSI_STATE_RECOVERY_FAILED;
-               if (conn)
-                       wake_up(&conn->ehwait);
+               if (session->leadconn)
+                       wake_up(&session->leadconn->ehwait);
        }
        spin_unlock_bh(&session->lock);
 }
@@ -1041,7 +981,6 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
        struct Scsi_Host *host = sc->device->host;
        struct iscsi_session *session = iscsi_hostdata(host->hostdata);
        struct iscsi_conn *conn = session->leadconn;
-       int fail_session = 0;
 
        spin_lock_bh(&session->lock);
        if (session->state == ISCSI_STATE_TERMINATE) {
@@ -1052,19 +991,13 @@ failed:
                return FAILED;
        }
 
-       if (sc->SCp.phase == session->age) {
-               debug_scsi("failing connection CID %d due to SCSI host reset\n",
-                          conn->id);
-               fail_session = 1;
-       }
        spin_unlock_bh(&session->lock);
 
        /*
         * we drop the lock here but the leadconn cannot be destoyed while
         * we are in the scsi eh
         */
-       if (fail_session)
-               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+       iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
 
        debug_scsi("iscsi_eh_host_reset wait for relogin\n");
        wait_event_interruptible(conn->ehwait,
@@ -1085,62 +1018,43 @@ failed:
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_host_reset);
 
-static void iscsi_tmabort_timedout(unsigned long data)
+static void iscsi_tmf_timedout(unsigned long data)
 {
-       struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data;
-       struct iscsi_conn *conn = ctask->conn;
+       struct iscsi_conn *conn = (struct iscsi_conn *)data;
        struct iscsi_session *session = conn->session;
 
        spin_lock(&session->lock);
-       if (conn->tmabort_state == TMABORT_INITIAL) {
-               conn->tmabort_state = TMABORT_TIMEDOUT;
-               debug_scsi("tmabort timedout [sc %p itt 0x%x]\n",
-                       ctask->sc, ctask->itt);
+       if (conn->tmf_state == TMF_QUEUED) {
+               conn->tmf_state = TMF_TIMEDOUT;
+               debug_scsi("tmf timedout\n");
                /* unblock eh_abort() */
                wake_up(&conn->ehwait);
        }
        spin_unlock(&session->lock);
 }
 
-static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
-                                struct iscsi_cmd_task *ctask)
+static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
+                                  struct iscsi_tm *hdr, int age)
 {
-       struct iscsi_conn *conn = ctask->conn;
        struct iscsi_session *session = conn->session;
-       struct iscsi_tm *hdr = &conn->tmhdr;
-
-       /*
-        * ctask timed out but session is OK requests must be serialized.
-        */
-       memset(hdr, 0, sizeof(struct iscsi_tm));
-       hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
-       hdr->flags = ISCSI_TM_FUNC_ABORT_TASK;
-       hdr->flags |= ISCSI_FLAG_CMD_FINAL;
-       memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
-       hdr->rtt = ctask->hdr->itt;
-       hdr->refcmdsn = ctask->hdr->cmdsn;
+       struct iscsi_mgmt_task *mtask;
 
-       ctask->mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
-                                           NULL, 0);
-       if (!ctask->mtask) {
+       mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
+                                     NULL, 0);
+       if (!mtask) {
                spin_unlock_bh(&session->lock);
                iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-               spin_lock_bh(&session->lock)
-               debug_scsi("abort sent failure [itt 0x%x]\n", ctask->itt);
+               spin_lock_bh(&session->lock);
+               debug_scsi("tmf exec failure\n");
                return -EPERM;
        }
-       ctask->state = ISCSI_TASK_ABORTING;
-
-       debug_scsi("abort sent [itt 0x%x]\n", ctask->itt);
+       conn->tmfcmd_pdus_cnt++;
+       conn->tmf_timer.expires = 30 * HZ + jiffies;
+       conn->tmf_timer.function = iscsi_tmf_timedout;
+       conn->tmf_timer.data = (unsigned long)conn;
+       add_timer(&conn->tmf_timer);
+       debug_scsi("tmf set timeout\n");
 
-       if (conn->tmabort_state == TMABORT_INITIAL) {
-               conn->tmfcmd_pdus_cnt++;
-               conn->tmabort_timer.expires = 20*HZ + jiffies;
-               conn->tmabort_timer.function = iscsi_tmabort_timedout;
-               conn->tmabort_timer.data = (unsigned long)ctask;
-               add_timer(&conn->tmabort_timer);
-               debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt);
-       }
        spin_unlock_bh(&session->lock);
        mutex_unlock(&session->eh_mutex);
        scsi_queue_work(session->host, &conn->xmitwork);
@@ -1148,61 +1062,30 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
        /*
         * block eh thread until:
         *
-        * 1) abort response
-        * 2) abort timeout
+        * 1) tmf response
+        * 2) tmf timeout
         * 3) session is terminated or restarted or userspace has
         * given up on recovery
         */
-       wait_event_interruptible(conn->ehwait,
-                                sc->SCp.phase != session->age ||
+       wait_event_interruptible(conn->ehwait, age != session->age ||
                                 session->state != ISCSI_STATE_LOGGED_IN ||
-                                conn->tmabort_state != TMABORT_INITIAL);
+                                conn->tmf_state != TMF_QUEUED);
        if (signal_pending(current))
                flush_signals(current);
-       del_timer_sync(&conn->tmabort_timer);
+       del_timer_sync(&conn->tmf_timer);
+
        mutex_lock(&session->eh_mutex);
        spin_lock_bh(&session->lock);
-       return 0;
-}
-
-/*
- * session lock must be held
- */
-static struct iscsi_mgmt_task *
-iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt)
-{
-       int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*);
-       struct iscsi_mgmt_task *task;
-
-       debug_scsi("searching %d tasks\n", nr_tasks);
-
-       for (i = 0; i < nr_tasks; i++) {
-               __kfifo_get(fifo, (void*)&task, sizeof(void*));
-               debug_scsi("check task %u\n", task->itt);
-
-               if (task->itt == itt) {
-                       debug_scsi("matched task\n");
-                       return task;
-               }
+       /* if the session drops it will clean up the mtask */
+       if (age != session->age ||
+           session->state != ISCSI_STATE_LOGGED_IN)
+               return -ENOTCONN;
 
-               __kfifo_put(fifo, (void*)&task, sizeof(void*));
+       if (!list_empty(&mtask->running)) {
+               list_del_init(&mtask->running);
+               __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+                           sizeof(void*));
        }
-       return NULL;
-}
-
-static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask)
-{
-       struct iscsi_conn *conn = ctask->conn;
-       struct iscsi_session *session = conn->session;
-
-       if (!ctask->mtask)
-               return -EINVAL;
-
-       if (!iscsi_remove_mgmt_task(conn->mgmtqueue, ctask->mtask->itt))
-               list_del(&ctask->mtask->running);
-       __kfifo_put(session->mgmtpool.queue, (void*)&ctask->mtask,
-                   sizeof(void*));
-       ctask->mtask = NULL;
        return 0;
 }
 
@@ -1226,7 +1109,6 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
                conn->session->queued_cmdsn--;
        else
                conn->session->tt->cleanup_cmd_task(conn, ctask);
-       iscsi_ctask_mtask_cleanup(ctask);
 
        sc->result = err;
        sc->resid = sc->request_bufflen;
@@ -1236,6 +1118,44 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
        __iscsi_put_ctask(ctask);
 }
 
+/*
+ * Fail commands. session lock held and recv side suspended and xmit
+ * thread flushed
+ */
+static void fail_all_commands(struct iscsi_conn *conn, unsigned lun)
+{
+       struct iscsi_cmd_task *ctask, *tmp;
+
+       if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1))
+               conn->ctask = NULL;
+
+       /* flush pending */
+       list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
+               if (lun == ctask->sc->device->lun || lun == -1) {
+                       debug_scsi("failing pending sc %p itt 0x%x\n",
+                                  ctask->sc, ctask->itt);
+                       fail_command(conn, ctask, DID_BUS_BUSY << 16);
+               }
+       }
+
+       list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) {
+               if (lun == ctask->sc->device->lun || lun == -1) {
+                       debug_scsi("failing requeued sc %p itt 0x%x\n",
+                                  ctask->sc, ctask->itt);
+                       fail_command(conn, ctask, DID_BUS_BUSY << 16);
+               }
+       }
+
+       /* fail all other running */
+       list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
+               if (lun == ctask->sc->device->lun || lun == -1) {
+                       debug_scsi("failing in progress sc %p itt 0x%x\n",
+                                  ctask->sc, ctask->itt);
+                       fail_command(conn, ctask, DID_BUS_BUSY << 16);
+               }
+       }
+}
+
 static void iscsi_suspend_tx(struct iscsi_conn *conn)
 {
        set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
@@ -1248,110 +1168,26 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
        scsi_queue_work(conn->session->host, &conn->xmitwork);
 }
 
-static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
-{
-       struct iscsi_cls_session *cls_session;
-       struct iscsi_session *session;
-       struct iscsi_conn *conn;
-       enum scsi_eh_timer_return rc = EH_NOT_HANDLED;
-
-       cls_session = starget_to_session(scsi_target(scmd->device));
-       session = class_to_transport_session(cls_session);
-
-       debug_scsi("scsi cmd %p timedout\n", scmd);
-
-       spin_lock(&session->lock);
-       if (session->state != ISCSI_STATE_LOGGED_IN) {
-               /*
-                * We are probably in the middle of iscsi recovery so let
-                * that complete and handle the error.
-                */
-               rc = EH_RESET_TIMER;
-               goto done;
-       }
-
-       conn = session->leadconn;
-       if (!conn) {
-               /* In the middle of shuting down */
-               rc = EH_RESET_TIMER;
-               goto done;
-       }
-
-       if (!conn->recv_timeout && !conn->ping_timeout)
-               goto done;
-       /*
-        * if the ping timedout then we are in the middle of cleaning up
-        * and can let the iscsi eh handle it
-        */
-       if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
-                          (conn->ping_timeout * HZ), jiffies))
-               rc = EH_RESET_TIMER;
-       /*
-        * if we are about to check the transport then give the command
-        * more time
-        */
-       else if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ),
-                               jiffies))
-               rc = EH_RESET_TIMER;
-       /* if in the middle of checking the transport then give us more time */
-       else if (conn->ping_mtask)
-               rc = EH_RESET_TIMER;
-done:
-       spin_unlock(&session->lock);
-       debug_scsi("return %s\n", rc == EH_RESET_TIMER ? "timer reset" : "nh");
-       return rc;
-}
-
-static void iscsi_check_transport_timeouts(unsigned long data)
+static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask,
+                                     struct iscsi_tm *hdr)
 {
-       struct iscsi_conn *conn = (struct iscsi_conn *)data;    
-       struct iscsi_session *session = conn->session;
-       unsigned long timeout, next_timeout = 0, last_recv;
-
-       spin_lock(&session->lock);
-       if (session->state != ISCSI_STATE_LOGGED_IN)
-               goto done;
-
-       timeout = conn->recv_timeout;
-       if (!timeout)
-               goto done;
-
-       timeout *= HZ;
-       last_recv = conn->last_recv;
-       if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
-                          jiffies)) {
-               printk(KERN_ERR "ping timeout of %d secs expired, "
-                      "last rx %lu, last ping %lu, now %lu\n",
-                      conn->ping_timeout, last_recv,
-                      conn->last_ping, jiffies);
-               spin_unlock(&session->lock);
-               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-               return;
-       }
-
-       if (time_before_eq(last_recv + timeout, jiffies)) {
-               if (time_before_eq(conn->last_ping, last_recv)) {
-                       /* send a ping to try to provoke some traffic */
-                       debug_scsi("Sending nopout as ping on conn %p\n", conn);
-                       iscsi_send_nopout(conn, NULL);
-               }
-               next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
-       } else
-               next_timeout = last_recv + timeout;
-
-       debug_scsi("Setting next tmo %lu\n", next_timeout);
-       mod_timer(&conn->transport_timer, next_timeout);
-done:
-       spin_unlock(&session->lock);
+       memset(hdr, 0, sizeof(*hdr));
+       hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+       hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK;
+       hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+       memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
+       hdr->rtt = ctask->hdr->itt;
+       hdr->refcmdsn = ctask->hdr->cmdsn;
 }
 
 int iscsi_eh_abort(struct scsi_cmnd *sc)
 {
        struct Scsi_Host *host = sc->device->host;
        struct iscsi_session *session = iscsi_hostdata(host->hostdata);
-       struct iscsi_cmd_task *ctask;
        struct iscsi_conn *conn;
-       int rc;
+       struct iscsi_cmd_task *ctask;
+       struct iscsi_tm *hdr;
+       int rc, age;
 
        mutex_lock(&session->eh_mutex);
        spin_lock_bh(&session->lock);
@@ -1366,19 +1202,23 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                return SUCCESS;
        }
 
-       ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
-       conn = ctask->conn;
-
-       conn->eh_abort_cnt++;
-       debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
-
        /*
         * If we are not logged in or we have started a new session
         * then let the host reset code handle this
         */
-       if (session->state != ISCSI_STATE_LOGGED_IN ||
-           sc->SCp.phase != session->age)
-               goto failed;
+       if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN ||
+           sc->SCp.phase != session->age) {
+               spin_unlock_bh(&session->lock);
+               mutex_unlock(&session->eh_mutex);
+               return FAILED;
+       }
+
+       conn = session->leadconn;
+       conn->eh_abort_cnt++;
+       age = session->age;
+
+       ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
+       debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
 
        /* ctask completed before time out */
        if (!ctask->sc) {
@@ -1386,27 +1226,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                goto success;
        }
 
-       /* what should we do here ? */
-       if (conn->ctask == ctask) {
-               printk(KERN_INFO "iscsi: sc %p itt 0x%x partially sent. "
-                      "Failing abort\n", sc, ctask->itt);
-               goto failed;
-       }
-
        if (ctask->state == ISCSI_TASK_PENDING) {
                fail_command(conn, ctask, DID_ABORT << 16);
                goto success;
        }
 
-       conn->tmabort_state = TMABORT_INITIAL;
-       rc = iscsi_exec_abort_task(sc, ctask);
-       if (rc || sc->SCp.phase != session->age ||
-           session->state != ISCSI_STATE_LOGGED_IN)
+       /* only have one tmf outstanding at a time */
+       if (conn->tmf_state != TMF_INITIAL)
                goto failed;
-       iscsi_ctask_mtask_cleanup(ctask);
+       conn->tmf_state = TMF_QUEUED;
 
-       switch (conn->tmabort_state) {
-       case TMABORT_SUCCESS:
+       hdr = &conn->tmhdr;
+       iscsi_prep_abort_task_pdu(ctask, hdr);
+
+       if (iscsi_exec_task_mgmt_fn(conn, hdr, age)) {
+               rc = FAILED;
+               goto failed;
+       }
+
+       switch (conn->tmf_state) {
+       case TMF_SUCCESS:
                spin_unlock_bh(&session->lock);
                iscsi_suspend_tx(conn);
                /*
@@ -1415,22 +1254,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                write_lock_bh(conn->recv_lock);
                spin_lock(&session->lock);
                fail_command(conn, ctask, DID_ABORT << 16);
+               conn->tmf_state = TMF_INITIAL;
                spin_unlock(&session->lock);
                write_unlock_bh(conn->recv_lock);
                iscsi_start_tx(conn);
                goto success_unlocked;
-       case TMABORT_NOT_FOUND:
-               if (!ctask->sc) {
+       case TMF_TIMEDOUT:
+               spin_unlock_bh(&session->lock);
+               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+               goto failed_unlocked;
+       case TMF_NOT_FOUND:
+               if (!sc->SCp.ptr) {
+                       conn->tmf_state = TMF_INITIAL;
                        /* ctask completed before tmf abort response */
                        debug_scsi("sc completed while abort in progress\n");
                        goto success;
                }
                /* fall through */
        default:
-               /* timedout or failed */
-               spin_unlock_bh(&session->lock);
-               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-               goto failed_unlocked;
+               conn->tmf_state = TMF_INITIAL;
+               goto failed;
        }
 
 success:
@@ -1443,12 +1286,93 @@ success_unlocked:
 failed:
        spin_unlock_bh(&session->lock);
 failed_unlocked:
-       debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+       debug_scsi("abort failed [sc %p itt 0x%x]\n", sc,
+                   ctask ? ctask->itt : 0);
        mutex_unlock(&session->eh_mutex);
        return FAILED;
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_abort);
 
+static void iscsi_prep_lun_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
+{
+       memset(hdr, 0, sizeof(*hdr));
+       hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+       hdr->flags = ISCSI_TM_FUNC_LOGICAL_UNIT_RESET & ISCSI_FLAG_TM_FUNC_MASK;
+       hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+       int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
+       hdr->rtt = ISCSI_RESERVED_TAG;
+}
+
+int iscsi_eh_device_reset(struct scsi_cmnd *sc)
+{
+       struct Scsi_Host *host = sc->device->host;
+       struct iscsi_session *session = iscsi_hostdata(host->hostdata);
+       struct iscsi_conn *conn;
+       struct iscsi_tm *hdr;
+       int rc = FAILED;
+
+       debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
+
+       mutex_lock(&session->eh_mutex);
+       spin_lock_bh(&session->lock);
+       /*
+        * Just check if we are not logged in. We cannot check for
+        * the phase because the reset could come from a ioctl.
+        */
+       if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+               goto unlock;
+       conn = session->leadconn;
+
+       /* only have one tmf outstanding at a time */
+       if (conn->tmf_state != TMF_INITIAL)
+               goto unlock;
+       conn->tmf_state = TMF_QUEUED;
+
+       hdr = &conn->tmhdr;
+       iscsi_prep_lun_reset_pdu(sc, hdr);
+
+       if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age)) {
+               rc = FAILED;
+               goto unlock;
+       }
+
+       switch (conn->tmf_state) {
+       case TMF_SUCCESS:
+               break;
+       case TMF_TIMEDOUT:
+               spin_unlock_bh(&session->lock);
+               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+               goto done;
+       default:
+               conn->tmf_state = TMF_INITIAL;
+               goto unlock;
+       }
+
+       rc = SUCCESS;
+       spin_unlock_bh(&session->lock);
+
+       iscsi_suspend_tx(conn);
+       /* need to grab the recv lock then session lock */
+       write_lock_bh(conn->recv_lock);
+       spin_lock(&session->lock);
+       fail_all_commands(conn, sc->device->lun);
+       conn->tmf_state = TMF_INITIAL;
+       spin_unlock(&session->lock);
+       write_unlock_bh(conn->recv_lock);
+
+       iscsi_start_tx(conn);
+       goto done;
+
+unlock:
+       spin_unlock_bh(&session->lock);
+done:
+       debug_scsi("iscsi_eh_device_reset %s\n",
+                 rc == SUCCESS ? "SUCCESS" : "FAILED");
+       mutex_unlock(&session->eh_mutex);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_device_reset);
+
 int
 iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
 {
@@ -1520,12 +1444,26 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free);
 
 #define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
 
-static struct iscsi_cls_session *
-__iscsi_session_setup(struct iscsi_transport *iscsit,
-                     struct scsi_transport_template *scsit,
-                     uint16_t cmds_max, uint16_t qdepth,
-                     int cmd_task_size, int mgmt_task_size,
-                     uint32_t initial_cmdsn, uint32_t *hostno)
+/**
+ * iscsi_session_setup - create iscsi cls session and host and session
+ * @scsit: scsi transport template
+ * @iscsit: iscsi transport template
+ * @cmds_max: scsi host can queue
+ * @qdepth: scsi host cmds per lun
+ * @cmd_task_size: LLD ctask private data size
+ * @mgmt_task_size: LLD mtask private data size
+ * @initial_cmdsn: initial CmdSN
+ * @hostno: host no allocated
+ *
+ * This can be used by software iscsi_transports that allocate
+ * a session per scsi host.
+ **/
+struct iscsi_cls_session *
+iscsi_session_setup(struct iscsi_transport *iscsit,
+                   struct scsi_transport_template *scsit,
+                   uint16_t cmds_max, uint16_t qdepth,
+                   int cmd_task_size, int mgmt_task_size,
+                   uint32_t initial_cmdsn, uint32_t *hostno)
 {
        struct Scsi_Host *shost;
        struct iscsi_session *session;
@@ -1535,9 +1473,9 @@ __iscsi_session_setup(struct iscsi_transport *iscsit,
        if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
                if (qdepth != 0)
                        printk(KERN_ERR "iscsi: invalid queue depth of %d. "
-                              "Queue depth must be between 1 and %d.\n",
-                              qdepth, ISCSI_MAX_CMD_PER_LUN);
-               qdepth = ISCSI_DEF_CMD_PER_LUN;
+                             "Queue depth must be between 1 and %d.\n",
+                             qdepth, ISCSI_MAX_CMD_PER_LUN);
+               qdepth = ISCSI_DEF_CMD_PER_LUN; 
        }
 
        if (cmds_max < 2 || (cmds_max & (cmds_max - 1)) ||
@@ -1546,8 +1484,8 @@ __iscsi_session_setup(struct iscsi_transport *iscsit,
                        printk(KERN_ERR "iscsi: invalid can_queue of %d. "
                               "can_queue must be a power of 2 and between "
                               "2 and %d - setting to %d.\n", cmds_max,
-                              ISCSI_MGMT_ITT_OFFSET, ISCSI_XMIT_CMDS_MAX);
-               cmds_max = ISCSI_XMIT_CMDS_MAX;
+                              ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX);
+               cmds_max = ISCSI_DEF_XMIT_CMDS_MAX;
        }
 
        shost = scsi_host_alloc(iscsit->host_template,
@@ -1564,7 +1502,6 @@ __iscsi_session_setup(struct iscsi_transport *iscsit,
        shost->max_cmd_len = iscsit->max_cmd_len;
        shost->transportt = scsit;
        shost->transportt->create_work_queue = 1;
-       shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
        *hostno = shost->host_no;
 
        session = iscsi_hostdata(shost->hostdata);
@@ -1640,63 +1577,8 @@ cmdpool_alloc_fail:
        scsi_host_put(shost);
        return NULL;
 }
-
-/**
- * iscsi_session_setup - create iscsi cls session and host and session
- * @scsit: scsi transport template
- * @iscsit: iscsi transport template
- * @cmd_task_size: LLD ctask private data size
- * @mgmt_task_size: LLD mtask private data size
- * @initial_cmdsn: initial CmdSN
- * @hostno: host no allocated
- *
- * This can be used by software iscsi_transports that allocate
- * a session per scsi host.
- **/
-struct iscsi_cls_session *
-iscsi_session_setup(struct iscsi_transport *iscsit,
-                   struct scsi_transport_template *scsit,
-                   int cmd_task_size, int mgmt_task_size,
-                   uint32_t initial_cmdsn, uint32_t *hostno)
-{
-       return __iscsi_session_setup(iscsit, scsit, ISCSI_XMIT_CMDS_MAX,
-                                    ISCSI_DEF_CMD_PER_LUN,
-                                    cmd_task_size, mgmt_task_size,
-                                    initial_cmdsn, hostno);
-}
 EXPORT_SYMBOL_GPL(iscsi_session_setup);
 
-/*
- * This is a KABI work around. This new version takes the defaults
- * session queue depth and default device queue depth.
- */
-/**
- * iscsi_session_setup - create iscsi cls session and host and session
- * @scsit: scsi transport template
- * @iscsit: iscsi transport template
- * @cmds_max: session queue depth
- * @qdepth: default device queue depth
- * @cmd_task_size: LLD ctask private data size
- * @mgmt_task_size: LLD mtask private data size
- * @initial_cmdsn: initial CmdSN
- * @hostno: host no allocated
- *
- * This can be used by software iscsi_transports that allocate
- * a session per scsi host.
- **/
-struct iscsi_cls_session *
-iscsi_session_setup2(struct iscsi_transport *iscsit,
-                    struct scsi_transport_template *scsit,
-                    uint16_t cmds_max, uint16_t qdepth,
-                    int cmd_task_size, int mgmt_task_size,
-                    uint32_t initial_cmdsn, uint32_t *hostno)
-{
-       return __iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
-                                    cmd_task_size, mgmt_task_size,
-                                    initial_cmdsn, hostno);
-}
-EXPORT_SYMBOL_GPL(iscsi_session_setup2);
-
 /**
  * iscsi_session_teardown - destroy session, host, and cls_session
  * shost: scsi host
@@ -1755,23 +1637,13 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
        conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
        conn->id = conn_idx;
        conn->exp_statsn = 0;
-       conn->tmabort_state = TMABORT_INITIAL;
-
-       init_timer(&conn->transport_timer);
-       conn->transport_timer.data = (unsigned long)conn;
-       conn->transport_timer.function = iscsi_check_transport_timeouts;
-
+       conn->tmf_state = TMF_INITIAL;
        INIT_LIST_HEAD(&conn->run_list);
        INIT_LIST_HEAD(&conn->mgmt_run_list);
+       INIT_LIST_HEAD(&conn->mgmtqueue);
        INIT_LIST_HEAD(&conn->xmitqueue);
-
-       /* initialize general immediate & non-immediate PDU commands queue */
-       conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
-                                       GFP_KERNEL, NULL);
-       if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
-               goto mgmtqueue_alloc_fail;
-
-       INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
+       INIT_LIST_HEAD(&conn->requeue);
+       INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
 
        /* allocate login_mtask used for the login/text sequences */
        spin_lock_bh(&session->lock);
@@ -1788,18 +1660,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
                goto login_mtask_data_alloc_fail;
        conn->login_mtask->data = conn->data = data;
 
-       init_timer(&conn->tmabort_timer);
-       /*
-        * RHEL5.0 iscsi_tcp tried to ise the xmitmutex to serialize
-        * access to the connection during sysfs access and teardown
-        * and setup, but the code did not actually protect the access
-        * due to a bug. So incase somone uses a new libiscsi with old
-        * iscsi_tcp, we init this and those weirdos would get the old
-        * broken behavior.
-        *
-        * TODO: Do I have to support such weirdness for KABI?
-        */
-       mutex_init(&conn->xmitmutex);
+       init_timer(&conn->tmf_timer);
        init_waitqueue_head(&conn->ehwait);
 
        return cls_conn;
@@ -1808,8 +1669,6 @@ login_mtask_data_alloc_fail:
        __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
                    sizeof(void*));
 login_mtask_alloc_fail:
-       kfifo_free(conn->mgmtqueue);
-mgmtqueue_alloc_fail:
        iscsi_destroy_conn(cls_conn);
        return NULL;
 }
@@ -1828,10 +1687,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
        struct iscsi_session *session = conn->session;
        unsigned long flags;
 
-       del_timer_sync(&conn->transport_timer);
-
        spin_lock_bh(&session->lock);
-       set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
        conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
        if (session->leadconn == conn) {
                /*
@@ -1864,7 +1720,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
        }
 
        /* flush queued up work because we free the connection below */
-       scsi_flush_work(session->host);
+       iscsi_suspend_tx(conn);
 
        spin_lock_bh(&session->lock);
        kfree(conn->data);
@@ -1875,8 +1731,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
                session->leadconn = NULL;
        spin_unlock_bh(&session->lock);
 
-       kfifo_free(conn->mgmtqueue);
-
        iscsi_destroy_conn(cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
@@ -1899,29 +1753,11 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
                return -EINVAL;
        }
 
-       if (conn->ping_timeout && !conn->recv_timeout) {
-               printk(KERN_ERR "iscsi: invalid recv timeout of zero. "
-                     "Using 5 seconds\n.");
-               conn->recv_timeout = 5;
-       }
-
-       if (conn->recv_timeout && !conn->ping_timeout) {
-               printk(KERN_ERR "iscsi: invalid ping timeout of zero. "
-                      "Using 5 seconds.\n");
-               conn->ping_timeout = 5;
-       }
-
        spin_lock_bh(&session->lock);
        conn->c_stage = ISCSI_CONN_STARTED;
        session->state = ISCSI_STATE_LOGGED_IN;
        session->queued_cmdsn = session->cmdsn;
 
-       conn->last_recv = jiffies;
-       conn->last_ping = jiffies;
-       if (conn->recv_timeout && conn->ping_timeout)
-               mod_timer(&conn->transport_timer,
-                         jiffies + (conn->recv_timeout * HZ));
-
        switch(conn->stop_stage) {
        case STOP_CONN_RECOVER:
                /*
@@ -1929,7 +1765,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
                 * commands after successful recovery
                 */
                conn->stop_stage = 0;
-               conn->tmabort_state = TMABORT_INITIAL;
+               conn->tmf_state = TMF_INITIAL;
                session->age++;
                spin_unlock_bh(&session->lock);
 
@@ -1954,40 +1790,27 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
        struct iscsi_mgmt_task *mtask, *tmp;
 
        /* handle pending */
-       while (__kfifo_get(conn->mgmtqueue, (void*)&mtask, sizeof(void*))) {
+       list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) {
                debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt);
-               iscsi_free_mgmt_task(conn, mtask);
+               list_del_init(&mtask->running);
+               if (mtask == conn->login_mtask)
+                       continue;
+               __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+                           sizeof(void*));
        }
 
        /* handle running */
        list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) {
                debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt);
-               iscsi_free_mgmt_task(conn, mtask);
-       }
+               list_del_init(&mtask->running);
 
-       conn->mtask = NULL;
-}
-
-/* Fail commands. Mutex and session lock held and recv side suspended */
-static void fail_all_commands(struct iscsi_conn *conn)
-{
-       struct iscsi_cmd_task *ctask, *tmp;
-
-       /* flush pending */
-       list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
-               debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc,
-                          ctask->itt);
-               fail_command(conn, ctask, DID_BUS_BUSY << 16);
-       }
-
-       /* fail all other running */
-       list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
-               debug_scsi("failing in progress sc %p itt 0x%x\n",
-                          ctask->sc, ctask->itt);
-               fail_command(conn, ctask, DID_BUS_BUSY << 16);
+               if (mtask == conn->login_mtask)
+                       continue;
+               __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+                          sizeof(void*));
        }
 
-       conn->ctask = NULL;
+       conn->mtask = NULL;
 }
 
 static void iscsi_start_session_recovery(struct iscsi_session *session,
@@ -1995,8 +1818,6 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
 {
        int old_stop_stage;
 
-       del_timer_sync(&conn->transport_timer);
-
        mutex_lock(&session->eh_mutex);
        spin_lock_bh(&session->lock);
        if (conn->stop_stage == STOP_CONN_TERM) {
@@ -2057,7 +1878,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
         * flush queues.
         */
        spin_lock_bh(&session->lock);
-       fail_all_commands(conn);
+       fail_all_commands(conn, -1);
        flush_control_queues(session, conn);
        spin_unlock_bh(&session->lock);
        mutex_unlock(&session->eh_mutex);
@@ -2108,11 +1929,8 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
        uint32_t value;
 
        switch(param) {
-       case ISCSI_PARAM_PING_TMO:
-               sscanf(buf, "%d", &conn->ping_timeout);
-               break;
-       case ISCSI_PARAM_RECV_TMO:
-               sscanf(buf, "%d", &conn->recv_timeout);
+       case ISCSI_PARAM_FAST_ABORT:
+               sscanf(buf, "%d", &session->fast_abort);
                break;
        case ISCSI_PARAM_MAX_RECV_DLENGTH:
                sscanf(buf, "%d", &conn->max_recv_dlength);
@@ -2228,6 +2046,9 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
        int len;
 
        switch(param) {
+       case ISCSI_PARAM_FAST_ABORT:
+               len = sprintf(buf, "%d\n", session->fast_abort);
+               break;
        case ISCSI_PARAM_INITIAL_R2T_EN:
                len = sprintf(buf, "%d\n", session->initial_r2t_en);
                break;
@@ -2285,12 +2106,6 @@ int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
        int len;
 
        switch(param) {
-       case ISCSI_PARAM_PING_TMO:
-               len = sprintf(buf, "%u\n", conn->ping_timeout);
-               break;
-       case ISCSI_PARAM_RECV_TMO:
-               len = sprintf(buf, "%u\n", conn->recv_timeout);
-               break;
        case ISCSI_PARAM_MAX_RECV_DLENGTH:
                len = sprintf(buf, "%u\n", conn->max_recv_dlength);
                break;
index 6c97a46ced8386a030469b63509e4f76c51f193f..96d44c3d13f94624352f00b026ca653599832e68 100644 (file)
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_iscsi.h>
-#include <scsi/iscsi_if.h>
+#include "scsi_transport_iscsi.h"
+#include "iscsi_if.h"
 
-#define ISCSI_SESSION_ATTRS 15
-#define ISCSI_CONN_ATTRS 13
+#define ISCSI_SESSION_ATTRS 16
+#define ISCSI_CONN_ATTRS 11
 #define ISCSI_HOST_ATTRS 4
-#define ISCSI_TRANSPORT_VERSION "2.0-724"
+#define ISCSI_TRANSPORT_VERSION "2.0-865"
 
 struct iscsi_internal {
        int daemon_pid;
@@ -234,9 +234,11 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
        return 0;
 }
 
-static void session_recovery_timedout(void *data)
+static void session_recovery_timedout(struct work_struct *work)
 {
-       struct iscsi_cls_session *session = data;
+       struct iscsi_cls_session *session =
+               container_of(work, struct iscsi_cls_session,
+                            recovery_work.work);
 
        dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
                  "out after %d secs\n", session->recovery_tmo);
@@ -276,7 +278,7 @@ iscsi_alloc_session(struct Scsi_Host *shost,
 
        session->transport = transport;
        session->recovery_tmo = 120;
-       INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
+       INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
        INIT_LIST_HEAD(&session->host_list);
        INIT_LIST_HEAD(&session->sess_list);
 
@@ -811,17 +813,11 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
        unsigned long flags;
        uint32_t hostno;
 
-       if ((!ev->u.c_session.cmds_max && !ev->u.c_session.queue_depth) ||
-            !transport->create_session2)
-               session = transport->create_session(transport, &priv->t,
-                                               ev->u.c_session.initial_cmdsn,
-                                               &hostno);
-       else
-               session = transport->create_session2(transport, &priv->t,
-                                               ev->u.c_session.cmds_max,
-                                               ev->u.c_session.queue_depth,
-                                               ev->u.c_session.initial_cmdsn,
-                                               &hostno);
+       session = transport->create_session(transport, &priv->t,
+                                           ev->u.c_session.cmds_max,
+                                           ev->u.c_session.queue_depth,
+                                           ev->u.c_session.initial_cmdsn,
+                                           &hostno);
        if (!session)
                return -ENOMEM;
 
@@ -951,20 +947,31 @@ static int
 iscsi_tgt_dscvr(struct iscsi_transport *transport,
                struct iscsi_uevent *ev)
 {
+       struct Scsi_Host *shost;
        struct sockaddr *dst_addr;
+       int err;
 
        if (!transport->tgt_dscvr)
                return -EINVAL;
 
+       shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
+       if (IS_ERR(shost)) {
+               printk(KERN_ERR "target discovery could not find host no %u\n",
+                      ev->u.tgt_dscvr.host_no);
+               return -ENODEV;
+       }
+
+
        dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
-       return transport->tgt_dscvr(ev->u.tgt_dscvr.type,
-                                   ev->u.tgt_dscvr.host_no,
-                                   ev->u.tgt_dscvr.enable, dst_addr);
+       err = transport->tgt_dscvr(shost, ev->u.tgt_dscvr.type,
+                                  ev->u.tgt_dscvr.enable, dst_addr);
+       scsi_host_put(shost);
+       return err;
 }
 
 static int
 iscsi_set_host_param(struct iscsi_transport *transport,
-                     struct iscsi_uevent *ev)
+                    struct iscsi_uevent *ev)
 {
        char *data = (char*)ev + sizeof(*ev);
        struct Scsi_Host *shost;
@@ -1081,7 +1088,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                err = iscsi_set_host_param(transport, ev);
                break;
        default:
-               err = -EINVAL;
+               err = -ENOSYS;
                break;
        }
 
@@ -1184,8 +1191,6 @@ iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT);
 iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
 iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
 iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
-iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
-iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
 
 #define iscsi_cdev_to_session(_cdev) \
        iscsi_dev_to_session(_cdev->dev)
@@ -1224,6 +1229,7 @@ iscsi_session_attr(username, ISCSI_PARAM_USERNAME, 1);
 iscsi_session_attr(username_in, ISCSI_PARAM_USERNAME_IN, 1);
 iscsi_session_attr(password, ISCSI_PARAM_PASSWORD, 1);
 iscsi_session_attr(password_in, ISCSI_PARAM_PASSWORD_IN, 1);
+iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 1);
 
 #define iscsi_priv_session_attr_show(field, format)                    \
 static ssize_t                                                         \
@@ -1267,6 +1273,7 @@ do {                                                                      \
        count++;                                                        \
 } while (0)
 
+
 #define SETUP_SESSION_RD_ATTR(field, param_flag)                       \
 do {                                                                   \
        if (tt->param_mask & param_flag) {                              \
@@ -1398,7 +1405,6 @@ iscsi_register_transport(struct iscsi_transport *tt)
        SETUP_HOST_RD_ATTR(ipaddress, ISCSI_HOST_IPADDRESS);
        SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS);
        SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME);
-
        BUG_ON(count > ISCSI_HOST_ATTRS);
        priv->host_attrs[count] = NULL;
        count = 0;
@@ -1420,8 +1426,6 @@ iscsi_register_transport(struct iscsi_transport *tt)
        SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
        SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
        SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
-       SETUP_CONN_RD_ATTR(ping_tmo, ISCSI_PING_TMO);
-       SETUP_CONN_RD_ATTR(recv_tmo, ISCSI_RECV_TMO);
 
        BUG_ON(count > ISCSI_CONN_ATTRS);
        priv->conn_attrs[count] = NULL;
@@ -1447,6 +1451,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
        SETUP_SESSION_RD_ATTR(password_in, ISCSI_USERNAME_IN);
        SETUP_SESSION_RD_ATTR(username, ISCSI_PASSWORD);
        SETUP_SESSION_RD_ATTR(username_in, ISCSI_PASSWORD_IN);
+       SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT);
        SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
 
        BUG_ON(count > ISCSI_SESSION_ATTRS);
@@ -1521,7 +1526,7 @@ static __init int iscsi_transport_init(void)
                goto unregister_conn_class;
 
        nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
-                       THIS_MODULE);
+                       NULL, THIS_MODULE);
        if (!nls) {
                err = -ENOBUFS;
                goto unregister_session_class;
index 4e7ae4c05b1b2b8db5abd31048a7877494c79603..803e8d9ff38c371a5b6e058e817ec0fea2523cba 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef ISCSI_IF_H
 #define ISCSI_IF_H
 
-#include <scsi/iscsi_proto.h>
+#include <iscsi_proto.h>
 
 #define UEVENT_BASE                    10
 #define KEVENT_BASE                    100
@@ -48,9 +48,7 @@ enum iscsi_uevent_e {
        ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT    = UEVENT_BASE + 14,
 
        ISCSI_UEVENT_TGT_DSCVR          = UEVENT_BASE + 15,
-#ifndef __GENKSYMS__
        ISCSI_UEVENT_SET_HOST_PARAM     = UEVENT_BASE + 16,
-#endif
 
        /* up events */
        ISCSI_KEVENT_RECV_PDU           = KEVENT_BASE + 1,
@@ -74,10 +72,8 @@ struct iscsi_uevent {
                /* messages u -> k */
                struct msg_create_session {
                        uint32_t        initial_cmdsn;
-#ifndef __GENKSYMS__
                        uint16_t        cmds_max;
                        uint16_t        queue_depth;
-#endif
                } c_session;
                struct msg_destroy_session {
                        uint32_t        sid;
@@ -143,13 +139,11 @@ struct iscsi_uevent {
                         */
                        uint32_t        enable;
                } tgt_dscvr;
-#ifndef __GENKSYMS__
                struct msg_set_host_param {
                        uint32_t        host_no;
                        uint32_t        param; /* enum iscsi_host_param */
                        uint32_t        len;
                } set_host_param;
-#endif
        } u;
        union {
                /* messages k -> u */
@@ -237,29 +231,14 @@ enum iscsi_param {
        ISCSI_PARAM_CONN_PORT,
        ISCSI_PARAM_CONN_ADDRESS,
 
-       /* must always be last */
-       ISCSI_PARAM_MAX,
-
-#ifndef __GENKSYMS__
-       /* no one uses ISCSI_PARAM_MAX */
-       ISCSI_PARAM_USERNAME = ISCSI_PARAM_MAX,
+       ISCSI_PARAM_USERNAME,
        ISCSI_PARAM_USERNAME_IN,
        ISCSI_PARAM_PASSWORD,
        ISCSI_PARAM_PASSWORD_IN,
 
-       /*
-        * These tmf timers are not yet used in RHEL, but come before the ping
-        * ones upstream so they are being brought in to maintain ordering.
-        */
        ISCSI_PARAM_FAST_ABORT,
-       ISCSI_PARAM_ABORT_TMO,
-       ISCSI_PARAM_LU_RESET_TMO,
-       ISCSI_PARAM_HOST_RESET_TMO,
-
-       ISCSI_PARAM_PING_TMO,
-       ISCSI_PARAM_RECV_TMO,
-
-#endif
+       /* must always be last */
+       ISCSI_PARAM_MAX,
 };
 
 #define ISCSI_MAX_RECV_DLENGTH         (1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
@@ -289,11 +268,6 @@ enum iscsi_param {
 #define ISCSI_PASSWORD                 (1 << ISCSI_PARAM_PASSWORD)
 #define ISCSI_PASSWORD_IN              (1 << ISCSI_PARAM_PASSWORD_IN)
 #define ISCSI_FAST_ABORT               (1 << ISCSI_PARAM_FAST_ABORT)
-#define ISCSI_ABORT_TMO                        (1 << ISCSI_PARAM_ABORT_TMO)
-#define ISCSI_LU_RESET_TMO             (1 << ISCSI_PARAM_LU_RESET_TMO)
-#define ISCSI_HOST_RESET_TMO           (1 << ISCSI_PARAM_HOST_RESET_TMO)
-#define ISCSI_PING_TMO                 (1 << ISCSI_PARAM_PING_TMO)
-#define ISCSI_RECV_TMO                 (1 << ISCSI_PARAM_RECV_TMO)
 
 /* iSCSI HBA params */
 enum iscsi_host_param {
@@ -339,7 +313,6 @@ enum iscsi_host_param {
  * These flags describes reason of stop_conn() call
  */
 #define STOP_CONN_TERM         0x1
-#define STOP_CONN_SUSPEND      0x2
 #define STOP_CONN_RECOVER      0x3
 
 #define ISCSI_STATS_CUSTOM_MAX         32
index a845f2e404a60f70ee5b02e88fb777837d2d11a5..e821932ed1ca6360e0e4d4978b00e9d3a3471770 100644 (file)
 }
 #define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;}
 
+/*
+ * If running svn modules we may need to define these.
+ * This should not go upstream since this is already properly defined there
+ */
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
 /* initiator tags; opaque for target */
 typedef uint32_t __bitwise__ itt_t;
 /* below makes sense only for initiator that created this tag */
@@ -58,12 +73,7 @@ struct iscsi_hdr {
        uint8_t         hlength;        /* AHSs total length */
        uint8_t         dlength[3];     /* Data length */
        uint8_t         lun[8];
-
-#ifndef __GENKSYMS__
        itt_t           itt;            /* Initiator Task Tag, opaque for target */
-#else
-       __be32          itt;
-#endif
        __be32          ttt;            /* Target Task Tag */
        __be32          statsn;
        __be32          exp_statsn;
@@ -124,11 +134,7 @@ struct iscsi_cmd {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
-       itt_t itt;      /* Initiator Task Tag */
-#else
-       __be32 itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32 data_length;
        __be32 cmdsn;
        __be32 exp_statsn;
@@ -165,11 +171,7 @@ struct iscsi_cmd_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32  rsvd1;
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -227,11 +229,7 @@ struct iscsi_nopout {
        uint8_t rsvd3;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32  ttt;    /* Target Transfer Tag */
        __be32  cmdsn;
        __be32  exp_statsn;
@@ -246,11 +244,7 @@ struct iscsi_nopin {
        uint8_t rsvd3;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32  ttt;    /* Target Transfer Tag */
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -266,17 +260,8 @@ struct iscsi_tm {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
        itt_t    itt;   /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
-
-#ifndef __GENKSYMS__
-       itt_t   rtt;    /* Reference Task Tag */
-#else
-       __be32  rtt;
-#endif
+       itt_t    rtt;   /* Reference Task Tag */
        __be32  cmdsn;
        __be32  exp_statsn;
        __be32  refcmdsn;
@@ -305,17 +290,8 @@ struct iscsi_tm_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd2[8];
-#ifndef __GENKSYMS__
        itt_t    itt;   /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
-
-#ifndef __GENKSYMS__
-       itt_t   rtt;    /* Reference Task Tag */
-#else
-       __be32  rtt
-#endif
+       itt_t    rtt;   /* Reference Task Tag */
        __be32  statsn;
        __be32  exp_cmdsn;
        __be32  max_cmdsn;
@@ -340,11 +316,7 @@ struct iscsi_r2t_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
        itt_t    itt;   /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
        __be32  ttt;    /* Target Transfer Tag */
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -362,11 +334,7 @@ struct iscsi_data {
        uint8_t rsvd3;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
        itt_t    itt;
-#else
-       __be32  itt;
-#endif
        __be32  ttt;
        __be32  rsvd4;
        __be32  exp_statsn;
@@ -386,11 +354,7 @@ struct iscsi_data_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t lun[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;
        __be32  ttt;
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -414,11 +378,7 @@ struct iscsi_text {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd4[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;
        __be32  ttt;
        __be32  cmdsn;
        __be32  exp_statsn;
@@ -436,11 +396,7 @@ struct iscsi_text_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd4[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;
        __be32  ttt;
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -459,11 +415,7 @@ struct iscsi_login {
        uint8_t dlength[3];
        uint8_t isid[6];        /* Initiator Session ID */
        __be16  tsih;   /* Target Session Handle */
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be16  cid;
        __be16  rsvd3;
        __be32  cmdsn;
@@ -492,11 +444,7 @@ struct iscsi_login_rsp {
        uint8_t dlength[3];
        uint8_t isid[6];        /* Initiator Session ID */
        __be16  tsih;   /* Target Session Handle */
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32  rsvd3;
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -553,11 +501,7 @@ struct iscsi_logout {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd2[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be16  cid;
        uint8_t rsvd3[2];
        __be32  cmdsn;
@@ -584,11 +528,7 @@ struct iscsi_logout_rsp {
        uint8_t hlength;
        uint8_t dlength[3];
        uint8_t rsvd3[8];
-#ifndef __GENKSYMS__
-       itt_t   itt;    /* Initiator Task Tag */
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;   /* Initiator Task Tag */
        __be32  rsvd4;
        __be32  statsn;
        __be32  exp_cmdsn;
@@ -611,11 +551,7 @@ struct iscsi_snack {
        uint8_t opcode;
        uint8_t flags;
        uint8_t rsvd2[14];
-#ifndef __GENKSYMS__
-       itt_t   itt;
-#else
-       __be32  itt;
-#endif
+       itt_t    itt;
        __be32  begrun;
        __be32  runlength;
        __be32  exp_statsn;
@@ -667,8 +603,6 @@ struct iscsi_reject {
 #define VALUE_MAXLEN           255
 #define TARGET_NAME_MAXLEN     VALUE_MAXLEN
 
-#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH   8192
-
 #define ISCSI_DEF_MAX_RECV_SEG_LEN             8192
 #define ISCSI_MIN_MAX_RECV_SEG_LEN             512
 #define ISCSI_MAX_MAX_RECV_SEG_LEN             16777215
@@ -681,6 +615,8 @@ struct iscsi_reject {
 #define ISCSI_MIN_MAX_BURST_LEN                        512
 #define ISCSI_MAX_MAX_BURST_LEN                        16777215
 
+#define ISCSI_DEF_TIME2WAIT                    2
+
 /************************* RFC 3720 End *****************************/
 
 #endif /* ISCSI_PROTO_H */
index 2b936f77ef9fdbd1279c9a53cdc0fbb41c982f57..dbea6b466e03a02bcfe8c34a0ce881ffc1a83f71 100644 (file)
 
 #include <linux/types.h>
 #include <linux/mutex.h>
-#include <scsi/iscsi_proto.h>
-#include <scsi/iscsi_if.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include "iscsi_proto.h"
+#include "iscsi_if.h"
 
 struct scsi_transport_template;
 struct scsi_device;
@@ -46,11 +48,8 @@ struct iscsi_nopin;
 #define debug_scsi(fmt...)
 #endif
 
-#define ISCSI_XMIT_CMDS_MAX    256     /* must be power of 2 */
+#define ISCSI_DEF_XMIT_CMDS_MAX        128     /* must be power of 2 */
 #define ISCSI_MGMT_CMDS_MAX    16      /* must be power of 2 */
-#define ISCSI_CONN_MAX                 1
-
-#define ISCSI_ADDRESS_BUF_LEN          64
 
 #define ISCSI_MGMT_ITT_OFFSET  0xa00
 
@@ -58,11 +57,14 @@ struct iscsi_nopin;
 #define ISCSI_MAX_CMD_PER_LUN          128
 
 /* Task Mgmt states */
-#define TMABORT_INITIAL                        0x0
-#define TMABORT_SUCCESS                        0x1
-#define TMABORT_FAILED                 0x2
-#define TMABORT_TIMEDOUT               0x3
-#define TMABORT_NOT_FOUND              0x4
+enum {
+       TMF_INITIAL,
+       TMF_QUEUED,
+       TMF_SUCCESS,
+       TMF_FAILED,
+       TMF_TIMEDOUT,
+       TMF_NOT_FOUND,
+};
 
 /* Connection suspend "bit" */
 #define ISCSI_SUSPEND_BIT              1
@@ -73,6 +75,8 @@ struct iscsi_nopin;
 #define ISCSI_AGE_SHIFT                        28
 #define ISCSI_AGE_MASK                 (0xf << ISCSI_AGE_SHIFT)
 
+#define ISCSI_ADDRESS_BUF_LEN          64
+
 struct iscsi_mgmt_task {
        /*
         * Becuae LLDs allocate their hdr differently, this is a pointer to
@@ -80,7 +84,7 @@ struct iscsi_mgmt_task {
         */
        struct iscsi_hdr        *hdr;
        char                    *data;          /* mgmt payload */
-       int                     data_count;     /* counts data to be sent */
+       unsigned                data_count;     /* counts data to be sent */
        uint32_t                itt;            /* this ITT */
        void                    *dd_data;       /* driver/transport data */
        struct list_head        running;
@@ -90,9 +94,6 @@ enum {
        ISCSI_TASK_COMPLETED,
        ISCSI_TASK_PENDING,
        ISCSI_TASK_RUNNING,
-#ifndef __GENKSYMS__
-       ISCSI_TASK_ABORTING,
-#endif
 };
 
 struct iscsi_cmd_task {
@@ -102,18 +103,15 @@ struct iscsi_cmd_task {
         */
        struct iscsi_cmd        *hdr;
        int                     itt;            /* this ITT */
-       int                     datasn;         /* DataSN */
 
        uint32_t                unsol_datasn;
-       int                     imm_count;      /* imm-data (bytes)   */
-       int                     unsol_count;    /* unsolicited (bytes)*/
+       unsigned                imm_count;      /* imm-data (bytes)   */
+       unsigned                unsol_count;    /* unsolicited (bytes)*/
        /* offset in unsolicited stream (bytes); */
-       int                     unsol_offset;
-       int                     data_count;     /* remaining Data-Out */
+       unsigned                unsol_offset;
+       unsigned                data_count;     /* remaining Data-Out */
        struct scsi_cmnd        *sc;            /* associated SCSI cmd*/
-       int                     total_length;
        struct iscsi_conn       *conn;          /* used connection    */
-       struct iscsi_mgmt_task  *mtask;         /* tmf mtask in progr */
 
        /* state set/tested under session->lock */
        int                     state;
@@ -141,7 +139,6 @@ struct iscsi_conn {
 
        /* control data */
        int                     id;             /* CID */
-       struct list_head        item;           /* maintains list of conns */
        int                     c_stage;        /* connection state */
        /*
         * Preallocated buffer for pdus that have data but do not
@@ -156,30 +153,24 @@ struct iscsi_conn {
        struct iscsi_cmd_task   *ctask;         /* xmit ctask in progress */
 
        /* xmit */
-       struct kfifo            *immqueue;      /* immediate xmit queue */
-       struct kfifo            *mgmtqueue;     /* mgmt (control) xmit queue */
+       struct list_head        mgmtqueue;      /* mgmt (control) xmit queue */
        struct list_head        mgmt_run_list;  /* list of control tasks */
        struct list_head        xmitqueue;      /* data-path cmd queue */
        struct list_head        run_list;       /* list of cmds in progress */
+       struct list_head        requeue;        /* tasks needing another run */
        struct work_struct      xmitwork;       /* per-conn. xmit workqueue */
-       /*
-        * serializes connection xmit, access to kfifos:
-        * xmitqueue, immqueue, mgmtqueue
-        */
-       struct mutex            xmitmutex;
-
        unsigned long           suspend_tx;     /* suspend Tx */
        unsigned long           suspend_rx;     /* suspend Rx */
 
        /* abort */
        wait_queue_head_t       ehwait;         /* used in eh_abort() */
        struct iscsi_tm         tmhdr;
-       struct timer_list       tmabort_timer;
-       int                     tmabort_state;  /* see TMABORT_INITIAL, etc.*/
+       struct timer_list       tmf_timer;
+       int                     tmf_state;      /* see TMF_INITIAL, etc.*/
 
        /* negotiated params */
-       int                     max_recv_dlength; /* initiator_max_recv_dsl*/
-       int                     max_xmit_dlength; /* target_max_recv_dsl */
+       unsigned                max_recv_dlength; /* initiator_max_recv_dsl*/
+       unsigned                max_xmit_dlength; /* target_max_recv_dsl */
        int                     hdrdgst_en;
        int                     datadgst_en;
        int                     ifmarker_en;
@@ -187,6 +178,12 @@ struct iscsi_conn {
        /* values userspace uses to id a conn */
        int                     persistent_port;
        char                    *persistent_address;
+       /* remote portal currently connected to */
+       int                     portal_port;
+       char                    portal_address[ISCSI_ADDRESS_BUF_LEN];
+       /* local address */
+       int                     local_port;
+       char                    local_address[ISCSI_ADDRESS_BUF_LEN];
 
        /* MIB-statistics */
        uint64_t                txdata_octets;
@@ -201,21 +198,6 @@ struct iscsi_conn {
 
        /* custom statistics */
        uint32_t                eh_abort_cnt;
-#ifndef __GENKSYMS__
-       /* remote portal currently connected to */
-       int                     portal_port;
-       char                    portal_address[ISCSI_ADDRESS_BUF_LEN];
-       /* local address */
-       int                     local_port;
-       char                    local_address[ISCSI_ADDRESS_BUF_LEN];
-
-       struct timer_list       transport_timer;
-       unsigned long           last_recv;
-       unsigned long           last_ping;
-       int                     ping_timeout;
-       int                     recv_timeout;
-       struct iscsi_mgmt_task  *ping_mtask;
-#endif
 };
 
 struct iscsi_queue {
@@ -225,25 +207,43 @@ struct iscsi_queue {
 };
 
 struct iscsi_session {
+       /*
+        * Syncs up the scsi eh thread with the iscsi eh thread when sending
+        * task management functions. This must be taken before the session
+        * and recv lock.
+        */
+       struct mutex            eh_mutex;
+
        /* iSCSI session-wide sequencing */
        uint32_t                cmdsn;
        uint32_t                exp_cmdsn;
        uint32_t                max_cmdsn;
 
+       /* This tracks the reqs queued into the initiator */
+       uint32_t                queued_cmdsn;
+
        /* configuration */
        int                     initial_r2t_en;
-       int                     max_r2t;
+       unsigned                max_r2t;
        int                     imm_data_en;
-       int                     first_burst;
-       int                     max_burst;
+       unsigned                first_burst;
+       unsigned                max_burst;
        int                     time2wait;
        int                     time2retain;
        int                     pdu_inorder_en;
        int                     dataseq_inorder_en;
        int                     erl;
+       int                     fast_abort;
        int                     tpgt;
+       char                    *username;
+       char                    *username_in;
+       char                    *password;
+       char                    *password_in;
        char                    *targetname;
-
+       char                    *initiatorname;
+       /* hw address or netdev iscsi connection is bound to */
+       char                    *hwaddress;
+       char                    *netdev;
        /* control data */
        struct iscsi_transport  *tt;
        struct Scsi_Host        *host;
@@ -255,35 +255,14 @@ struct iscsi_session {
                                                 * - mgmtpool,             *
                                                 * - r2tpool               */
        int                     state;          /* session state           */
-       struct list_head        item;
        int                     age;            /* counts session re-opens */
 
-       struct list_head        connections;    /* list of connections */
        int                     cmds_max;       /* size of cmds array */
        struct iscsi_cmd_task   **cmds;         /* Original Cmds arr */
        struct iscsi_queue      cmdpool;        /* PDU's pool */
        int                     mgmtpool_max;   /* size of mgmt array */
        struct iscsi_mgmt_task  **mgmt_cmds;    /* Original mgmt arr */
        struct iscsi_queue      mgmtpool;       /* Mgmt PDU's pool */
-#ifndef __GENKSYMS__
-       /* This tracks the reqs queued into the initiator */
-       uint32_t                queued_cmdsn;
-       /*
-        * Syncs up the scsi eh thread with the iscsi eh thread when sending
-        * task management functions. This must be taken before the session
-        * and recv lock.
-        */
-       struct mutex            eh_mutex;
-
-       char                    *username;
-       char                    *username_in;
-       char                    *password;
-       char                    *password_in;
-       char                    *initiatorname;
-       /* hw address or netdev iscsi connection is bound to */
-       char                    *hwaddress;
-       char                    *netdev;
-#endif
 };
 
 /*
@@ -292,9 +271,11 @@ struct iscsi_session {
 extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_host_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
 extern int iscsi_queuecommand(struct scsi_cmnd *sc,
                              void (*done)(struct scsi_cmnd *));
 
+
 /*
  * iSCSI host helpers.
  */
@@ -309,10 +290,7 @@ extern int iscsi_host_get_param(struct Scsi_Host *shost,
  */
 extern struct iscsi_cls_session *
 iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
-                   int, int, uint32_t, uint32_t *);
-extern struct iscsi_cls_session *
-iscsi_session_setup2(struct iscsi_transport *, struct scsi_transport_template *,
-                    uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
+                   uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
 extern void iscsi_session_teardown(struct iscsi_cls_session *);
 extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
 extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
@@ -341,8 +319,7 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
 /*
  * pdu and task processing
  */
-extern int iscsi_check_assign_cmdsn(struct iscsi_session *,
-                                   struct iscsi_nopin *);
+extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
 extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
                                        struct iscsi_data *hdr);
 extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
@@ -353,10 +330,7 @@ extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
                                char *, int);
 extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
                            uint32_t *);
-extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
-                                struct iscsi_mgmt_task *mtask);
-extern void iscsi_update_cmdsn(struct iscsi_session *,
-                               struct iscsi_nopin *);;
+extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
 
 /*
  * generic helpers
index e6d1d735cdccd0693ae44b627da8a5768bdd15aa..05e25542527cd77dc44e4d4b29eee0bda30ea0fd 100644 (file)
@@ -24,7 +24,7 @@
 #define SCSI_TRANSPORT_ISCSI_H
 
 #include <linux/device.h>
-#include <scsi/iscsi_if.h>
+#include "iscsi_if.h"
 
 struct scsi_transport_template;
 struct iscsi_transport;
@@ -79,7 +79,8 @@ struct iscsi_transport {
        char *name;
        unsigned int caps;
        /* LLD sets this to indicate what values it can export to sysfs */
-       unsigned int param_mask;
+       uint64_t param_mask;
+       uint64_t host_param_mask;
        struct scsi_host_template *host_template;
        /* LLD connection data size */
        int conndata_size;
@@ -89,7 +90,8 @@ struct iscsi_transport {
        unsigned int max_conn;
        unsigned int max_cmd_len;
        struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
-               struct scsi_transport_template *t, uint32_t sn, uint32_t *hn);
+               struct scsi_transport_template *t, uint16_t, uint16_t,
+               uint32_t sn, uint32_t *hn);
        void (*destroy_session) (struct iscsi_cls_session *session);
        struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
                                uint32_t cid);
@@ -105,14 +107,18 @@ struct iscsi_transport {
                               enum iscsi_param param, char *buf);
        int (*get_session_param) (struct iscsi_cls_session *session,
                                  enum iscsi_param param, char *buf);
+       int (*get_host_param) (struct Scsi_Host *shost,
+                               enum iscsi_host_param param, char *buf);
+       int (*set_host_param) (struct Scsi_Host *shost,
+                              enum iscsi_host_param param, char *buf,
+                              int buflen);
        int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
                         char *data, uint32_t data_size);
        void (*get_stats) (struct iscsi_cls_conn *conn,
                           struct iscsi_stats *stats);
        void (*init_cmd_task) (struct iscsi_cmd_task *ctask);
        void (*init_mgmt_task) (struct iscsi_conn *conn,
-                               struct iscsi_mgmt_task *mtask,
-                               char *data, uint32_t data_size);
+                               struct iscsi_mgmt_task *mtask);
        int (*xmit_cmd_task) (struct iscsi_conn *conn,
                              struct iscsi_cmd_task *ctask);
        void (*cleanup_cmd_task) (struct iscsi_conn *conn,
@@ -124,19 +130,8 @@ struct iscsi_transport {
                           uint64_t *ep_handle);
        int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
        void (*ep_disconnect) (uint64_t ep_handle);
-       int (*tgt_dscvr) (enum iscsi_tgt_dscvr type, uint32_t host_no,
+       int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
                          uint32_t enable, struct sockaddr *dst_addr);
-#ifndef __GENKSYMS__
-       uint64_t host_param_mask;
-       int (*get_host_param) (struct Scsi_Host *shost,
-                              enum iscsi_host_param param, char *buf);
-       int (*set_host_param) (struct Scsi_Host *shost,
-                             enum iscsi_host_param param, char *buf,
-                             int buflen);
-       struct iscsi_cls_session *(*create_session2) (struct iscsi_transport *i,
-               struct scsi_transport_template *t, uint16_t cmds_max,
-               uint16_t qdepth, uint32_t sn, uint32_t *hn);
-#endif
 };
 
 /*
@@ -187,7 +182,7 @@ struct iscsi_cls_session {
 
        /* recovery fields */
        int recovery_tmo;
-       struct work_struct recovery_work;
+       struct delayed_work recovery_work;
 
        int target_id;