diff options
author | Or Gerlitz <ogerlitz@voltaire.com> | 2010-02-08 08:19:56 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-02-24 12:41:12 -0500 |
commit | f19624aa92003969ba822cd3c552800965aa530b (patch) | |
tree | 0ee572198ce21da332b9fe25fde7bbe8d8a7cb98 /drivers/infiniband | |
parent | 78ad0a34dc138047529058c5f2265664cb70a052 (diff) |
IB/iser: Simplify send flow/descriptors
Simplify and shrink the logic/code used for the send descriptors.
Changes include removing struct iser_dto (an unnecessary abstraction),
using struct iser_regd_buf only for handling SCSI commands, using
dma_sync instead of dma_map/unmap, etc.
Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 34 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 48 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 176 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_memory.c | 60 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 75 |
5 files changed, 115 insertions, 278 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 355470e7e904..331147b71a91 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -128,6 +128,28 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode) | |||
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | int iser_initialize_task_headers(struct iscsi_task *task, | ||
132 | struct iser_tx_desc *tx_desc) | ||
133 | { | ||
134 | struct iscsi_iser_conn *iser_conn = task->conn->dd_data; | ||
135 | struct iser_device *device = iser_conn->ib_conn->device; | ||
136 | struct iscsi_iser_task *iser_task = task->dd_data; | ||
137 | u64 dma_addr; | ||
138 | |||
139 | dma_addr = ib_dma_map_single(device->ib_device, (void *)tx_desc, | ||
140 | ISER_HEADERS_LEN, DMA_TO_DEVICE); | ||
141 | if (ib_dma_mapping_error(device->ib_device, dma_addr)) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | tx_desc->dma_addr = dma_addr; | ||
145 | tx_desc->tx_sg[0].addr = tx_desc->dma_addr; | ||
146 | tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; | ||
147 | tx_desc->tx_sg[0].lkey = device->mr->lkey; | ||
148 | |||
149 | iser_task->headers_initialized = 1; | ||
150 | iser_task->iser_conn = iser_conn; | ||
151 | return 0; | ||
152 | } | ||
131 | /** | 153 | /** |
132 | * iscsi_iser_task_init - Initialize task | 154 | * iscsi_iser_task_init - Initialize task |
133 | * @task: iscsi task | 155 | * @task: iscsi task |
@@ -137,17 +159,17 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode) | |||
137 | static int | 159 | static int |
138 | iscsi_iser_task_init(struct iscsi_task *task) | 160 | iscsi_iser_task_init(struct iscsi_task *task) |
139 | { | 161 | { |
140 | struct iscsi_iser_conn *iser_conn = task->conn->dd_data; | ||
141 | struct iscsi_iser_task *iser_task = task->dd_data; | 162 | struct iscsi_iser_task *iser_task = task->dd_data; |
142 | 163 | ||
164 | if (!iser_task->headers_initialized) | ||
165 | if (iser_initialize_task_headers(task, &iser_task->desc)) | ||
166 | return -ENOMEM; | ||
167 | |||
143 | /* mgmt task */ | 168 | /* mgmt task */ |
144 | if (!task->sc) { | 169 | if (!task->sc) |
145 | iser_task->desc.data = task->data; | ||
146 | return 0; | 170 | return 0; |
147 | } | ||
148 | 171 | ||
149 | iser_task->command_sent = 0; | 172 | iser_task->command_sent = 0; |
150 | iser_task->iser_conn = iser_conn; | ||
151 | iser_task_rdma_init(iser_task); | 173 | iser_task_rdma_init(iser_task); |
152 | return 0; | 174 | return 0; |
153 | } | 175 | } |
@@ -675,7 +697,7 @@ static int __init iser_init(void) | |||
675 | memset(&ig, 0, sizeof(struct iser_global)); | 697 | memset(&ig, 0, sizeof(struct iser_global)); |
676 | 698 | ||
677 | ig.desc_cache = kmem_cache_create("iser_descriptors", | 699 | ig.desc_cache = kmem_cache_create("iser_descriptors", |
678 | sizeof (struct iser_desc), | 700 | sizeof(struct iser_tx_desc), |
679 | 0, SLAB_HWCACHE_ALIGN, | 701 | 0, SLAB_HWCACHE_ALIGN, |
680 | NULL); | 702 | NULL); |
681 | if (ig.desc_cache == NULL) | 703 | if (ig.desc_cache == NULL) |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index a314576be4bf..269f23f1b6d1 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -193,28 +193,8 @@ struct iser_regd_buf { | |||
193 | struct iser_mem_reg reg; /* memory registration info */ | 193 | struct iser_mem_reg reg; /* memory registration info */ |
194 | void *virt_addr; | 194 | void *virt_addr; |
195 | struct iser_device *device; /* device->device for dma_unmap */ | 195 | struct iser_device *device; /* device->device for dma_unmap */ |
196 | u64 dma_addr; /* if non zero, addr for dma_unmap */ | ||
197 | enum dma_data_direction direction; /* direction for dma_unmap */ | 196 | enum dma_data_direction direction; /* direction for dma_unmap */ |
198 | unsigned int data_size; | 197 | unsigned int data_size; |
199 | atomic_t ref_count; /* refcount, freed when dec to 0 */ | ||
200 | }; | ||
201 | |||
202 | #define MAX_REGD_BUF_VECTOR_LEN 2 | ||
203 | |||
204 | struct iser_dto { | ||
205 | struct iscsi_iser_task *task; | ||
206 | struct iser_conn *ib_conn; | ||
207 | int notify_enable; | ||
208 | |||
209 | /* vector of registered buffers */ | ||
210 | unsigned int regd_vector_len; | ||
211 | struct iser_regd_buf *regd[MAX_REGD_BUF_VECTOR_LEN]; | ||
212 | |||
213 | /* offset into the registered buffer may be specified */ | ||
214 | unsigned int offset[MAX_REGD_BUF_VECTOR_LEN]; | ||
215 | |||
216 | /* a smaller size may be specified, if 0, then full size is used */ | ||
217 | unsigned int used_sz[MAX_REGD_BUF_VECTOR_LEN]; | ||
218 | }; | 198 | }; |
219 | 199 | ||
220 | enum iser_desc_type { | 200 | enum iser_desc_type { |
@@ -223,14 +203,15 @@ enum iser_desc_type { | |||
223 | ISCSI_TX_DATAOUT | 203 | ISCSI_TX_DATAOUT |
224 | }; | 204 | }; |
225 | 205 | ||
226 | struct iser_desc { | 206 | struct iser_tx_desc { |
227 | struct iser_hdr iser_header; | 207 | struct iser_hdr iser_header; |
228 | struct iscsi_hdr iscsi_header; | 208 | struct iscsi_hdr iscsi_header; |
229 | struct iser_regd_buf hdr_regd_buf; | ||
230 | void *data; /* used by RX & TX_CONTROL */ | ||
231 | struct iser_regd_buf data_regd_buf; /* used by RX & TX_CONTROL */ | ||
232 | enum iser_desc_type type; | 209 | enum iser_desc_type type; |
233 | struct iser_dto dto; | 210 | u64 dma_addr; |
211 | /* sg[0] points to iser/iscsi headers, sg[1] optionally points to either | ||
212 | of immediate data, unsolicited data-out or control (login,text) */ | ||
213 | struct ib_sge tx_sg[2]; | ||
214 | int num_sge; | ||
234 | }; | 215 | }; |
235 | 216 | ||
236 | #define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \ | 217 | #define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \ |
@@ -287,7 +268,7 @@ struct iscsi_iser_conn { | |||
287 | }; | 268 | }; |
288 | 269 | ||
289 | struct iscsi_iser_task { | 270 | struct iscsi_iser_task { |
290 | struct iser_desc desc; | 271 | struct iser_tx_desc desc; |
291 | struct iscsi_iser_conn *iser_conn; | 272 | struct iscsi_iser_conn *iser_conn; |
292 | enum iser_task_status status; | 273 | enum iser_task_status status; |
293 | int command_sent; /* set if command sent */ | 274 | int command_sent; /* set if command sent */ |
@@ -295,6 +276,7 @@ struct iscsi_iser_task { | |||
295 | struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ | 276 | struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ |
296 | struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ | 277 | struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ |
297 | struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ | 278 | struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ |
279 | int headers_initialized; | ||
298 | }; | 280 | }; |
299 | 281 | ||
300 | struct iser_page_vec { | 282 | struct iser_page_vec { |
@@ -346,22 +328,14 @@ void iser_rcv_completion(struct iser_rx_desc *desc, | |||
346 | unsigned long dto_xfer_len, | 328 | unsigned long dto_xfer_len, |
347 | struct iser_conn *ib_conn); | 329 | struct iser_conn *ib_conn); |
348 | 330 | ||
349 | void iser_snd_completion(struct iser_desc *desc); | 331 | void iser_snd_completion(struct iser_tx_desc *desc, struct iser_conn *ib_conn); |
350 | 332 | ||
351 | void iser_task_rdma_init(struct iscsi_iser_task *task); | 333 | void iser_task_rdma_init(struct iscsi_iser_task *task); |
352 | 334 | ||
353 | void iser_task_rdma_finalize(struct iscsi_iser_task *task); | 335 | void iser_task_rdma_finalize(struct iscsi_iser_task *task); |
354 | 336 | ||
355 | void iser_dto_buffs_release(struct iser_dto *dto); | ||
356 | |||
357 | int iser_regd_buff_release(struct iser_regd_buf *regd_buf); | ||
358 | |||
359 | void iser_free_rx_descriptors(struct iser_conn *ib_conn); | 337 | void iser_free_rx_descriptors(struct iser_conn *ib_conn); |
360 | 338 | ||
361 | void iser_reg_single(struct iser_device *device, | ||
362 | struct iser_regd_buf *regd_buf, | ||
363 | enum dma_data_direction direction); | ||
364 | |||
365 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task, | 339 | void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task, |
366 | enum iser_data_dir cmd_dir); | 340 | enum iser_data_dir cmd_dir); |
367 | 341 | ||
@@ -381,7 +355,7 @@ void iser_unreg_mem(struct iser_mem_reg *mem_reg); | |||
381 | 355 | ||
382 | int iser_post_recvl(struct iser_conn *ib_conn); | 356 | int iser_post_recvl(struct iser_conn *ib_conn); |
383 | int iser_post_recvm(struct iser_conn *ib_conn, int count); | 357 | int iser_post_recvm(struct iser_conn *ib_conn, int count); |
384 | int iser_post_send(struct iser_desc *tx_desc); | 358 | int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc); |
385 | 359 | ||
386 | int iser_conn_state_comp(struct iser_conn *ib_conn, | 360 | int iser_conn_state_comp(struct iser_conn *ib_conn, |
387 | enum iser_ib_conn_state comp); | 361 | enum iser_ib_conn_state comp); |
@@ -392,4 +366,6 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, | |||
392 | enum dma_data_direction dma_dir); | 366 | enum dma_data_direction dma_dir); |
393 | 367 | ||
394 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); | 368 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); |
369 | int iser_initialize_task_headers(struct iscsi_task *task, | ||
370 | struct iser_tx_desc *tx_desc); | ||
395 | #endif | 371 | #endif |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 3e65a43d2154..3be3a13b5e30 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -39,26 +39,6 @@ | |||
39 | 39 | ||
40 | #include "iscsi_iser.h" | 40 | #include "iscsi_iser.h" |
41 | 41 | ||
42 | |||
43 | /* iser_dto_add_regd_buff - increments the reference count for * | ||
44 | * the registered buffer & adds it to the DTO object */ | ||
45 | static void iser_dto_add_regd_buff(struct iser_dto *dto, | ||
46 | struct iser_regd_buf *regd_buf, | ||
47 | unsigned long use_offset, | ||
48 | unsigned long use_size) | ||
49 | { | ||
50 | int add_idx; | ||
51 | |||
52 | atomic_inc(®d_buf->ref_count); | ||
53 | |||
54 | add_idx = dto->regd_vector_len; | ||
55 | dto->regd[add_idx] = regd_buf; | ||
56 | dto->used_sz[add_idx] = use_size; | ||
57 | dto->offset[add_idx] = use_offset; | ||
58 | |||
59 | dto->regd_vector_len++; | ||
60 | } | ||
61 | |||
62 | /* Register user buffer memory and initialize passive rdma | 42 | /* Register user buffer memory and initialize passive rdma |
63 | * dto descriptor. Total data size is stored in | 43 | * dto descriptor. Total data size is stored in |
64 | * iser_task->data[ISER_DIR_IN].data_len | 44 | * iser_task->data[ISER_DIR_IN].data_len |
@@ -119,9 +99,9 @@ iser_prepare_write_cmd(struct iscsi_task *task, | |||
119 | struct iscsi_iser_task *iser_task = task->dd_data; | 99 | struct iscsi_iser_task *iser_task = task->dd_data; |
120 | struct iser_regd_buf *regd_buf; | 100 | struct iser_regd_buf *regd_buf; |
121 | int err; | 101 | int err; |
122 | struct iser_dto *send_dto = &iser_task->desc.dto; | ||
123 | struct iser_hdr *hdr = &iser_task->desc.iser_header; | 102 | struct iser_hdr *hdr = &iser_task->desc.iser_header; |
124 | struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT]; | 103 | struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT]; |
104 | struct ib_sge *tx_dsg = &iser_task->desc.tx_sg[1]; | ||
125 | 105 | ||
126 | err = iser_dma_map_task_data(iser_task, | 106 | err = iser_dma_map_task_data(iser_task, |
127 | buf_out, | 107 | buf_out, |
@@ -160,37 +140,36 @@ iser_prepare_write_cmd(struct iscsi_task *task, | |||
160 | if (imm_sz > 0) { | 140 | if (imm_sz > 0) { |
161 | iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n", | 141 | iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n", |
162 | task->itt, imm_sz); | 142 | task->itt, imm_sz); |
163 | iser_dto_add_regd_buff(send_dto, | 143 | tx_dsg->addr = regd_buf->reg.va; |
164 | regd_buf, | 144 | tx_dsg->length = imm_sz; |
165 | 0, | 145 | tx_dsg->lkey = regd_buf->reg.lkey; |
166 | imm_sz); | 146 | iser_task->desc.num_sge = 2; |
167 | } | 147 | } |
168 | 148 | ||
169 | return 0; | 149 | return 0; |
170 | } | 150 | } |
171 | 151 | ||
172 | /* creates a new tx descriptor and adds header regd buffer */ | 152 | /* creates a new tx descriptor and adds header regd buffer */ |
173 | static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn, | 153 | static void iser_create_send_desc(struct iser_conn *ib_conn, |
174 | struct iser_desc *tx_desc) | 154 | struct iser_tx_desc *tx_desc) |
175 | { | 155 | { |
176 | struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf; | 156 | struct iser_device *device = ib_conn->device; |
177 | struct iser_dto *send_dto = &tx_desc->dto; | ||
178 | |||
179 | memset(regd_hdr, 0, sizeof(struct iser_regd_buf)); | ||
180 | regd_hdr->device = iser_conn->ib_conn->device; | ||
181 | regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */ | ||
182 | regd_hdr->data_size = ISER_HEADERS_LEN; | ||
183 | 157 | ||
184 | send_dto->ib_conn = iser_conn->ib_conn; | 158 | ib_dma_sync_single_for_cpu(device->ib_device, |
185 | send_dto->notify_enable = 1; | 159 | tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE); |
186 | send_dto->regd_vector_len = 0; | ||
187 | 160 | ||
188 | memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr)); | 161 | memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr)); |
189 | tx_desc->iser_header.flags = ISER_VER; | 162 | tx_desc->iser_header.flags = ISER_VER; |
190 | 163 | ||
191 | iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0); | 164 | tx_desc->num_sge = 1; |
165 | |||
166 | if (tx_desc->tx_sg[0].lkey != device->mr->lkey) { | ||
167 | tx_desc->tx_sg[0].lkey = device->mr->lkey; | ||
168 | iser_dbg("sdesc %p lkey mismatch, fixing\n", tx_desc); | ||
169 | } | ||
192 | } | 170 | } |
193 | 171 | ||
172 | |||
194 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) | 173 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) |
195 | { | 174 | { |
196 | int i, j; | 175 | int i, j; |
@@ -303,12 +282,12 @@ int iser_send_command(struct iscsi_conn *conn, | |||
303 | { | 282 | { |
304 | struct iscsi_iser_conn *iser_conn = conn->dd_data; | 283 | struct iscsi_iser_conn *iser_conn = conn->dd_data; |
305 | struct iscsi_iser_task *iser_task = task->dd_data; | 284 | struct iscsi_iser_task *iser_task = task->dd_data; |
306 | struct iser_dto *send_dto = NULL; | ||
307 | unsigned long edtl; | 285 | unsigned long edtl; |
308 | int err; | 286 | int err; |
309 | struct iser_data_buf *data_buf; | 287 | struct iser_data_buf *data_buf; |
310 | struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr; | 288 | struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr; |
311 | struct scsi_cmnd *sc = task->sc; | 289 | struct scsi_cmnd *sc = task->sc; |
290 | struct iser_tx_desc *tx_desc = &iser_task->desc; | ||
312 | 291 | ||
313 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { | 292 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { |
314 | iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); | 293 | iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); |
@@ -320,10 +299,8 @@ int iser_send_command(struct iscsi_conn *conn, | |||
320 | edtl = ntohl(hdr->data_length); | 299 | edtl = ntohl(hdr->data_length); |
321 | 300 | ||
322 | /* build the tx desc regd header and add it to the tx desc dto */ | 301 | /* build the tx desc regd header and add it to the tx desc dto */ |
323 | iser_task->desc.type = ISCSI_TX_SCSI_COMMAND; | 302 | tx_desc->type = ISCSI_TX_SCSI_COMMAND; |
324 | send_dto = &iser_task->desc.dto; | 303 | iser_create_send_desc(iser_conn->ib_conn, tx_desc); |
325 | send_dto->task = iser_task; | ||
326 | iser_create_send_desc(iser_conn, &iser_task->desc); | ||
327 | 304 | ||
328 | if (hdr->flags & ISCSI_FLAG_CMD_READ) | 305 | if (hdr->flags & ISCSI_FLAG_CMD_READ) |
329 | data_buf = &iser_task->data[ISER_DIR_IN]; | 306 | data_buf = &iser_task->data[ISER_DIR_IN]; |
@@ -352,17 +329,13 @@ int iser_send_command(struct iscsi_conn *conn, | |||
352 | goto send_command_error; | 329 | goto send_command_error; |
353 | } | 330 | } |
354 | 331 | ||
355 | iser_reg_single(iser_conn->ib_conn->device, | ||
356 | send_dto->regd[0], DMA_TO_DEVICE); | ||
357 | |||
358 | iser_task->status = ISER_TASK_STATUS_STARTED; | 332 | iser_task->status = ISER_TASK_STATUS_STARTED; |
359 | 333 | ||
360 | err = iser_post_send(&iser_task->desc); | 334 | err = iser_post_send(iser_conn->ib_conn, tx_desc); |
361 | if (!err) | 335 | if (!err) |
362 | return 0; | 336 | return 0; |
363 | 337 | ||
364 | send_command_error: | 338 | send_command_error: |
365 | iser_dto_buffs_release(send_dto); | ||
366 | iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err); | 339 | iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err); |
367 | return err; | 340 | return err; |
368 | } | 341 | } |
@@ -376,12 +349,14 @@ int iser_send_data_out(struct iscsi_conn *conn, | |||
376 | { | 349 | { |
377 | struct iscsi_iser_conn *iser_conn = conn->dd_data; | 350 | struct iscsi_iser_conn *iser_conn = conn->dd_data; |
378 | struct iscsi_iser_task *iser_task = task->dd_data; | 351 | struct iscsi_iser_task *iser_task = task->dd_data; |
379 | struct iser_desc *tx_desc = NULL; | 352 | struct iser_tx_desc *tx_desc = NULL; |
380 | struct iser_dto *send_dto = NULL; | 353 | struct iser_regd_buf *regd_buf; |
381 | unsigned long buf_offset; | 354 | unsigned long buf_offset; |
382 | unsigned long data_seg_len; | 355 | unsigned long data_seg_len; |
383 | uint32_t itt; | 356 | uint32_t itt; |
384 | int err = 0; | 357 | int err = 0; |
358 | struct ib_sge *tx_dsg; | ||
359 | |||
385 | 360 | ||
386 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { | 361 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { |
387 | iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); | 362 | iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); |
@@ -398,28 +373,25 @@ int iser_send_data_out(struct iscsi_conn *conn, | |||
398 | iser_dbg("%s itt %d dseg_len %d offset %d\n", | 373 | iser_dbg("%s itt %d dseg_len %d offset %d\n", |
399 | __func__,(int)itt,(int)data_seg_len,(int)buf_offset); | 374 | __func__,(int)itt,(int)data_seg_len,(int)buf_offset); |
400 | 375 | ||
401 | tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO); | 376 | tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_NOIO); |
402 | if (tx_desc == NULL) { | 377 | if (tx_desc == NULL) { |
403 | iser_err("Failed to alloc desc for post dataout\n"); | 378 | iser_err("Failed to alloc desc for post dataout\n"); |
404 | return -ENOMEM; | 379 | return -ENOMEM; |
405 | } | 380 | } |
406 | 381 | ||
407 | tx_desc->type = ISCSI_TX_DATAOUT; | 382 | tx_desc->type = ISCSI_TX_DATAOUT; |
383 | tx_desc->iser_header.flags = ISER_VER; | ||
408 | memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); | 384 | memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); |
409 | 385 | ||
410 | /* build the tx desc regd header and add it to the tx desc dto */ | 386 | /* build the tx desc */ |
411 | send_dto = &tx_desc->dto; | 387 | iser_initialize_task_headers(task, tx_desc); |
412 | send_dto->task = iser_task; | ||
413 | iser_create_send_desc(iser_conn, tx_desc); | ||
414 | |||
415 | iser_reg_single(iser_conn->ib_conn->device, | ||
416 | send_dto->regd[0], DMA_TO_DEVICE); | ||
417 | 388 | ||
418 | /* all data was registered for RDMA, we can use the lkey */ | 389 | regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT]; |
419 | iser_dto_add_regd_buff(send_dto, | 390 | tx_dsg = &tx_desc->tx_sg[1]; |
420 | &iser_task->rdma_regd[ISER_DIR_OUT], | 391 | tx_dsg->addr = regd_buf->reg.va + buf_offset; |
421 | buf_offset, | 392 | tx_dsg->length = data_seg_len; |
422 | data_seg_len); | 393 | tx_dsg->lkey = regd_buf->reg.lkey; |
394 | tx_desc->num_sge = 2; | ||
423 | 395 | ||
424 | if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) { | 396 | if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) { |
425 | iser_err("Offset:%ld & DSL:%ld in Data-Out " | 397 | iser_err("Offset:%ld & DSL:%ld in Data-Out " |
@@ -433,12 +405,11 @@ int iser_send_data_out(struct iscsi_conn *conn, | |||
433 | itt, buf_offset, data_seg_len); | 405 | itt, buf_offset, data_seg_len); |
434 | 406 | ||
435 | 407 | ||
436 | err = iser_post_send(tx_desc); | 408 | err = iser_post_send(iser_conn->ib_conn, tx_desc); |
437 | if (!err) | 409 | if (!err) |
438 | return 0; | 410 | return 0; |
439 | 411 | ||
440 | send_data_out_error: | 412 | send_data_out_error: |
441 | iser_dto_buffs_release(send_dto); | ||
442 | kmem_cache_free(ig.desc_cache, tx_desc); | 413 | kmem_cache_free(ig.desc_cache, tx_desc); |
443 | iser_err("conn %p failed err %d\n",conn, err); | 414 | iser_err("conn %p failed err %d\n",conn, err); |
444 | return err; | 415 | return err; |
@@ -449,11 +420,9 @@ int iser_send_control(struct iscsi_conn *conn, | |||
449 | { | 420 | { |
450 | struct iscsi_iser_conn *iser_conn = conn->dd_data; | 421 | struct iscsi_iser_conn *iser_conn = conn->dd_data; |
451 | struct iscsi_iser_task *iser_task = task->dd_data; | 422 | struct iscsi_iser_task *iser_task = task->dd_data; |
452 | struct iser_desc *mdesc = &iser_task->desc; | 423 | struct iser_tx_desc *mdesc = &iser_task->desc; |
453 | struct iser_dto *send_dto = NULL; | ||
454 | unsigned long data_seg_len; | 424 | unsigned long data_seg_len; |
455 | int err; | 425 | int err = 0; |
456 | struct iser_regd_buf *regd_buf; | ||
457 | struct iser_device *device; | 426 | struct iser_device *device; |
458 | 427 | ||
459 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { | 428 | if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { |
@@ -466,27 +435,24 @@ int iser_send_control(struct iscsi_conn *conn, | |||
466 | 435 | ||
467 | /* build the tx desc regd header and add it to the tx desc dto */ | 436 | /* build the tx desc regd header and add it to the tx desc dto */ |
468 | mdesc->type = ISCSI_TX_CONTROL; | 437 | mdesc->type = ISCSI_TX_CONTROL; |
469 | send_dto = &mdesc->dto; | 438 | iser_create_send_desc(iser_conn->ib_conn, mdesc); |
470 | send_dto->task = NULL; | ||
471 | iser_create_send_desc(iser_conn, mdesc); | ||
472 | 439 | ||
473 | device = iser_conn->ib_conn->device; | 440 | device = iser_conn->ib_conn->device; |
474 | 441 | ||
475 | iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE); | ||
476 | |||
477 | data_seg_len = ntoh24(task->hdr->dlength); | 442 | data_seg_len = ntoh24(task->hdr->dlength); |
478 | 443 | ||
479 | if (data_seg_len > 0) { | 444 | if (data_seg_len > 0) { |
480 | regd_buf = &mdesc->data_regd_buf; | 445 | struct ib_sge *tx_dsg = &mdesc->tx_sg[1]; |
481 | memset(regd_buf, 0, sizeof(struct iser_regd_buf)); | 446 | if (task != conn->login_task) { |
482 | regd_buf->device = device; | 447 | iser_err("data present on non login task!!!\n"); |
483 | regd_buf->virt_addr = task->data; | 448 | goto send_control_error; |
484 | regd_buf->data_size = task->data_count; | 449 | } |
485 | iser_reg_single(device, regd_buf, | 450 | memcpy(iser_conn->ib_conn->login_buf, task->data, |
486 | DMA_TO_DEVICE); | 451 | task->data_count); |
487 | iser_dto_add_regd_buff(send_dto, regd_buf, | 452 | tx_dsg->addr = iser_conn->ib_conn->login_dma; |
488 | 0, | 453 | tx_dsg->length = data_seg_len; |
489 | data_seg_len); | 454 | tx_dsg->lkey = device->mr->lkey; |
455 | mdesc->num_sge = 2; | ||
490 | } | 456 | } |
491 | 457 | ||
492 | if (task == conn->login_task) { | 458 | if (task == conn->login_task) { |
@@ -495,12 +461,11 @@ int iser_send_control(struct iscsi_conn *conn, | |||
495 | goto send_control_error; | 461 | goto send_control_error; |
496 | } | 462 | } |
497 | 463 | ||
498 | err = iser_post_send(mdesc); | 464 | err = iser_post_send(iser_conn->ib_conn, mdesc); |
499 | if (!err) | 465 | if (!err) |
500 | return 0; | 466 | return 0; |
501 | 467 | ||
502 | send_control_error: | 468 | send_control_error: |
503 | iser_dto_buffs_release(send_dto); | ||
504 | iser_err("conn %p failed err %d\n",conn, err); | 469 | iser_err("conn %p failed err %d\n",conn, err); |
505 | return err; | 470 | return err; |
506 | } | 471 | } |
@@ -584,21 +549,20 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc, | |||
584 | } | 549 | } |
585 | } | 550 | } |
586 | 551 | ||
587 | void iser_snd_completion(struct iser_desc *tx_desc) | 552 | void iser_snd_completion(struct iser_tx_desc *tx_desc, |
553 | struct iser_conn *ib_conn) | ||
588 | { | 554 | { |
589 | struct iser_dto *dto = &tx_desc->dto; | ||
590 | struct iser_conn *ib_conn = dto->ib_conn; | ||
591 | struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; | 555 | struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; |
592 | struct iscsi_conn *conn = iser_conn->iscsi_conn; | 556 | struct iscsi_conn *conn = iser_conn->iscsi_conn; |
593 | struct iscsi_task *task; | 557 | struct iscsi_task *task; |
594 | int resume_tx = 0; | 558 | int resume_tx = 0; |
559 | struct iser_device *device = ib_conn->device; | ||
595 | 560 | ||
596 | iser_dbg("Initiator, Data sent dto=0x%p\n", dto); | 561 | if (tx_desc->type == ISCSI_TX_DATAOUT) { |
597 | 562 | ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr, | |
598 | iser_dto_buffs_release(dto); | 563 | ISER_HEADERS_LEN, DMA_TO_DEVICE); |
599 | |||
600 | if (tx_desc->type == ISCSI_TX_DATAOUT) | ||
601 | kmem_cache_free(ig.desc_cache, tx_desc); | 564 | kmem_cache_free(ig.desc_cache, tx_desc); |
565 | } | ||
602 | 566 | ||
603 | if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == | 567 | if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == |
604 | ISER_QP_MAX_REQ_DTOS) | 568 | ISER_QP_MAX_REQ_DTOS) |
@@ -639,7 +603,6 @@ void iser_task_rdma_init(struct iscsi_iser_task *iser_task) | |||
639 | 603 | ||
640 | void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) | 604 | void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) |
641 | { | 605 | { |
642 | int deferred; | ||
643 | int is_rdma_aligned = 1; | 606 | int is_rdma_aligned = 1; |
644 | struct iser_regd_buf *regd; | 607 | struct iser_regd_buf *regd; |
645 | 608 | ||
@@ -657,32 +620,17 @@ void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) | |||
657 | 620 | ||
658 | if (iser_task->dir[ISER_DIR_IN]) { | 621 | if (iser_task->dir[ISER_DIR_IN]) { |
659 | regd = &iser_task->rdma_regd[ISER_DIR_IN]; | 622 | regd = &iser_task->rdma_regd[ISER_DIR_IN]; |
660 | deferred = iser_regd_buff_release(regd); | 623 | if (regd->reg.is_fmr) |
661 | if (deferred) { | 624 | iser_unreg_mem(®d->reg); |
662 | iser_err("%d references remain for BUF-IN rdma reg\n", | ||
663 | atomic_read(®d->ref_count)); | ||
664 | } | ||
665 | } | 625 | } |
666 | 626 | ||
667 | if (iser_task->dir[ISER_DIR_OUT]) { | 627 | if (iser_task->dir[ISER_DIR_OUT]) { |
668 | regd = &iser_task->rdma_regd[ISER_DIR_OUT]; | 628 | regd = &iser_task->rdma_regd[ISER_DIR_OUT]; |
669 | deferred = iser_regd_buff_release(regd); | 629 | if (regd->reg.is_fmr) |
670 | if (deferred) { | 630 | iser_unreg_mem(®d->reg); |
671 | iser_err("%d references remain for BUF-OUT rdma reg\n", | ||
672 | atomic_read(®d->ref_count)); | ||
673 | } | ||
674 | } | 631 | } |
675 | 632 | ||
676 | /* if the data was unaligned, it was already unmapped and then copied */ | 633 | /* if the data was unaligned, it was already unmapped and then copied */ |
677 | if (is_rdma_aligned) | 634 | if (is_rdma_aligned) |
678 | iser_dma_unmap_task_data(iser_task); | 635 | iser_dma_unmap_task_data(iser_task); |
679 | } | 636 | } |
680 | |||
681 | void iser_dto_buffs_release(struct iser_dto *dto) | ||
682 | { | ||
683 | int i; | ||
684 | |||
685 | for (i = 0; i < dto->regd_vector_len; i++) | ||
686 | iser_regd_buff_release(dto->regd[i]); | ||
687 | } | ||
688 | |||
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 274c883ef3ea..5e32e8f1edf5 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -41,62 +41,6 @@ | |||
41 | #define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */ | 41 | #define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */ |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Decrements the reference count for the | ||
45 | * registered buffer & releases it | ||
46 | * | ||
47 | * returns 0 if released, 1 if deferred | ||
48 | */ | ||
49 | int iser_regd_buff_release(struct iser_regd_buf *regd_buf) | ||
50 | { | ||
51 | struct ib_device *dev; | ||
52 | |||
53 | if ((atomic_read(®d_buf->ref_count) == 0) || | ||
54 | atomic_dec_and_test(®d_buf->ref_count)) { | ||
55 | /* if we used the dma mr, unreg is just NOP */ | ||
56 | if (regd_buf->reg.is_fmr) | ||
57 | iser_unreg_mem(®d_buf->reg); | ||
58 | |||
59 | if (regd_buf->dma_addr) { | ||
60 | dev = regd_buf->device->ib_device; | ||
61 | ib_dma_unmap_single(dev, | ||
62 | regd_buf->dma_addr, | ||
63 | regd_buf->data_size, | ||
64 | regd_buf->direction); | ||
65 | } | ||
66 | /* else this regd buf is associated with task which we */ | ||
67 | /* dma_unmap_single/sg later */ | ||
68 | return 0; | ||
69 | } else { | ||
70 | iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf); | ||
71 | return 1; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * iser_reg_single - fills registered buffer descriptor with | ||
77 | * registration information | ||
78 | */ | ||
79 | void iser_reg_single(struct iser_device *device, | ||
80 | struct iser_regd_buf *regd_buf, | ||
81 | enum dma_data_direction direction) | ||
82 | { | ||
83 | u64 dma_addr; | ||
84 | |||
85 | dma_addr = ib_dma_map_single(device->ib_device, | ||
86 | regd_buf->virt_addr, | ||
87 | regd_buf->data_size, direction); | ||
88 | BUG_ON(ib_dma_mapping_error(device->ib_device, dma_addr)); | ||
89 | |||
90 | regd_buf->reg.lkey = device->mr->lkey; | ||
91 | regd_buf->reg.len = regd_buf->data_size; | ||
92 | regd_buf->reg.va = dma_addr; | ||
93 | regd_buf->reg.is_fmr = 0; | ||
94 | |||
95 | regd_buf->dma_addr = dma_addr; | ||
96 | regd_buf->direction = direction; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * iser_start_rdma_unaligned_sg | 44 | * iser_start_rdma_unaligned_sg |
101 | */ | 45 | */ |
102 | static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | 46 | static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, |
@@ -474,9 +418,5 @@ int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task, | |||
474 | return err; | 418 | return err; |
475 | } | 419 | } |
476 | } | 420 | } |
477 | |||
478 | /* take a reference on this regd buf such that it will not be released * | ||
479 | * (eg in send dto completion) before we get the scsi response */ | ||
480 | atomic_inc(®d_buf->ref_count); | ||
481 | return 0; | 421 | return 0; |
482 | } | 422 | } |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 218aa10939a0..18cf65f092e8 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -194,7 +194,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
194 | init_attr.recv_cq = device->rx_cq; | 194 | init_attr.recv_cq = device->rx_cq; |
195 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; | 195 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; |
196 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; | 196 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; |
197 | init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN; | 197 | init_attr.cap.max_send_sge = 2; |
198 | init_attr.cap.max_recv_sge = 1; | 198 | init_attr.cap.max_recv_sge = 1; |
199 | init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 199 | init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
200 | init_attr.qp_type = IB_QPT_RC; | 200 | init_attr.qp_type = IB_QPT_RC; |
@@ -702,85 +702,36 @@ int iser_post_recvm(struct iser_conn *ib_conn, int count) | |||
702 | 702 | ||
703 | 703 | ||
704 | /** | 704 | /** |
705 | * iser_dto_to_iov - builds IOV from a dto descriptor | ||
706 | */ | ||
707 | static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len) | ||
708 | { | ||
709 | int i; | ||
710 | struct ib_sge *sge; | ||
711 | struct iser_regd_buf *regd_buf; | ||
712 | |||
713 | if (dto->regd_vector_len > iov_len) { | ||
714 | iser_err("iov size %d too small for posting dto of len %d\n", | ||
715 | iov_len, dto->regd_vector_len); | ||
716 | BUG(); | ||
717 | } | ||
718 | |||
719 | for (i = 0; i < dto->regd_vector_len; i++) { | ||
720 | sge = &iov[i]; | ||
721 | regd_buf = dto->regd[i]; | ||
722 | |||
723 | sge->addr = regd_buf->reg.va; | ||
724 | sge->length = regd_buf->reg.len; | ||
725 | sge->lkey = regd_buf->reg.lkey; | ||
726 | |||
727 | if (dto->used_sz[i] > 0) /* Adjust size */ | ||
728 | sge->length = dto->used_sz[i]; | ||
729 | |||
730 | /* offset and length should not exceed the regd buf length */ | ||
731 | if (sge->length + dto->offset[i] > regd_buf->reg.len) { | ||
732 | iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:" | ||
733 | "%ld in dto:0x%p [%d], va:0x%08lX\n", | ||
734 | (unsigned long)sge->length, dto->offset[i], | ||
735 | (unsigned long)regd_buf->reg.len, dto, i, | ||
736 | (unsigned long)sge->addr); | ||
737 | BUG(); | ||
738 | } | ||
739 | |||
740 | sge->addr += dto->offset[i]; /* Adjust offset */ | ||
741 | } | ||
742 | } | ||
743 | |||
744 | |||
745 | /** | ||
746 | * iser_start_send - Initiate a Send DTO operation | 705 | * iser_start_send - Initiate a Send DTO operation |
747 | * | 706 | * |
748 | * returns 0 on success, -1 on failure | 707 | * returns 0 on success, -1 on failure |
749 | */ | 708 | */ |
750 | int iser_post_send(struct iser_desc *tx_desc) | 709 | int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc) |
751 | { | 710 | { |
752 | int ib_ret, ret_val = 0; | 711 | int ib_ret; |
753 | struct ib_send_wr send_wr, *send_wr_failed; | 712 | struct ib_send_wr send_wr, *send_wr_failed; |
754 | struct ib_sge iov[MAX_REGD_BUF_VECTOR_LEN]; | ||
755 | struct iser_conn *ib_conn; | ||
756 | struct iser_dto *dto = &tx_desc->dto; | ||
757 | 713 | ||
758 | ib_conn = dto->ib_conn; | 714 | ib_dma_sync_single_for_device(ib_conn->device->ib_device, |
759 | 715 | tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE); | |
760 | iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN); | ||
761 | 716 | ||
762 | send_wr.next = NULL; | 717 | send_wr.next = NULL; |
763 | send_wr.wr_id = (unsigned long)tx_desc; | 718 | send_wr.wr_id = (unsigned long)tx_desc; |
764 | send_wr.sg_list = iov; | 719 | send_wr.sg_list = tx_desc->tx_sg; |
765 | send_wr.num_sge = dto->regd_vector_len; | 720 | send_wr.num_sge = tx_desc->num_sge; |
766 | send_wr.opcode = IB_WR_SEND; | 721 | send_wr.opcode = IB_WR_SEND; |
767 | send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0; | 722 | send_wr.send_flags = IB_SEND_SIGNALED; |
768 | 723 | ||
769 | atomic_inc(&ib_conn->post_send_buf_count); | 724 | atomic_inc(&ib_conn->post_send_buf_count); |
770 | 725 | ||
771 | ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed); | 726 | ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed); |
772 | if (ib_ret) { | 727 | if (ib_ret) { |
773 | iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n", | ||
774 | dto, dto->regd_vector_len); | ||
775 | iser_err("ib_post_send failed, ret:%d\n", ib_ret); | 728 | iser_err("ib_post_send failed, ret:%d\n", ib_ret); |
776 | atomic_dec(&ib_conn->post_send_buf_count); | 729 | atomic_dec(&ib_conn->post_send_buf_count); |
777 | ret_val = -1; | ||
778 | } | 730 | } |
779 | 731 | return ib_ret; | |
780 | return ret_val; | ||
781 | } | 732 | } |
782 | 733 | ||
783 | static void iser_handle_comp_error(struct iser_desc *desc, | 734 | static void iser_handle_comp_error(struct iser_tx_desc *desc, |
784 | struct iser_conn *ib_conn) | 735 | struct iser_conn *ib_conn) |
785 | { | 736 | { |
786 | if (desc && desc->type == ISCSI_TX_DATAOUT) | 737 | if (desc && desc->type == ISCSI_TX_DATAOUT) |
@@ -809,16 +760,16 @@ static int iser_drain_tx_cq(struct iser_device *device) | |||
809 | { | 760 | { |
810 | struct ib_cq *cq = device->tx_cq; | 761 | struct ib_cq *cq = device->tx_cq; |
811 | struct ib_wc wc; | 762 | struct ib_wc wc; |
812 | struct iser_desc *tx_desc; | 763 | struct iser_tx_desc *tx_desc; |
813 | struct iser_conn *ib_conn; | 764 | struct iser_conn *ib_conn; |
814 | int completed_tx = 0; | 765 | int completed_tx = 0; |
815 | 766 | ||
816 | while (ib_poll_cq(cq, 1, &wc) == 1) { | 767 | while (ib_poll_cq(cq, 1, &wc) == 1) { |
817 | tx_desc = (struct iser_desc *) (unsigned long) wc.wr_id; | 768 | tx_desc = (struct iser_tx_desc *) (unsigned long) wc.wr_id; |
818 | ib_conn = wc.qp->qp_context; | 769 | ib_conn = wc.qp->qp_context; |
819 | if (wc.status == IB_WC_SUCCESS) { | 770 | if (wc.status == IB_WC_SUCCESS) { |
820 | if (wc.opcode == IB_WC_SEND) | 771 | if (wc.opcode == IB_WC_SEND) |
821 | iser_snd_completion(tx_desc); | 772 | iser_snd_completion(tx_desc, ib_conn); |
822 | else | 773 | else |
823 | iser_err("expected opcode %d got %d\n", | 774 | iser_err("expected opcode %d got %d\n", |
824 | IB_WC_SEND, wc.opcode); | 775 | IB_WC_SEND, wc.opcode); |