crypto_digest_update(conn->data_rx_tfm, &temp, 1);
 }
 
+static void
+iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len)
+{
+       struct scatterlist tmp;
+
+       sg_init_one(&tmp, buf, len);
+       crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
+}
+
 static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 {
        struct iscsi_cmd_task *ctask = conn->in.ctask;
        struct scsi_cmnd *sc = ctask->sc;
-       struct scatterlist tmp, *sg;
+       struct scatterlist *sg;
        int i, offset, rc = 0;
 
        BUG_ON((void*)ctask != sc->SCp.ptr);
                                      sc->request_bufflen, ctask->data_offset);
                if (rc == -EAGAIN)
                        return rc;
-               if (conn->datadgst_en) {
-                       sg_init_one(&tmp, sc->request_buffer, i);
-                       crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
-               }
+               if (conn->datadgst_en) 
+                       iscsi_recv_digest_update(conn, sc->request_buffer, i);
                rc = 0;
                goto done;
        }
                conn->in.hdr = &conn->hdr;
                conn->senselen = (conn->data[0] << 8) | conn->data[1];
                rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+               if (!rc && conn->datadgst_en) 
+                       iscsi_recv_digest_update(conn, conn->data,
+                                                conn->in.datalen);
        }
        break;
        case ISCSI_OP_TEXT_RSP:
                rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
                                    conn->data, conn->in.datalen);
 
+               if (!rc && conn->datadgst_en && 
+                       conn->in.opcode != ISCSI_OP_LOGIN_RSP)
+                       iscsi_recv_digest_update(conn, conn->data,
+                                               conn->in.datalen);
+
                if (mtask && conn->login_mtask != mtask) {
                        spin_lock(&session->lock);
                        __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
                }
        }
        break;
+       case ISCSI_OP_ASYNC_EVENT:
+       case ISCSI_OP_REJECT:
        default:
                BUG_ON(1);
        }
                rc = iscsi_hdr_recv(conn);
                if (!rc && conn->in.datalen) {
                        if (conn->datadgst_en &&
-                           conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+                               conn->in.opcode != ISCSI_OP_LOGIN_RSP) {
                                BUG_ON(!conn->data_rx_tfm);
                                crypto_digest_init(conn->data_rx_tfm);
                        }
        }
 
        if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+               uint32_t recv_digest;
                debug_tcp("extra data_recv offset %d copy %d\n",
                          conn->in.offset, conn->in.copy);
-               if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
-                       uint32_t recv_digest;
-                       skb_copy_bits(conn->in.skb, conn->in.offset,
-                                     &recv_digest, 4);
-                       conn->in.offset += 4;
-                       conn->in.copy -= 4;
-                       if (recv_digest != conn->in.datadgst) {
-                               debug_tcp("iscsi_tcp: data digest error!"
-                                         "0x%x != 0x%x\n", recv_digest,
-                                         conn->in.datadgst);
-                               iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
-                               return 0;
-                       } else {
-                               debug_tcp("iscsi_tcp: data digest match!"
-                                         "0x%x == 0x%x\n", recv_digest,
-                                         conn->in.datadgst);
-                               conn->in_progress = IN_PROGRESS_WAIT_HEADER;
-                       }
+               skb_copy_bits(conn->in.skb, conn->in.offset,
+                               &recv_digest, 4);
+               conn->in.offset += 4;
+               conn->in.copy -= 4;
+               if (recv_digest != conn->in.datadgst) {
+                       debug_tcp("iscsi_tcp: data digest error!"
+                                 "0x%x != 0x%x\n", recv_digest,
+                                 conn->in.datadgst);
+                       iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+                       return 0;
+               } else {
+                       debug_tcp("iscsi_tcp: data digest match!"
+                                 "0x%x == 0x%x\n", recv_digest,
+                                 conn->in.datadgst);
+                       conn->in_progress = IN_PROGRESS_WAIT_HEADER;
                }
        }
 
                conn->in.copy -= conn->in.padding;
                conn->in.offset += conn->in.padding;
                if (conn->datadgst_en &&
-                   conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+                       conn->in.opcode != ISCSI_OP_LOGIN_RSP) {
                        if (conn->in.padding) {
                                debug_tcp("padding -> %d\n", conn->in.padding);
                                memset(pad, 0, conn->in.padding);