Merge mulgrave-w:git/scsi-misc-2.6
James Bottomley [Sat, 23 Sep 2006 20:33:43 +0000 (15:33 -0500)]
Conflicts:

drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h

Pretty horrible merge between crypto hash consolidation
and crypto_digest_...->crypto_hash_... conversion

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

1  2 
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
include/linux/pci_ids.h

@@@ -108,12 -107,9 +107,9 @@@ iscsi_hdr_digest(struct iscsi_conn *con
                 u8* crc)
  {
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-       struct hash_desc desc;
  
-       desc.tfm = tcp_conn->tx_tfm;
-       desc.flags = 0;
-       crypto_hash_digest(&desc, &buf->sg, buf->sg.length, crc);
-       buf->sg.length += sizeof(uint32_t);
 -      crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc);
++      crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
+       buf->sg.length = tcp_conn->hdr_size;
  }
  
  static inline int
@@@ -461,9 -468,7 +468,8 @@@ iscsi_tcp_hdr_recv(struct iscsi_conn *c
  
                sg_init_one(&sg, (u8 *)hdr,
                            sizeof(struct iscsi_hdr) + ahslen);
-               desc.tfm = tcp_conn->rx_tfm;
-               desc.flags = 0;
-               crypto_hash_digest(&desc, &sg, sg.length, (u8 *)&cdgst);
 -              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) {
@@@ -672,15 -675,15 +676,15 @@@ iscsi_tcp_copy(struct iscsi_conn *conn
  }
  
  static inline void
- partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn,
-                        struct scatterlist *sg, int offset, int length)
 -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;
  
        memcpy(&temp, sg, sizeof(struct scatterlist));
        temp.offset = offset;
        temp.length = length;
-       crypto_hash_update(&tcp_conn->data_rx_hash, &temp, length);
 -      crypto_digest_update(tfm, &temp, 1);
++      crypto_hash_update(desc, &temp, length);
  }
  
  static void
@@@ -689,7 -692,7 +693,7 @@@ iscsi_recv_digest_update(struct iscsi_t
        struct scatterlist tmp;
  
        sg_init_one(&tmp, buf, len);
-       crypto_hash_update(&tcp_conn->data_rx_hash, &tmp, 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)
                if (!rc) {
                        if (conn->datadgst_en) {
                                if (!offset)
 -                                      crypto_digest_update(
 -                                                      tcp_conn->rx_tfm,
 +                                      crypto_hash_update(
-                                                       &tcp_conn->data_rx_hash,
-                                                       &sg[i], sg[i].length);
++                                                      &tcp_conn->rx_hash,
+                                                       &sg[i], 1);
                                else
-                                       partial_sg_digest_update(tcp_conn,
+                                       partial_sg_digest_update(
 -                                                      tcp_conn->rx_tfm,
++                                                      &tcp_conn->rx_hash,
                                                        &sg[i],
                                                        sg[i].offset + offset,
                                                        sg[i].length - offset);
                                /*
                                 * data-in is complete, but buffer not...
                                 */
-                               partial_sg_digest_update(tcp_conn, &sg[i],
-                                               sg[i].offset, sg[i].length-rc);
 -                              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;
                }
@@@ -883,9 -884,8 +886,8 @@@ more
                 */
                rc = iscsi_tcp_hdr_recv(conn);
                if (!rc && tcp_conn->in.datalen) {
-                       if (conn->datadgst_en) {
-                               crypto_hash_init(&tcp_conn->data_rx_hash);
-                       }
+                       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);
                                          tcp_conn->in.padding);
                                memset(pad, 0, tcp_conn->in.padding);
                                sg_init_one(&sg, pad, tcp_conn->in.padding);
-                               crypto_hash_update(&tcp_conn->data_rx_hash,
 -                              crypto_digest_update(tcp_conn->rx_tfm,
 -                                                   &sg, 1);
++                              crypto_hash_update(&tcp_conn->rx_hash,
 +                                                 &sg, sg.length);
                        }
-                       crypto_hash_final(&tcp_conn->data_rx_hash,
-                                         (u8 *)&tcp_conn->in.datadgst);
 -                      crypto_digest_final(tcp_conn->rx_tfm,
 -                                          (u8 *) &tcp_conn->in.datadgst);
++                      crypto_hash_final(&tcp_conn->rx_hash,
++                                        (u8 *) &tcp_conn->in.datadgst);
                        debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
                        tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
+                       tcp_conn->data_copied = 0;
                } else
                        tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
        }
@@@ -1183,11 -1189,9 +1191,9 @@@ iscsi_sendpage(struct iscsi_conn *conn
  
  static inline void
  iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
-                     struct iscsi_cmd_task *ctask)
+                     struct iscsi_tcp_cmd_task *tcp_ctask)
  {
-       struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-       crypto_hash_init(&tcp_conn->data_tx_hash);
 -      crypto_digest_init(tcp_conn->tx_tfm);
++      crypto_hash_init(&tcp_conn->tx_hash);
        tcp_ctask->digest_count = 4;
  }
  
@@@ -1450,86 -1416,125 +1418,126 @@@ iscsi_send_write_hdr(struct iscsi_conn 
                iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
                                 (u8*)tcp_ctask->hdrext);
        rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
-       if (rc)
+       if (rc) {
                tcp_ctask->xmstate |= XMSTATE_W_HDR;
-       return rc;
+               return rc;
+       }
+       if (ctask->imm_count) {
+               tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
+               iscsi_set_padding(tcp_ctask, ctask->imm_count);
+               if (ctask->conn->datadgst_en) {
+                       iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
+                       tcp_ctask->immdigest = 0;
+               }
+       }
+       if (ctask->unsol_count)
+               tcp_ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
+       return 0;
  }
  
- static inline int
- handle_xmstate_data_digest(struct iscsi_conn *conn,
-                          struct iscsi_cmd_task *ctask)
+ static int
+ iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
  {
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-       int rc;
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       int sent = 0, rc;
  
-       tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST;
-       debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest);
-       rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf,
-                                   &tcp_ctask->datadigest, 0);
+       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);
++                      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;
+       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);
+       rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
+                          &sent);
        if (rc) {
-               tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
-               debug_tcp("resent data digest 0x%x fail!\n",
-                         tcp_ctask->datadigest);
+               debug_scsi("padding send failed %d\n", rc);
+               tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
        }
        return rc;
  }
  
- static inline int
- handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ static int
+ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+                       struct iscsi_buf *buf, uint32_t *digest)
  {
-       struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-       int rc;
+       struct iscsi_tcp_cmd_task *tcp_ctask;
+       struct iscsi_tcp_conn *tcp_conn;
+       int rc, sent = 0;
  
-       BUG_ON(!ctask->imm_count);
-       tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
+       if (!conn->datadgst_en)
+               return 0;
  
-       if (conn->datadgst_en) {
-               iscsi_data_digest_init(tcp_conn, ctask);
-               tcp_ctask->immdigest = 0;
-       }
+       tcp_ctask = ctask->dd_data;
+       tcp_conn = conn->dd_data;
  
-       for (;;) {
-               rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf,
-                                  &ctask->imm_count, &tcp_ctask->sent);
-               if (rc) {
-                       tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
-                       if (conn->datadgst_en) {
-                               crypto_hash_final(&tcp_conn->data_tx_hash,
-                                                 (u8 *)&tcp_ctask->immdigest);
-                               debug_tcp("tx imm sendpage fail 0x%x\n",
-                                         tcp_ctask->datadigest);
-                       }
-                       return rc;
-               }
-               if (conn->datadgst_en)
-                       crypto_hash_update(&tcp_conn->data_tx_hash,
-                                          &tcp_ctask->sendbuf.sg,
-                                          tcp_ctask->sendbuf.sg.length);
+       if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
 -              crypto_digest_final(tcp_conn->tx_tfm, (u8*)digest);
++              crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
+               iscsi_buf_init_iov(buf, (char*)digest, 4);
+       }
+       tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
  
-               if (!ctask->imm_count)
-                       break;
-               iscsi_buf_init_sg(&tcp_ctask->sendbuf,
-                                 &tcp_ctask->sg[tcp_ctask->sg_count++]);
+       rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
+       if (!rc)
+               debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest,
+                         ctask->itt);
+       else {
+               debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
+                         *digest, ctask->itt);
+               tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST;
        }
+       return rc;
+ }
  
-       if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) {
-               rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf,
-                                           &tcp_ctask->immdigest, 1);
-               if (rc) {
-                       debug_tcp("sending imm digest 0x%x fail!\n",
-                                 tcp_ctask->immdigest);
-                       return rc;
+ static int
+ iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
+               struct scatterlist **sg, int *sent, int *count,
+               struct iscsi_buf *digestbuf, uint32_t *digest)
+ {
+       struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+       struct iscsi_conn *conn = ctask->conn;
+       struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+       int rc, buf_sent, offset;
+       while (*count) {
+               buf_sent = 0;
+               offset = sendbuf->sent;
+               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) {
+                       iscsi_buf_init_sg(sendbuf, *sg);
+                       *sg = *sg + 1;
                }
-               debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest);
+               if (rc)
+                       return rc;
        }
  
-       return 0;
+       rc = iscsi_send_padding(conn, ctask);
+       if (rc)
+               return rc;
+       return iscsi_send_digest(conn, ctask, digestbuf, digest);
  }
  
- static inline int
- handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ static int
+ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
  {
        struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
        struct iscsi_data_task *dtask;
@@@ -1931,8 -1768,20 +1771,24 @@@ iscsi_tcp_conn_create(struct iscsi_cls_
        /* 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 (!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 (!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:
        iscsi_conn_teardown(cls_conn);
        return NULL;
@@@ -1970,14 -1819,10 +1826,10 @@@ iscsi_tcp_conn_destroy(struct iscsi_cls
  
        /* now free tcp_conn */
        if (digest) {
--              if (tcp_conn->tx_tfm)
-                       crypto_free_hash(tcp_conn->tx_tfm);
-               if (tcp_conn->rx_tfm)
-                       crypto_free_hash(tcp_conn->rx_tfm);
-               if (tcp_conn->data_tx_hash.tfm)
-                       crypto_free_hash(tcp_conn->data_tx_hash.tfm);
-               if (tcp_conn->data_rx_hash.tfm)
-                       crypto_free_hash(tcp_conn->data_rx_hash.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);
@@@ -84,10 -81,6 +82,7 @@@ struct iscsi_tcp_conn 
                                                 * stop to terminate */
        /* iSCSI connection-wide sequencing */
        int                     hdr_size;       /* PDU header size */
 +
-       struct crypto_hash      *rx_tfm;        /* CRC32C (Rx) */
-       struct hash_desc        data_rx_hash;   /* CRC32C (Rx) for data */
        /* control data */
        struct iscsi_tcp_recv   in;             /* TCP receive context */
        int                     in_progress;    /* connection state machine */
@@@ -97,9 -90,9 +92,9 @@@
        void                    (*old_state_change)(struct sock *);
        void                    (*old_write_space)(struct sock *);
  
-       /* xmit */
-       struct crypto_hash      *tx_tfm;        /* CRC32C (Tx) */
-       struct hash_desc        data_tx_hash;   /* CRC32C (Tx) for data */
+       /* 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;
Simple merge