]> Pileus Git - ~andy/linux/blobdiff - drivers/infiniband/ulp/iser/iser_initiator.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[~andy/linux] / drivers / infiniband / ulp / iser / iser_initiator.c
index 31ad498bdc51118f0418349c974e3018ccc6f1fb..cdd28318904732091be64ed22688109984e032a0 100644 (file)
@@ -64,46 +64,46 @@ static void iser_dto_add_regd_buff(struct iser_dto *dto,
 
 /* Register user buffer memory and initialize passive rdma
  *  dto descriptor. Total data size is stored in
- *  iser_ctask->data[ISER_DIR_IN].data_len
+ *  iser_task->data[ISER_DIR_IN].data_len
  */
-static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask,
+static int iser_prepare_read_cmd(struct iscsi_task *task,
                                 unsigned int edtl)
 
 {
-       struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+       struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_regd_buf *regd_buf;
        int err;
-       struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
-       struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN];
+       struct iser_hdr *hdr = &iser_task->desc.iser_header;
+       struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN];
 
-       err = iser_dma_map_task_data(iser_ctask,
+       err = iser_dma_map_task_data(iser_task,
                                     buf_in,
                                     ISER_DIR_IN,
                                     DMA_FROM_DEVICE);
        if (err)
                return err;
 
-       if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) {
+       if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
                iser_err("Total data length: %ld, less than EDTL: "
                         "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
-                        iser_ctask->data[ISER_DIR_IN].data_len, edtl,
-                        ctask->itt, iser_ctask->iser_conn);
+                        iser_task->data[ISER_DIR_IN].data_len, edtl,
+                        task->itt, iser_task->iser_conn);
                return -EINVAL;
        }
 
-       err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN);
+       err = iser_reg_rdma_mem(iser_task,ISER_DIR_IN);
        if (err) {
                iser_err("Failed to set up Data-IN RDMA\n");
                return err;
        }
-       regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN];
+       regd_buf = &iser_task->rdma_regd[ISER_DIR_IN];
 
        hdr->flags    |= ISER_RSV;
        hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey);
        hdr->read_va   = cpu_to_be64(regd_buf->reg.va);
 
        iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n",
-                ctask->itt, regd_buf->reg.rkey,
+                task->itt, regd_buf->reg.rkey,
                 (unsigned long long)regd_buf->reg.va);
 
        return 0;
@@ -111,43 +111,43 @@ static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask,
 
 /* Register user buffer memory and initialize passive rdma
  *  dto descriptor. Total data size is stored in
- *  ctask->data[ISER_DIR_OUT].data_len
+ *  task->data[ISER_DIR_OUT].data_len
  */
 static int
-iser_prepare_write_cmd(struct iscsi_cmd_task *ctask,
+iser_prepare_write_cmd(struct iscsi_task *task,
                       unsigned int imm_sz,
                       unsigned int unsol_sz,
                       unsigned int edtl)
 {
-       struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+       struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_regd_buf *regd_buf;
        int err;
-       struct iser_dto *send_dto = &iser_ctask->desc.dto;
-       struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
-       struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT];
+       struct iser_dto *send_dto = &iser_task->desc.dto;
+       struct iser_hdr *hdr = &iser_task->desc.iser_header;
+       struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
 
-       err = iser_dma_map_task_data(iser_ctask,
+       err = iser_dma_map_task_data(iser_task,
                                     buf_out,
                                     ISER_DIR_OUT,
                                     DMA_TO_DEVICE);
        if (err)
                return err;
 
-       if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) {
+       if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
                iser_err("Total data length: %ld, less than EDTL: %d, "
                         "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
-                        iser_ctask->data[ISER_DIR_OUT].data_len,
-                        edtl, ctask->itt, ctask->conn);
+                        iser_task->data[ISER_DIR_OUT].data_len,
+                        edtl, task->itt, task->conn);
                return -EINVAL;
        }
 
-       err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT);
+       err = iser_reg_rdma_mem(iser_task,ISER_DIR_OUT);
        if (err != 0) {
                iser_err("Failed to register write cmd RDMA mem\n");
                return err;
        }
 
-       regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+       regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
 
        if (unsol_sz < edtl) {
                hdr->flags     |= ISER_WSV;
@@ -156,13 +156,13 @@ iser_prepare_write_cmd(struct iscsi_cmd_task *ctask,
 
                iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
                         "VA:%#llX + unsol:%d\n",
-                        ctask->itt, regd_buf->reg.rkey,
+                        task->itt, regd_buf->reg.rkey,
                         (unsigned long long)regd_buf->reg.va, unsol_sz);
        }
 
        if (imm_sz > 0) {
                iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
-                        ctask->itt, imm_sz);
+                        task->itt, imm_sz);
                iser_dto_add_regd_buff(send_dto,
                                       regd_buf,
                                       0,
@@ -314,38 +314,38 @@ iser_check_xmit(struct iscsi_conn *conn, void *task)
 /**
  * iser_send_command - send command PDU
  */
-int iser_send_command(struct iscsi_conn     *conn,
-                     struct iscsi_cmd_task *ctask)
+int iser_send_command(struct iscsi_conn *conn,
+                     struct iscsi_task *task)
 {
        struct iscsi_iser_conn *iser_conn = conn->dd_data;
-       struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+       struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_dto *send_dto = NULL;
        unsigned long edtl;
        int err = 0;
        struct iser_data_buf *data_buf;
 
-       struct iscsi_cmd *hdr =  ctask->hdr;
-       struct scsi_cmnd *sc  =  ctask->sc;
+       struct iscsi_cmd *hdr =  task->hdr;
+       struct scsi_cmnd *sc  =  task->sc;
 
        if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
                iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
                return -EPERM;
        }
-       if (iser_check_xmit(conn, ctask))
+       if (iser_check_xmit(conn, task))
                return -ENOBUFS;
 
        edtl = ntohl(hdr->data_length);
 
        /* build the tx desc regd header and add it to the tx desc dto */
-       iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND;
-       send_dto = &iser_ctask->desc.dto;
-       send_dto->ctask = iser_ctask;
-       iser_create_send_desc(iser_conn, &iser_ctask->desc);
+       iser_task->desc.type = ISCSI_TX_SCSI_COMMAND;
+       send_dto = &iser_task->desc.dto;
+       send_dto->task = iser_task;
+       iser_create_send_desc(iser_conn, &iser_task->desc);
 
        if (hdr->flags & ISCSI_FLAG_CMD_READ)
-               data_buf = &iser_ctask->data[ISER_DIR_IN];
+               data_buf = &iser_task->data[ISER_DIR_IN];
        else
-               data_buf = &iser_ctask->data[ISER_DIR_OUT];
+               data_buf = &iser_task->data[ISER_DIR_OUT];
 
        if (scsi_sg_count(sc)) { /* using a scatter list */
                data_buf->buf  = scsi_sglist(sc);
@@ -355,15 +355,15 @@ int iser_send_command(struct iscsi_conn     *conn,
        data_buf->data_len = scsi_bufflen(sc);
 
        if (hdr->flags & ISCSI_FLAG_CMD_READ) {
-               err = iser_prepare_read_cmd(ctask, edtl);
+               err = iser_prepare_read_cmd(task, edtl);
                if (err)
                        goto send_command_error;
        }
        if (hdr->flags & ISCSI_FLAG_CMD_WRITE) {
-               err = iser_prepare_write_cmd(ctask,
-                                            ctask->imm_count,
-                                            ctask->imm_count +
-                                            ctask->unsol_count,
+               err = iser_prepare_write_cmd(task,
+                                            task->imm_count,
+                                            task->imm_count +
+                                            task->unsol_count,
                                             edtl);
                if (err)
                        goto send_command_error;
@@ -378,27 +378,27 @@ int iser_send_command(struct iscsi_conn     *conn,
                goto send_command_error;
        }
 
-       iser_ctask->status = ISER_TASK_STATUS_STARTED;
+       iser_task->status = ISER_TASK_STATUS_STARTED;
 
-       err = iser_post_send(&iser_ctask->desc);
+       err = iser_post_send(&iser_task->desc);
        if (!err)
                return 0;
 
 send_command_error:
        iser_dto_buffs_release(send_dto);
-       iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err);
+       iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
        return err;
 }
 
 /**
  * iser_send_data_out - send data out PDU
  */
-int iser_send_data_out(struct iscsi_conn     *conn,
-                      struct iscsi_cmd_task *ctask,
+int iser_send_data_out(struct iscsi_conn *conn,
+                      struct iscsi_task *task,
                       struct iscsi_data *hdr)
 {
        struct iscsi_iser_conn *iser_conn = conn->dd_data;
-       struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+       struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_desc *tx_desc = NULL;
        struct iser_dto *send_dto = NULL;
        unsigned long buf_offset;
@@ -411,7 +411,7 @@ int iser_send_data_out(struct iscsi_conn     *conn,
                return -EPERM;
        }
 
-       if (iser_check_xmit(conn, ctask))
+       if (iser_check_xmit(conn, task))
                return -ENOBUFS;
 
        itt = (__force uint32_t)hdr->itt;
@@ -432,7 +432,7 @@ int iser_send_data_out(struct iscsi_conn     *conn,
 
        /* build the tx desc regd header and add it to the tx desc dto */
        send_dto = &tx_desc->dto;
-       send_dto->ctask = iser_ctask;
+       send_dto->task = iser_task;
        iser_create_send_desc(iser_conn, tx_desc);
 
        iser_reg_single(iser_conn->ib_conn->device,
@@ -440,15 +440,15 @@ int iser_send_data_out(struct iscsi_conn     *conn,
 
        /* all data was registered for RDMA, we can use the lkey */
        iser_dto_add_regd_buff(send_dto,
-                              &iser_ctask->rdma_regd[ISER_DIR_OUT],
+                              &iser_task->rdma_regd[ISER_DIR_OUT],
                               buf_offset,
                               data_seg_len);
 
-       if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) {
+       if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
                iser_err("Offset:%ld & DSL:%ld in Data-Out "
                         "inconsistent with total len:%ld, itt:%d\n",
                         buf_offset, data_seg_len,
-                        iser_ctask->data[ISER_DIR_OUT].data_len, itt);
+                        iser_task->data[ISER_DIR_OUT].data_len, itt);
                err = -EINVAL;
                goto send_data_out_error;
        }
@@ -468,10 +468,11 @@ send_data_out_error:
 }
 
 int iser_send_control(struct iscsi_conn *conn,
-                     struct iscsi_mgmt_task *mtask)
+                     struct iscsi_task *task)
 {
        struct iscsi_iser_conn *iser_conn = conn->dd_data;
-       struct iser_desc *mdesc = mtask->dd_data;
+       struct iscsi_iser_task *iser_task = task->dd_data;
+       struct iser_desc *mdesc = &iser_task->desc;
        struct iser_dto *send_dto = NULL;
        unsigned long data_seg_len;
        int err = 0;
@@ -483,27 +484,27 @@ int iser_send_control(struct iscsi_conn *conn,
                return -EPERM;
        }
 
-       if (iser_check_xmit(conn,mtask))
+       if (iser_check_xmit(conn, task))
                return -ENOBUFS;
 
        /* build the tx desc regd header and add it to the tx desc dto */
        mdesc->type = ISCSI_TX_CONTROL;
        send_dto = &mdesc->dto;
-       send_dto->ctask = NULL;
+       send_dto->task = NULL;
        iser_create_send_desc(iser_conn, mdesc);
 
        device = iser_conn->ib_conn->device;
 
        iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
 
-       data_seg_len = ntoh24(mtask->hdr->dlength);
+       data_seg_len = ntoh24(task->hdr->dlength);
 
        if (data_seg_len > 0) {
                regd_buf = &mdesc->data_regd_buf;
                memset(regd_buf, 0, sizeof(struct iser_regd_buf));
                regd_buf->device = device;
-               regd_buf->virt_addr = mtask->data;
-               regd_buf->data_size = mtask->data_count;
+               regd_buf->virt_addr = task->data;
+               regd_buf->data_size = task->data_count;
                iser_reg_single(device, regd_buf,
                                DMA_TO_DEVICE);
                iser_dto_add_regd_buff(send_dto, regd_buf,
@@ -533,15 +534,13 @@ send_control_error:
 void iser_rcv_completion(struct iser_desc *rx_desc,
                         unsigned long dto_xfer_len)
 {
-       struct iser_dto        *dto = &rx_desc->dto;
+       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_task *task;
+       struct iscsi_iser_task *iser_task;
        struct iscsi_hdr *hdr;
        char   *rx_data = NULL;
        int     rx_data_len = 0;
-       unsigned int itt;
        unsigned char opcode;
 
        hdr = &rx_desc->iscsi_header;
@@ -557,19 +556,24 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
        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))
+               spin_lock(&conn->iscsi_conn->session->lock);
+               task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
+               if (task)
+                       __iscsi_get_task(task);
+               spin_unlock(&conn->iscsi_conn->session->lock);
+
+               if (!task)
                        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_task = task->dd_data;
+                       iser_dbg("itt %d task %p\n",hdr->itt, task);
+                       iser_task->status = ISER_TASK_STATUS_COMPLETED;
+                       iser_task_rdma_finalize(iser_task);
+                       iscsi_put_task(task);
+               }
        }
-
        iser_dto_buffs_release(dto);
 
        iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
@@ -590,7 +594,7 @@ void iser_snd_completion(struct iser_desc *tx_desc)
        struct iser_conn       *ib_conn = dto->ib_conn;
        struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
        struct iscsi_conn      *conn = iser_conn->iscsi_conn;
-       struct iscsi_mgmt_task *mtask;
+       struct iscsi_task *task;
        int resume_tx = 0;
 
        iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
@@ -613,36 +617,31 @@ void iser_snd_completion(struct iser_desc *tx_desc)
 
        if (tx_desc->type == ISCSI_TX_CONTROL) {
                /* this arithmetic is legal by libiscsi dd_data allocation */
-               mtask = (void *) ((long)(void *)tx_desc -
-                                 sizeof(struct iscsi_mgmt_task));
-               if (mtask->hdr->itt == RESERVED_ITT) {
-                       struct iscsi_session *session = conn->session;
-
-                       spin_lock(&conn->session->lock);
-                       iscsi_free_mgmt_task(conn, mtask);
-                       spin_unlock(&session->lock);
-               }
+               task = (void *) ((long)(void *)tx_desc -
+                                 sizeof(struct iscsi_task));
+               if (task->hdr->itt == RESERVED_ITT)
+                       iscsi_put_task(task);
        }
 }
 
-void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
+void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
 
 {
-       iser_ctask->status = ISER_TASK_STATUS_INIT;
+       iser_task->status = ISER_TASK_STATUS_INIT;
 
-       iser_ctask->dir[ISER_DIR_IN] = 0;
-       iser_ctask->dir[ISER_DIR_OUT] = 0;
+       iser_task->dir[ISER_DIR_IN] = 0;
+       iser_task->dir[ISER_DIR_OUT] = 0;
 
-       iser_ctask->data[ISER_DIR_IN].data_len  = 0;
-       iser_ctask->data[ISER_DIR_OUT].data_len = 0;
+       iser_task->data[ISER_DIR_IN].data_len  = 0;
+       iser_task->data[ISER_DIR_OUT].data_len = 0;
 
-       memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0,
+       memset(&iser_task->rdma_regd[ISER_DIR_IN], 0,
               sizeof(struct iser_regd_buf));
-       memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0,
+       memset(&iser_task->rdma_regd[ISER_DIR_OUT], 0,
               sizeof(struct iser_regd_buf));
 }
 
-void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
+void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
 {
        int deferred;
        int is_rdma_aligned = 1;
@@ -651,17 +650,17 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
        /* if we were reading, copy back to unaligned sglist,
         * anyway dma_unmap and free the copy
         */
-       if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
+       if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) {
                is_rdma_aligned = 0;
-               iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
+               iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN);
        }
-       if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
+       if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
                is_rdma_aligned = 0;
-               iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+               iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT);
        }
 
-       if (iser_ctask->dir[ISER_DIR_IN]) {
-               regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
+       if (iser_task->dir[ISER_DIR_IN]) {
+               regd = &iser_task->rdma_regd[ISER_DIR_IN];
                deferred = iser_regd_buff_release(regd);
                if (deferred) {
                        iser_err("%d references remain for BUF-IN rdma reg\n",
@@ -669,8 +668,8 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
                }
        }
 
-       if (iser_ctask->dir[ISER_DIR_OUT]) {
-               regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+       if (iser_task->dir[ISER_DIR_OUT]) {
+               regd = &iser_task->rdma_regd[ISER_DIR_OUT];
                deferred = iser_regd_buff_release(regd);
                if (deferred) {
                        iser_err("%d references remain for BUF-OUT rdma reg\n",
@@ -680,7 +679,7 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
 
        /* if the data was unaligned, it was already unmapped and then copied */
        if (is_rdma_aligned)
-               iser_dma_unmap_task_data(iser_ctask);
+               iser_dma_unmap_task_data(iser_task);
 }
 
 void iser_dto_buffs_release(struct iser_dto *dto)