dto->regd_vector_len++;
}
-static int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
- struct iser_data_buf *data,
- enum iser_data_dir iser_dir,
- enum dma_data_direction dma_dir)
-{
- struct device *dma_device;
-
- iser_ctask->dir[iser_dir] = 1;
- dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
- data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
- if (data->dma_nents == 0) {
- iser_err("dma_map_sg failed!!!\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
-{
- struct device *dma_device;
- struct iser_data_buf *data;
-
- dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
-
- if (iser_ctask->dir[ISER_DIR_IN]) {
- data = &iser_ctask->data[ISER_DIR_IN];
- dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
- }
-
- if (iser_ctask->dir[ISER_DIR_OUT]) {
- data = &iser_ctask->data[ISER_DIR_OUT];
- dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
- }
-}
-
/* Register user buffer memory and initialize passive rdma
* dto descriptor. Total data size is stored in
* iser_ctask->data[ISER_DIR_IN].data_len
}
recv_dto = &rx_desc->dto;
- recv_dto->conn = iser_conn;
+ recv_dto->ib_conn = iser_conn->ib_conn;
recv_dto->regd_vector_len = 0;
regd_hdr = &rx_desc->hdr_regd_buf;
regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */
regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
- send_dto->conn = iser_conn;
+ send_dto->ib_conn = iser_conn->ib_conn;
send_dto->notify_enable = 1;
send_dto->regd_vector_len = 0;
static int
iser_check_xmit(struct iscsi_conn *conn, void *task)
{
- int rc = 0;
struct iscsi_iser_conn *iser_conn = conn->dd_data;
- write_lock_bh(conn->recv_lock);
if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
ISER_QP_MAX_REQ_DTOS) {
- iser_dbg("%ld can't xmit task %p, suspending tx\n",jiffies,task);
- set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
- rc = -EAGAIN;
+ iser_dbg("%ld can't xmit task %p\n",jiffies,task);
+ return -ENOBUFS;
}
- write_unlock_bh(conn->recv_lock);
- return rc;
+ return 0;
}
return -EPERM;
}
if (iser_check_xmit(conn, ctask))
- return -EAGAIN;
+ return -ENOBUFS;
edtl = ntohl(hdr->data_length);
}
if (iser_check_xmit(conn, ctask))
- return -EAGAIN;
+ return -ENOBUFS;
itt = ntohl(hdr->itt);
data_seg_len = ntoh24(hdr->dlength);
struct iscsi_iser_conn *iser_conn = conn->dd_data;
struct iser_desc *mdesc = mtask->dd_data;
struct iser_dto *send_dto = NULL;
- unsigned int itt;
unsigned long data_seg_len;
int err = 0;
- unsigned char opcode;
struct iser_regd_buf *regd_buf;
struct iser_device *device;
}
if (iser_check_xmit(conn,mtask))
- return -EAGAIN;
+ return -ENOBUFS;
/* build the tx desc regd header and add it to the tx desc dto */
mdesc->type = ISCSI_TX_CONTROL;
iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
- itt = ntohl(mtask->hdr->itt);
- opcode = mtask->hdr->opcode & ISCSI_OPCODE_MASK;
data_seg_len = ntoh24(mtask->hdr->dlength);
if (data_seg_len > 0) {
unsigned long dto_xfer_len)
{
struct iser_dto *dto = &rx_desc->dto;
- struct iscsi_iser_conn *conn = dto->conn;
+ 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;
void iser_snd_completion(struct iser_desc *tx_desc)
{
struct iser_dto *dto = &tx_desc->dto;
- struct iscsi_iser_conn *iser_conn = dto->conn;
+ 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;
+ int resume_tx = 0;
iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
if (tx_desc->type == ISCSI_TX_DATAOUT)
kmem_cache_free(ig.desc_cache, tx_desc);
- atomic_dec(&iser_conn->ib_conn->post_send_buf_count);
+ if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
+ ISER_QP_MAX_REQ_DTOS)
+ resume_tx = 1;
+
+ atomic_dec(&ib_conn->post_send_buf_count);
- write_lock(conn->recv_lock);
- if (conn->suspend_tx) {
+ if (resume_tx) {
iser_dbg("%ld resuming tx\n",jiffies);
- clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
scsi_queue_work(conn->session->host, &conn->xmitwork);
}
- write_unlock(conn->recv_lock);
if (tx_desc->type == ISCSI_TX_CONTROL) {
/* this arithmetic is legal by libiscsi dd_data allocation */
void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
{
int deferred;
+ int is_rdma_aligned = 1;
/* 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_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
+ is_rdma_aligned = 0;
iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
- if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL)
+ }
+ if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
+ is_rdma_aligned = 0;
iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+ }
if (iser_ctask->dir[ISER_DIR_IN]) {
deferred = iser_regd_buff_release
}
}
- iser_dma_unmap_task_data(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);
}
void iser_dto_buffs_release(struct iser_dto *dto)