iser_initiator.c 18.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/*
 * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *	- Redistributions of source code must retain the above
 *	  copyright notice, this list of conditions and the following
 *	  disclaimer.
 *
 *	- Redistributions in binary form must reproduce the above
 *	  copyright notice, this list of conditions and the following
 *	  disclaimer in the documentation and/or other materials
 *	  provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/kfifo.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>

#include "iscsi_iser.h"


/* iser_dto_add_regd_buff - increments the reference count for *
 * the registered buffer & adds it to the DTO object           */
static void iser_dto_add_regd_buff(struct iser_dto *dto,
				   struct iser_regd_buf *regd_buf,
				   unsigned long use_offset,
				   unsigned long use_size)
{
	int add_idx;

	atomic_inc(&regd_buf->ref_count);

	add_idx = dto->regd_vector_len;
	dto->regd[add_idx] = regd_buf;
	dto->used_sz[add_idx] = use_size;
	dto->offset[add_idx] = use_offset;

	dto->regd_vector_len++;
}

/* Register user buffer memory and initialize passive rdma
 *  dto descriptor. Total data size is stored in
64
 *  iser_task->data[ISER_DIR_IN].data_len
65
 */
66
static int iser_prepare_read_cmd(struct iscsi_task *task,
67 68 69
				 unsigned int edtl)

{
70
	struct iscsi_iser_task *iser_task = task->dd_data;
71 72
	struct iser_regd_buf *regd_buf;
	int err;
73 74
	struct iser_hdr *hdr = &iser_task->desc.iser_header;
	struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN];
75

76
	err = iser_dma_map_task_data(iser_task,
77 78 79 80 81 82
				     buf_in,
				     ISER_DIR_IN,
				     DMA_FROM_DEVICE);
	if (err)
		return err;

83
	if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
84 85
		iser_err("Total data length: %ld, less than EDTL: "
			 "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
86 87
			 iser_task->data[ISER_DIR_IN].data_len, edtl,
			 task->itt, iser_task->iser_conn);
88 89 90
		return -EINVAL;
	}

91
	err = iser_reg_rdma_mem(iser_task,ISER_DIR_IN);
92 93 94 95
	if (err) {
		iser_err("Failed to set up Data-IN RDMA\n");
		return err;
	}
96
	regd_buf = &iser_task->rdma_regd[ISER_DIR_IN];
97 98 99 100 101 102

	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",
103
		 task->itt, regd_buf->reg.rkey,
104 105 106 107 108 109 110
		 (unsigned long long)regd_buf->reg.va);

	return 0;
}

/* Register user buffer memory and initialize passive rdma
 *  dto descriptor. Total data size is stored in
111
 *  task->data[ISER_DIR_OUT].data_len
112 113
 */
static int
114
iser_prepare_write_cmd(struct iscsi_task *task,
115 116 117 118
		       unsigned int imm_sz,
		       unsigned int unsol_sz,
		       unsigned int edtl)
{
119
	struct iscsi_iser_task *iser_task = task->dd_data;
120 121
	struct iser_regd_buf *regd_buf;
	int err;
122 123 124
	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];
125

126
	err = iser_dma_map_task_data(iser_task,
127 128 129 130 131 132
				     buf_out,
				     ISER_DIR_OUT,
				     DMA_TO_DEVICE);
	if (err)
		return err;

133
	if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
134 135
		iser_err("Total data length: %ld, less than EDTL: %d, "
			 "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
136 137
			 iser_task->data[ISER_DIR_OUT].data_len,
			 edtl, task->itt, task->conn);
138 139 140
		return -EINVAL;
	}

141
	err = iser_reg_rdma_mem(iser_task,ISER_DIR_OUT);
142 143 144 145 146
	if (err != 0) {
		iser_err("Failed to register write cmd RDMA mem\n");
		return err;
	}

147
	regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
148 149 150 151 152 153 154 155

	if (unsol_sz < edtl) {
		hdr->flags     |= ISER_WSV;
		hdr->write_stag = cpu_to_be32(regd_buf->reg.rkey);
		hdr->write_va   = cpu_to_be64(regd_buf->reg.va + unsol_sz);

		iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
			 "VA:%#llX + unsol:%d\n",
156
			 task->itt, regd_buf->reg.rkey,
157 158 159 160 161
			 (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",
162
			 task->itt, imm_sz);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
		iser_dto_add_regd_buff(send_dto,
				       regd_buf,
				       0,
				       imm_sz);
	}

	return 0;
}

/* creates a new tx descriptor and adds header regd buffer */
static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
				  struct iser_desc       *tx_desc)
{
	struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf;
	struct iser_dto      *send_dto = &tx_desc->dto;

	memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
	regd_hdr->device  = iser_conn->ib_conn->device;
	regd_hdr->virt_addr  = tx_desc; /* == &tx_desc->iser_header */
182
	regd_hdr->data_size  = ISER_HEADERS_LEN;
183

184
	send_dto->ib_conn         = iser_conn->ib_conn;
185 186 187 188 189 190 191 192 193
	send_dto->notify_enable   = 1;
	send_dto->regd_vector_len = 0;

	memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
	tx_desc->iser_header.flags = ISER_VER;

	iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0);
}

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
{
	int i, j;
	u64 dma_addr;
	struct iser_rx_desc *rx_desc;
	struct ib_sge       *rx_sg;
	struct iser_device  *device = ib_conn->device;

	ib_conn->rx_descs = kmalloc(ISER_QP_MAX_RECV_DTOS *
				sizeof(struct iser_rx_desc), GFP_KERNEL);
	if (!ib_conn->rx_descs)
		goto rx_desc_alloc_fail;

	rx_desc = ib_conn->rx_descs;

	for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++)  {
		dma_addr = ib_dma_map_single(device->ib_device, (void *)rx_desc,
					ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
		if (ib_dma_mapping_error(device->ib_device, dma_addr))
			goto rx_desc_dma_map_failed;

		rx_desc->dma_addr = dma_addr;

		rx_sg = &rx_desc->rx_sg;
		rx_sg->addr   = rx_desc->dma_addr;
		rx_sg->length = ISER_RX_PAYLOAD_SIZE;
		rx_sg->lkey   = device->mr->lkey;
	}

	ib_conn->rx_desc_head = 0;
	return 0;

rx_desc_dma_map_failed:
	rx_desc = ib_conn->rx_descs;
	for (j = 0; j < i; j++, rx_desc++)
		ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
			ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
	kfree(ib_conn->rx_descs);
	ib_conn->rx_descs = NULL;
rx_desc_alloc_fail:
	iser_err("failed allocating rx descriptors / data buffers\n");
	return -ENOMEM;
}

void iser_free_rx_descriptors(struct iser_conn *ib_conn)
{
	int i;
	struct iser_rx_desc *rx_desc;
	struct iser_device *device = ib_conn->device;

	if (ib_conn->login_buf) {
		ib_dma_unmap_single(device->ib_device, ib_conn->login_dma,
			ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
		kfree(ib_conn->login_buf);
	}

	if (!ib_conn->rx_descs)
		return;

	rx_desc = ib_conn->rx_descs;
	for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++)
		ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
			ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
	kfree(ib_conn->rx_descs);
}

260 261 262 263 264 265 266
/**
 *  iser_conn_set_full_featured_mode - (iSER API)
 */
int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
{
	struct iscsi_iser_conn *iser_conn = conn->dd_data;

267
	iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
268 269 270

	/* Check that there is no posted recv or send buffers left - */
	/* they must be consumed during the login phase */
271
	BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
272 273
	BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);

274 275 276
	if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
		return -ENOMEM;

277
	/* Initial post receive buffers */
278 279 280
	if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
		return -ENOMEM;

281 282 283 284 285 286 287 288 289 290
	return 0;
}

static int
iser_check_xmit(struct iscsi_conn *conn, void *task)
{
	struct iscsi_iser_conn *iser_conn = conn->dd_data;

	if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
	    ISER_QP_MAX_REQ_DTOS) {
291 292
		iser_dbg("%ld can't xmit task %p\n",jiffies,task);
		return -ENOBUFS;
293
	}
294
	return 0;
295 296 297 298 299 300
}


/**
 * iser_send_command - send command PDU
 */
301
int iser_send_command(struct iscsi_conn *conn,
302
		      struct iscsi_task *task)
303 304
{
	struct iscsi_iser_conn *iser_conn = conn->dd_data;
305
	struct iscsi_iser_task *iser_task = task->dd_data;
306 307
	struct iser_dto *send_dto = NULL;
	unsigned long edtl;
308
	int err;
309
	struct iser_data_buf *data_buf;
310
	struct iscsi_cmd *hdr =  (struct iscsi_cmd *)task->hdr;
311
	struct scsi_cmnd *sc  =  task->sc;
312 313 314 315 316

	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;
	}
317
	if (iser_check_xmit(conn, task))
318
		return -ENOBUFS;
319 320 321 322

	edtl = ntohl(hdr->data_length);

	/* build the tx desc regd header and add it to the tx desc dto */
323 324 325 326
	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);
327 328

	if (hdr->flags & ISCSI_FLAG_CMD_READ)
329
		data_buf = &iser_task->data[ISER_DIR_IN];
330
	else
331
		data_buf = &iser_task->data[ISER_DIR_OUT];
332

333 334 335
	if (scsi_sg_count(sc)) { /* using a scatter list */
		data_buf->buf  = scsi_sglist(sc);
		data_buf->size = scsi_sg_count(sc);
336 337
	}

338
	data_buf->data_len = scsi_bufflen(sc);
339 340

	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
341
		err = iser_prepare_read_cmd(task, edtl);
342 343 344 345
		if (err)
			goto send_command_error;
	}
	if (hdr->flags & ISCSI_FLAG_CMD_WRITE) {
346 347 348
		err = iser_prepare_write_cmd(task,
					     task->imm_count,
				             task->imm_count +
349
					     task->unsol_r2t.data_length,
350 351 352 353 354 355 356 357
					     edtl);
		if (err)
			goto send_command_error;
	}

	iser_reg_single(iser_conn->ib_conn->device,
			send_dto->regd[0], DMA_TO_DEVICE);

358
	iser_task->status = ISER_TASK_STATUS_STARTED;
359

360
	err = iser_post_send(&iser_task->desc);
361 362 363 364 365
	if (!err)
		return 0;

send_command_error:
	iser_dto_buffs_release(send_dto);
366
	iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
367 368 369 370 371 372
	return err;
}

/**
 * iser_send_data_out - send data out PDU
 */
373
int iser_send_data_out(struct iscsi_conn *conn,
374
		       struct iscsi_task *task,
375 376 377
		       struct iscsi_data *hdr)
{
	struct iscsi_iser_conn *iser_conn = conn->dd_data;
378
	struct iscsi_iser_task *iser_task = task->dd_data;
379 380 381 382
	struct iser_desc *tx_desc = NULL;
	struct iser_dto *send_dto = NULL;
	unsigned long buf_offset;
	unsigned long data_seg_len;
383
	uint32_t itt;
384 385 386 387 388 389 390
	int err = 0;

	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;
	}

391
	if (iser_check_xmit(conn, task))
392
		return -ENOBUFS;
393

394
	itt = (__force uint32_t)hdr->itt;
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
	data_seg_len = ntoh24(hdr->dlength);
	buf_offset   = ntohl(hdr->offset);

	iser_dbg("%s itt %d dseg_len %d offset %d\n",
		 __func__,(int)itt,(int)data_seg_len,(int)buf_offset);

	tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
	if (tx_desc == NULL) {
		iser_err("Failed to alloc desc for post dataout\n");
		return -ENOMEM;
	}

	tx_desc->type = ISCSI_TX_DATAOUT;
	memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));

	/* build the tx desc regd header and add it to the tx desc dto */
	send_dto = &tx_desc->dto;
412
	send_dto->task = iser_task;
413 414 415 416 417 418 419
	iser_create_send_desc(iser_conn, tx_desc);

	iser_reg_single(iser_conn->ib_conn->device,
			send_dto->regd[0], DMA_TO_DEVICE);

	/* all data was registered for RDMA, we can use the lkey */
	iser_dto_add_regd_buff(send_dto,
420
			       &iser_task->rdma_regd[ISER_DIR_OUT],
421 422 423
			       buf_offset,
			       data_seg_len);

424
	if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
425 426 427
		iser_err("Offset:%ld & DSL:%ld in Data-Out "
			 "inconsistent with total len:%ld, itt:%d\n",
			 buf_offset, data_seg_len,
428
			 iser_task->data[ISER_DIR_OUT].data_len, itt);
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
		err = -EINVAL;
		goto send_data_out_error;
	}
	iser_dbg("data-out itt: %d, offset: %ld, sz: %ld\n",
		 itt, buf_offset, data_seg_len);


	err = iser_post_send(tx_desc);
	if (!err)
		return 0;

send_data_out_error:
	iser_dto_buffs_release(send_dto);
	kmem_cache_free(ig.desc_cache, tx_desc);
	iser_err("conn %p failed err %d\n",conn, err);
	return err;
}

int iser_send_control(struct iscsi_conn *conn,
448
		      struct iscsi_task *task)
449 450
{
	struct iscsi_iser_conn *iser_conn = conn->dd_data;
451 452
	struct iscsi_iser_task *iser_task = task->dd_data;
	struct iser_desc *mdesc = &iser_task->desc;
453 454
	struct iser_dto *send_dto = NULL;
	unsigned long data_seg_len;
455
	int err;
456 457 458 459 460 461 462 463
	struct iser_regd_buf *regd_buf;
	struct iser_device *device;

	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;
	}

464
	if (iser_check_xmit(conn, task))
465
		return -ENOBUFS;
466 467 468 469

	/* build the tx desc regd header and add it to the tx desc dto */
	mdesc->type = ISCSI_TX_CONTROL;
	send_dto = &mdesc->dto;
470
	send_dto->task = NULL;
471 472 473 474 475 476
	iser_create_send_desc(iser_conn, mdesc);

	device = iser_conn->ib_conn->device;

	iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);

477
	data_seg_len = ntoh24(task->hdr->dlength);
478 479 480 481 482

	if (data_seg_len > 0) {
		regd_buf = &mdesc->data_regd_buf;
		memset(regd_buf, 0, sizeof(struct iser_regd_buf));
		regd_buf->device = device;
483 484
		regd_buf->virt_addr = task->data;
		regd_buf->data_size = task->data_count;
485 486 487 488 489 490 491
		iser_reg_single(device, regd_buf,
				DMA_TO_DEVICE);
		iser_dto_add_regd_buff(send_dto, regd_buf,
				       0,
				       data_seg_len);
	}

492 493 494 495
	if (task == conn->login_task) {
		err = iser_post_recvl(iser_conn->ib_conn);
		if (err)
			goto send_control_error;
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
	}

	err = iser_post_send(mdesc);
	if (!err)
		return 0;

send_control_error:
	iser_dto_buffs_release(send_dto);
	iser_err("conn %p failed err %d\n",conn, err);
	return err;
}

/**
 * iser_rcv_dto_completion - recv DTO completion
 */
511 512 513
void iser_rcv_completion(struct iser_rx_desc *rx_desc,
			 unsigned long rx_xfer_len,
			 struct iser_conn *ib_conn)
514
{
515
	struct iscsi_iser_conn *conn = ib_conn->iser_conn;
516 517
	struct iscsi_task *task;
	struct iscsi_iser_task *iser_task;
518 519
	struct iscsi_hdr *hdr;
	unsigned char opcode;
520 521 522 523 524 525 526 527 528 529 530
	u64 rx_dma;
	int rx_buflen, outstanding, count, err;

	/* differentiate between login to all other PDUs */
	if ((char *)rx_desc == ib_conn->login_buf) {
		rx_dma = ib_conn->login_dma;
		rx_buflen = ISER_RX_LOGIN_SIZE;
	} else {
		rx_dma = rx_desc->dma_addr;
		rx_buflen = ISER_RX_PAYLOAD_SIZE;
	}
531

532 533
	ib_dma_sync_single_for_cpu(ib_conn->device->ib_device, rx_dma,
			rx_buflen, DMA_FROM_DEVICE);
534

535
	hdr = &rx_desc->iscsi_header;
536

537 538
	iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
			hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
539 540 541 542

	opcode = hdr->opcode & ISCSI_OPCODE_MASK;

	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
543
		spin_lock(&conn->iscsi_conn->session->lock);
544
		task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
545 546 547 548
		if (task)
			__iscsi_get_task(task);
		spin_unlock(&conn->iscsi_conn->session->lock);

549
		if (!task)
550
			iser_err("itt can't be matched to task!!! "
551 552 553
				 "conn %p opcode %d itt %d\n",
				 conn->iscsi_conn, opcode, hdr->itt);
		else {
554 555 556 557
			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);
558
			iscsi_put_task(task);
559
		}
560 561
	}

562 563
	iscsi_iser_recv(conn->iscsi_conn, hdr,
		rx_desc->data, rx_xfer_len - ISER_HEADERS_LEN);
564

565 566
	ib_dma_sync_single_for_device(ib_conn->device->ib_device, rx_dma,
			rx_buflen, DMA_FROM_DEVICE);
567 568 569 570 571

	/* decrementing conn->post_recv_buf_count only --after-- freeing the   *
	 * task eliminates the need to worry on tasks which are completed in   *
	 * parallel to the execution of iser_conn_term. So the code that waits *
	 * for the posted rx bufs refcount to become zero handles everything   */
572
	conn->ib_conn->post_recv_buf_count--;
573 574 575 576

	if (rx_dma == ib_conn->login_dma)
		return;

577
	outstanding = ib_conn->post_recv_buf_count;
578 579 580 581 582 583 584
	if (outstanding + ISER_MIN_POSTED_RX <= ISER_QP_MAX_RECV_DTOS) {
		count = min(ISER_QP_MAX_RECV_DTOS - outstanding,
						ISER_MIN_POSTED_RX);
		err = iser_post_recvm(ib_conn, count);
		if (err)
			iser_err("posting %d rx bufs err %d\n", count, err);
	}
585 586 587 588 589
}

void iser_snd_completion(struct iser_desc *tx_desc)
{
	struct iser_dto        *dto = &tx_desc->dto;
590 591
	struct iser_conn       *ib_conn = dto->ib_conn;
	struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
592
	struct iscsi_conn      *conn = iser_conn->iscsi_conn;
593
	struct iscsi_task *task;
594
	int resume_tx = 0;
595 596 597 598 599 600 601 602

	iser_dbg("Initiator, Data sent dto=0x%p\n", dto);

	iser_dto_buffs_release(dto);

	if (tx_desc->type == ISCSI_TX_DATAOUT)
		kmem_cache_free(ig.desc_cache, tx_desc);

603 604 605 606
	if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
	    ISER_QP_MAX_REQ_DTOS)
		resume_tx = 1;

607
	atomic_dec(&ib_conn->post_send_buf_count);
608

609
	if (resume_tx) {
610
		iser_dbg("%ld resuming tx\n",jiffies);
611
		iscsi_conn_queue_work(conn);
612 613 614 615
	}

	if (tx_desc->type == ISCSI_TX_CONTROL) {
		/* this arithmetic is legal by libiscsi dd_data allocation */
616 617 618 619
		task = (void *) ((long)(void *)tx_desc -
				  sizeof(struct iscsi_task));
		if (task->hdr->itt == RESERVED_ITT)
			iscsi_put_task(task);
620 621 622
	}
}

623
void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
624 625

{
626
	iser_task->status = ISER_TASK_STATUS_INIT;
627

628 629
	iser_task->dir[ISER_DIR_IN] = 0;
	iser_task->dir[ISER_DIR_OUT] = 0;
630

631 632
	iser_task->data[ISER_DIR_IN].data_len  = 0;
	iser_task->data[ISER_DIR_OUT].data_len = 0;
633

634
	memset(&iser_task->rdma_regd[ISER_DIR_IN], 0,
635
	       sizeof(struct iser_regd_buf));
636
	memset(&iser_task->rdma_regd[ISER_DIR_OUT], 0,
637 638 639
	       sizeof(struct iser_regd_buf));
}

640
void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
641 642
{
	int deferred;
643
	int is_rdma_aligned = 1;
644
	struct iser_regd_buf *regd;
645 646 647 648

	/* if we were reading, copy back to unaligned sglist,
	 * anyway dma_unmap and free the copy
	 */
649
	if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) {
650
		is_rdma_aligned = 0;
651
		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN);
652
	}
653
	if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
654
		is_rdma_aligned = 0;
655
		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT);
656
	}
657

658 659
	if (iser_task->dir[ISER_DIR_IN]) {
		regd = &iser_task->rdma_regd[ISER_DIR_IN];
660
		deferred = iser_regd_buff_release(regd);
661
		if (deferred) {
662 663
			iser_err("%d references remain for BUF-IN rdma reg\n",
				 atomic_read(&regd->ref_count));
664 665 666
		}
	}

667 668
	if (iser_task->dir[ISER_DIR_OUT]) {
		regd = &iser_task->rdma_regd[ISER_DIR_OUT];
669
		deferred = iser_regd_buff_release(regd);
670
		if (deferred) {
671 672
			iser_err("%d references remain for BUF-OUT rdma reg\n",
				 atomic_read(&regd->ref_count));
673 674 675
		}
	}

676 677
       /* if the data was unaligned, it was already unmapped and then copied */
       if (is_rdma_aligned)
678
		iser_dma_unmap_task_data(iser_task);
679 680 681 682 683 684 685 686 687 688
}

void iser_dto_buffs_release(struct iser_dto *dto)
{
	int i;

	for (i = 0; i < dto->regd_vector_len; i++)
		iser_regd_buff_release(dto->regd[i]);
}