struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
 {
        int rc = 0;
-       uint32_t ret_itt;
        int datalen;
        int ahslen;
 
        /* read AHS */
        ahslen = hdr->hlength * 4;
 
-       /* verify itt (itt encoding: age+cid+itt) */
-       rc = iscsi_verify_itt(conn, hdr, &ret_itt);
-
-       if (!rc)
-               rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
-
+       rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
        if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
                goto error;
 
 
 {
        struct iser_dto        *dto = &rx_desc->dto;
        struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
-       struct iscsi_session *session = conn->iscsi_conn->session;
        struct iscsi_cmd_task *ctask;
        struct iscsi_iser_cmd_task *iser_ctask;
        struct iscsi_hdr *hdr;
        char   *rx_data = NULL;
        int     rx_data_len = 0;
-       unsigned int itt;
        unsigned char opcode;
 
        hdr = &rx_desc->iscsi_header;
        opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
        if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
-               itt = get_itt(hdr->itt); /* mask out cid and age bits */
-               if (!(itt < session->cmds_max))
+               ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
+               if (!ctask)
                        iser_err("itt can't be matched to task!!! "
-                                "conn %p opcode %d cmds_max %d itt %d\n",
-                                conn->iscsi_conn,opcode,session->cmds_max,itt);
-               /* use the mapping given with the cmds array indexed by itt */
-               ctask = (struct iscsi_cmd_task *)session->cmds[itt];
-               iser_ctask = ctask->dd_data;
-               iser_dbg("itt %d ctask %p\n",itt,ctask);
-               iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
-               iser_ctask_rdma_finalize(iser_ctask);
+                                "conn %p opcode %d itt %d\n",
+                                conn->iscsi_conn, opcode, hdr->itt);
+               else {
+                       iser_ctask = ctask->dd_data;
+                       iser_dbg("itt %d ctask %p\n",hdr->itt, ctask);
+                       iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
+                       iser_ctask_rdma_finalize(iser_ctask);
+               }
        }
-
        iser_dto_buffs_release(dto);
 
        iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
 
        struct iscsi_session *session = conn->session;
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        struct iscsi_cmd_task *ctask;
-       uint32_t itt;
 
        /* verify PDU length */
        tcp_conn->in.datalen = ntoh24(hdr->dlength);
 
        opcode = hdr->opcode & ISCSI_OPCODE_MASK;
        /* verify itt (itt encoding: age+cid+itt) */
-       rc = iscsi_verify_itt(conn, hdr, &itt);
+       rc = iscsi_verify_itt(conn, hdr->itt);
        if (rc)
                return rc;
 
 
        switch(opcode) {
        case ISCSI_OP_SCSI_DATA_IN:
-               ctask = session->cmds[itt];
+               ctask = iscsi_itt_to_ctask(conn, hdr->itt);
+               if (!ctask)
+                       return ISCSI_ERR_BAD_ITT;
+
                spin_lock(&conn->session->lock);
                rc = iscsi_data_rsp(conn, ctask);
                spin_unlock(&conn->session->lock);
                rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
                break;
        case ISCSI_OP_R2T:
-               ctask = session->cmds[itt];
+               ctask = iscsi_itt_to_ctask(conn, hdr->itt);
+               if (!ctask)
+                       return ISCSI_ERR_BAD_ITT;
+
                if (ahslen)
                        rc = ISCSI_ERR_AHSLEN;
                else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
 
        uint32_t itt;
 
        conn->last_recv = jiffies;
+       rc = iscsi_verify_itt(conn, hdr->itt);
+       if (rc)
+               return rc;
+
        if (hdr->itt != RESERVED_ITT)
                itt = get_itt(hdr->itt);
        else
 }
 EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
 
-/* verify itt (itt encoding: age+cid+itt) */
-int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-                    uint32_t *ret_itt)
+int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
 {
        struct iscsi_session *session = conn->session;
        struct iscsi_cmd_task *ctask;
-       uint32_t itt;
 
-       if (hdr->itt != RESERVED_ITT) {
-               if (((__force u32)hdr->itt & ISCSI_AGE_MASK) !=
-                   (session->age << ISCSI_AGE_SHIFT)) {
-                       iscsi_conn_printk(KERN_ERR, conn,
-                                         "received itt %x expected session "
-                                         "age (%x)\n", (__force u32)hdr->itt,
-                                         session->age & ISCSI_AGE_MASK);
-                       return ISCSI_ERR_BAD_ITT;
-               }
+       if (itt == RESERVED_ITT)
+               return 0;
 
-               itt = get_itt(hdr->itt);
-       } else
-               itt = ~0U;
+       if (((__force u32)itt & ISCSI_AGE_MASK) !=
+           (session->age << ISCSI_AGE_SHIFT)) {
+               iscsi_conn_printk(KERN_ERR, conn,
+                                 "received itt %x expected session age (%x)\n",
+                                 (__force u32)itt,
+                                 session->age & ISCSI_AGE_MASK);
+               return ISCSI_ERR_BAD_ITT;
+       }
 
        if (itt < session->cmds_max) {
                ctask = session->cmds[itt];
                }
        }
 
-       *ret_itt = itt;
        return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_verify_itt);
 
+struct iscsi_cmd_task *
+iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
+{
+       struct iscsi_session *session = conn->session;
+       struct iscsi_cmd_task *ctask;
+       uint32_t i;
+
+       if (iscsi_verify_itt(conn, itt))
+               return NULL;
+
+       if (itt == RESERVED_ITT)
+               return NULL;
+
+       i = get_itt(itt);
+       if (i >= session->cmds_max)
+               return NULL;
+
+       ctask = session->cmds[i];
+       if (!ctask->sc)
+               return NULL;
+
+       if (ctask->sc->SCp.phase != session->age)
+               return NULL;
+
+       return ctask;
+}
+EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
+
 void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
 {
        struct iscsi_session *session = conn->session;
 
                                char *, uint32_t);
 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 int iscsi_verify_itt(struct iscsi_conn *, itt_t);
+extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
 extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
 extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
                                 struct iscsi_mgmt_task *mtask);