diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/infiniband/ulp/iser | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/infiniband/ulp/iser')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 115 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 22 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 57 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_memory.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 178 |
5 files changed, 128 insertions, 252 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 0ab8c9cc3a7..9c61b9c2c59 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -57,7 +57,6 @@ | |||
57 | #include <linux/scatterlist.h> | 57 | #include <linux/scatterlist.h> |
58 | #include <linux/delay.h> | 58 | #include <linux/delay.h> |
59 | #include <linux/slab.h> | 59 | #include <linux/slab.h> |
60 | #include <linux/module.h> | ||
61 | 60 | ||
62 | #include <net/sock.h> | 61 | #include <net/sock.h> |
63 | 62 | ||
@@ -152,6 +151,7 @@ int iser_initialize_task_headers(struct iscsi_task *task, | |||
152 | tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; | 151 | tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; |
153 | tx_desc->tx_sg[0].lkey = device->mr->lkey; | 152 | tx_desc->tx_sg[0].lkey = device->mr->lkey; |
154 | 153 | ||
154 | iser_task->headers_initialized = 1; | ||
155 | iser_task->iser_conn = iser_conn; | 155 | iser_task->iser_conn = iser_conn; |
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
@@ -166,7 +166,8 @@ iscsi_iser_task_init(struct iscsi_task *task) | |||
166 | { | 166 | { |
167 | struct iscsi_iser_task *iser_task = task->dd_data; | 167 | struct iscsi_iser_task *iser_task = task->dd_data; |
168 | 168 | ||
169 | if (iser_initialize_task_headers(task, &iser_task->desc)) | 169 | if (!iser_task->headers_initialized) |
170 | if (iser_initialize_task_headers(task, &iser_task->desc)) | ||
170 | return -ENOMEM; | 171 | return -ENOMEM; |
171 | 172 | ||
172 | /* mgmt task */ | 173 | /* mgmt task */ |
@@ -277,13 +278,6 @@ iscsi_iser_task_xmit(struct iscsi_task *task) | |||
277 | static void iscsi_iser_cleanup_task(struct iscsi_task *task) | 278 | static void iscsi_iser_cleanup_task(struct iscsi_task *task) |
278 | { | 279 | { |
279 | struct iscsi_iser_task *iser_task = task->dd_data; | 280 | struct iscsi_iser_task *iser_task = task->dd_data; |
280 | struct iser_tx_desc *tx_desc = &iser_task->desc; | ||
281 | |||
282 | struct iscsi_iser_conn *iser_conn = task->conn->dd_data; | ||
283 | struct iser_device *device = iser_conn->ib_conn->device; | ||
284 | |||
285 | ib_dma_unmap_single(device->ib_device, | ||
286 | tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE); | ||
287 | 281 | ||
288 | /* mgmt tasks do not need special cleanup */ | 282 | /* mgmt tasks do not need special cleanup */ |
289 | if (!task->sc) | 283 | if (!task->sc) |
@@ -364,9 +358,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, | |||
364 | } | 358 | } |
365 | ib_conn = ep->dd_data; | 359 | ib_conn = ep->dd_data; |
366 | 360 | ||
367 | if (iser_alloc_rx_descriptors(ib_conn)) | ||
368 | return -ENOMEM; | ||
369 | |||
370 | /* binds the iSER connection retrieved from the previously | 361 | /* binds the iSER connection retrieved from the previously |
371 | * connected ep_handle to the iSCSI layer connection. exchanges | 362 | * connected ep_handle to the iSCSI layer connection. exchanges |
372 | * connection pointers */ | 363 | * connection pointers */ |
@@ -401,6 +392,19 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
401 | iser_conn->ib_conn = NULL; | 392 | iser_conn->ib_conn = NULL; |
402 | } | 393 | } |
403 | 394 | ||
395 | static int | ||
396 | iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) | ||
397 | { | ||
398 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
399 | int err; | ||
400 | |||
401 | err = iser_conn_set_full_featured_mode(conn); | ||
402 | if (err) | ||
403 | return err; | ||
404 | |||
405 | return iscsi_conn_start(cls_conn); | ||
406 | } | ||
407 | |||
404 | static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) | 408 | static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) |
405 | { | 409 | { |
406 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | 410 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); |
@@ -573,9 +577,10 @@ iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
573 | 577 | ||
574 | err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, | 578 | err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, |
575 | non_blocking); | 579 | non_blocking); |
576 | if (err) | 580 | if (err) { |
581 | iscsi_destroy_endpoint(ep); | ||
577 | return ERR_PTR(err); | 582 | return ERR_PTR(err); |
578 | 583 | } | |
579 | return ep; | 584 | return ep; |
580 | } | 585 | } |
581 | 586 | ||
@@ -627,59 +632,6 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep) | |||
627 | iser_conn_terminate(ib_conn); | 632 | iser_conn_terminate(ib_conn); |
628 | } | 633 | } |
629 | 634 | ||
630 | static umode_t iser_attr_is_visible(int param_type, int param) | ||
631 | { | ||
632 | switch (param_type) { | ||
633 | case ISCSI_HOST_PARAM: | ||
634 | switch (param) { | ||
635 | case ISCSI_HOST_PARAM_NETDEV_NAME: | ||
636 | case ISCSI_HOST_PARAM_HWADDRESS: | ||
637 | case ISCSI_HOST_PARAM_INITIATOR_NAME: | ||
638 | return S_IRUGO; | ||
639 | default: | ||
640 | return 0; | ||
641 | } | ||
642 | case ISCSI_PARAM: | ||
643 | switch (param) { | ||
644 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
645 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
646 | case ISCSI_PARAM_HDRDGST_EN: | ||
647 | case ISCSI_PARAM_DATADGST_EN: | ||
648 | case ISCSI_PARAM_CONN_ADDRESS: | ||
649 | case ISCSI_PARAM_CONN_PORT: | ||
650 | case ISCSI_PARAM_EXP_STATSN: | ||
651 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
652 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
653 | case ISCSI_PARAM_PING_TMO: | ||
654 | case ISCSI_PARAM_RECV_TMO: | ||
655 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
656 | case ISCSI_PARAM_MAX_R2T: | ||
657 | case ISCSI_PARAM_IMM_DATA_EN: | ||
658 | case ISCSI_PARAM_FIRST_BURST: | ||
659 | case ISCSI_PARAM_MAX_BURST: | ||
660 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
661 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
662 | case ISCSI_PARAM_TARGET_NAME: | ||
663 | case ISCSI_PARAM_TPGT: | ||
664 | case ISCSI_PARAM_USERNAME: | ||
665 | case ISCSI_PARAM_PASSWORD: | ||
666 | case ISCSI_PARAM_USERNAME_IN: | ||
667 | case ISCSI_PARAM_PASSWORD_IN: | ||
668 | case ISCSI_PARAM_FAST_ABORT: | ||
669 | case ISCSI_PARAM_ABORT_TMO: | ||
670 | case ISCSI_PARAM_LU_RESET_TMO: | ||
671 | case ISCSI_PARAM_TGT_RESET_TMO: | ||
672 | case ISCSI_PARAM_IFACE_NAME: | ||
673 | case ISCSI_PARAM_INITIATOR_NAME: | ||
674 | return S_IRUGO; | ||
675 | default: | ||
676 | return 0; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static struct scsi_host_template iscsi_iser_sht = { | 635 | static struct scsi_host_template iscsi_iser_sht = { |
684 | .module = THIS_MODULE, | 636 | .module = THIS_MODULE, |
685 | .name = "iSCSI Initiator over iSER, v." DRV_VER, | 637 | .name = "iSCSI Initiator over iSER, v." DRV_VER, |
@@ -701,6 +653,32 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
701 | .owner = THIS_MODULE, | 653 | .owner = THIS_MODULE, |
702 | .name = "iser", | 654 | .name = "iser", |
703 | .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T, | 655 | .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T, |
656 | .param_mask = ISCSI_MAX_RECV_DLENGTH | | ||
657 | ISCSI_MAX_XMIT_DLENGTH | | ||
658 | ISCSI_HDRDGST_EN | | ||
659 | ISCSI_DATADGST_EN | | ||
660 | ISCSI_INITIAL_R2T_EN | | ||
661 | ISCSI_MAX_R2T | | ||
662 | ISCSI_IMM_DATA_EN | | ||
663 | ISCSI_FIRST_BURST | | ||
664 | ISCSI_MAX_BURST | | ||
665 | ISCSI_PDU_INORDER_EN | | ||
666 | ISCSI_DATASEQ_INORDER_EN | | ||
667 | ISCSI_CONN_PORT | | ||
668 | ISCSI_CONN_ADDRESS | | ||
669 | ISCSI_EXP_STATSN | | ||
670 | ISCSI_PERSISTENT_PORT | | ||
671 | ISCSI_PERSISTENT_ADDRESS | | ||
672 | ISCSI_TARGET_NAME | ISCSI_TPGT | | ||
673 | ISCSI_USERNAME | ISCSI_PASSWORD | | ||
674 | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | | ||
675 | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | | ||
676 | ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | | ||
677 | ISCSI_PING_TMO | ISCSI_RECV_TMO | | ||
678 | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, | ||
679 | .host_param_mask = ISCSI_HOST_HWADDRESS | | ||
680 | ISCSI_HOST_NETDEV_NAME | | ||
681 | ISCSI_HOST_INITIATOR_NAME, | ||
704 | /* session management */ | 682 | /* session management */ |
705 | .create_session = iscsi_iser_session_create, | 683 | .create_session = iscsi_iser_session_create, |
706 | .destroy_session = iscsi_iser_session_destroy, | 684 | .destroy_session = iscsi_iser_session_destroy, |
@@ -708,12 +686,11 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
708 | .create_conn = iscsi_iser_conn_create, | 686 | .create_conn = iscsi_iser_conn_create, |
709 | .bind_conn = iscsi_iser_conn_bind, | 687 | .bind_conn = iscsi_iser_conn_bind, |
710 | .destroy_conn = iscsi_iser_conn_destroy, | 688 | .destroy_conn = iscsi_iser_conn_destroy, |
711 | .attr_is_visible = iser_attr_is_visible, | ||
712 | .set_param = iscsi_iser_set_param, | 689 | .set_param = iscsi_iser_set_param, |
713 | .get_conn_param = iscsi_conn_get_param, | 690 | .get_conn_param = iscsi_conn_get_param, |
714 | .get_ep_param = iscsi_iser_get_ep_param, | 691 | .get_ep_param = iscsi_iser_get_ep_param, |
715 | .get_session_param = iscsi_session_get_param, | 692 | .get_session_param = iscsi_session_get_param, |
716 | .start_conn = iscsi_conn_start, | 693 | .start_conn = iscsi_iser_conn_start, |
717 | .stop_conn = iscsi_iser_conn_stop, | 694 | .stop_conn = iscsi_iser_conn_stop, |
718 | /* iscsi host params */ | 695 | /* iscsi host params */ |
719 | .get_host_param = iscsi_host_get_param, | 696 | .get_host_param = iscsi_host_get_param, |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index ef7d3be46c3..db6f3ce9f3b 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -177,7 +177,6 @@ struct iser_data_buf { | |||
177 | 177 | ||
178 | /* fwd declarations */ | 178 | /* fwd declarations */ |
179 | struct iser_device; | 179 | struct iser_device; |
180 | struct iser_cq_desc; | ||
181 | struct iscsi_iser_conn; | 180 | struct iscsi_iser_conn; |
182 | struct iscsi_iser_task; | 181 | struct iscsi_iser_task; |
183 | struct iscsi_endpoint; | 182 | struct iscsi_endpoint; |
@@ -227,21 +226,16 @@ struct iser_rx_desc { | |||
227 | char pad[ISER_RX_PAD_SIZE]; | 226 | char pad[ISER_RX_PAD_SIZE]; |
228 | } __attribute__((packed)); | 227 | } __attribute__((packed)); |
229 | 228 | ||
230 | #define ISER_MAX_CQ 4 | ||
231 | |||
232 | struct iser_device { | 229 | struct iser_device { |
233 | struct ib_device *ib_device; | 230 | struct ib_device *ib_device; |
234 | struct ib_pd *pd; | 231 | struct ib_pd *pd; |
235 | struct ib_cq *rx_cq[ISER_MAX_CQ]; | 232 | struct ib_cq *rx_cq; |
236 | struct ib_cq *tx_cq[ISER_MAX_CQ]; | 233 | struct ib_cq *tx_cq; |
237 | struct ib_mr *mr; | 234 | struct ib_mr *mr; |
238 | struct tasklet_struct cq_tasklet[ISER_MAX_CQ]; | 235 | struct tasklet_struct cq_tasklet; |
239 | struct ib_event_handler event_handler; | 236 | struct ib_event_handler event_handler; |
240 | struct list_head ig_list; /* entry in ig devices list */ | 237 | struct list_head ig_list; /* entry in ig devices list */ |
241 | int refcount; | 238 | int refcount; |
242 | int cq_active_qps[ISER_MAX_CQ]; | ||
243 | int cqs_used; | ||
244 | struct iser_cq_desc *cq_desc; | ||
245 | }; | 239 | }; |
246 | 240 | ||
247 | struct iser_conn { | 241 | struct iser_conn { |
@@ -263,8 +257,7 @@ struct iser_conn { | |||
263 | struct list_head conn_list; /* entry in ig conn list */ | 257 | struct list_head conn_list; /* entry in ig conn list */ |
264 | 258 | ||
265 | char *login_buf; | 259 | char *login_buf; |
266 | char *login_req_buf, *login_resp_buf; | 260 | u64 login_dma; |
267 | u64 login_req_dma, login_resp_dma; | ||
268 | unsigned int rx_desc_head; | 261 | unsigned int rx_desc_head; |
269 | struct iser_rx_desc *rx_descs; | 262 | struct iser_rx_desc *rx_descs; |
270 | struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; | 263 | struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; |
@@ -284,6 +277,7 @@ struct iscsi_iser_task { | |||
284 | struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ | 277 | struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ |
285 | struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ | 278 | struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ |
286 | struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ | 279 | struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ |
280 | int headers_initialized; | ||
287 | }; | 281 | }; |
288 | 282 | ||
289 | struct iser_page_vec { | 283 | struct iser_page_vec { |
@@ -293,11 +287,6 @@ struct iser_page_vec { | |||
293 | int data_size; | 287 | int data_size; |
294 | }; | 288 | }; |
295 | 289 | ||
296 | struct iser_cq_desc { | ||
297 | struct iser_device *device; | ||
298 | int cq_index; | ||
299 | }; | ||
300 | |||
301 | struct iser_global { | 290 | struct iser_global { |
302 | struct mutex device_list_mutex;/* */ | 291 | struct mutex device_list_mutex;/* */ |
303 | struct list_head device_list; /* all iSER devices */ | 292 | struct list_head device_list; /* all iSER devices */ |
@@ -377,5 +366,4 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, | |||
377 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); | 366 | void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); |
378 | int iser_initialize_task_headers(struct iscsi_task *task, | 367 | int iser_initialize_task_headers(struct iscsi_task *task, |
379 | struct iser_tx_desc *tx_desc); | 368 | struct iser_tx_desc *tx_desc); |
380 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn); | ||
381 | #endif | 369 | #endif |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index a00ccd1ca33..f299de6b419 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -170,7 +170,7 @@ static void iser_create_send_desc(struct iser_conn *ib_conn, | |||
170 | } | 170 | } |
171 | 171 | ||
172 | 172 | ||
173 | int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) | 173 | static int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) |
174 | { | 174 | { |
175 | int i, j; | 175 | int i, j; |
176 | u64 dma_addr; | 176 | u64 dma_addr; |
@@ -220,6 +220,12 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn) | |||
220 | struct iser_rx_desc *rx_desc; | 220 | struct iser_rx_desc *rx_desc; |
221 | struct iser_device *device = ib_conn->device; | 221 | struct iser_device *device = ib_conn->device; |
222 | 222 | ||
223 | if (ib_conn->login_buf) { | ||
224 | ib_dma_unmap_single(device->ib_device, ib_conn->login_dma, | ||
225 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
226 | kfree(ib_conn->login_buf); | ||
227 | } | ||
228 | |||
223 | if (!ib_conn->rx_descs) | 229 | if (!ib_conn->rx_descs) |
224 | return; | 230 | return; |
225 | 231 | ||
@@ -230,24 +236,23 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn) | |||
230 | kfree(ib_conn->rx_descs); | 236 | kfree(ib_conn->rx_descs); |
231 | } | 237 | } |
232 | 238 | ||
233 | static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) | 239 | /** |
240 | * iser_conn_set_full_featured_mode - (iSER API) | ||
241 | */ | ||
242 | int iser_conn_set_full_featured_mode(struct iscsi_conn *conn) | ||
234 | { | 243 | { |
235 | struct iscsi_iser_conn *iser_conn = conn->dd_data; | 244 | struct iscsi_iser_conn *iser_conn = conn->dd_data; |
236 | 245 | ||
237 | iser_dbg("req op %x flags %x\n", req->opcode, req->flags); | 246 | iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX); |
238 | /* check if this is the last login - going to full feature phase */ | ||
239 | if ((req->flags & ISCSI_FULL_FEATURE_PHASE) != ISCSI_FULL_FEATURE_PHASE) | ||
240 | return 0; | ||
241 | 247 | ||
242 | /* | 248 | /* Check that there is no posted recv or send buffers left - */ |
243 | * Check that there is one posted recv buffer (for the last login | 249 | /* they must be consumed during the login phase */ |
244 | * response) and no posted send buffers left - they must have been | 250 | BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0); |
245 | * consumed during previous login phases. | 251 | BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); |
246 | */ | 252 | |
247 | WARN_ON(iser_conn->ib_conn->post_recv_buf_count != 1); | 253 | if (iser_alloc_rx_descriptors(iser_conn->ib_conn)) |
248 | WARN_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); | 254 | return -ENOMEM; |
249 | 255 | ||
250 | iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX); | ||
251 | /* Initial post receive buffers */ | 256 | /* Initial post receive buffers */ |
252 | if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX)) | 257 | if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX)) |
253 | return -ENOMEM; | 258 | return -ENOMEM; |
@@ -389,7 +394,6 @@ int iser_send_control(struct iscsi_conn *conn, | |||
389 | unsigned long data_seg_len; | 394 | unsigned long data_seg_len; |
390 | int err = 0; | 395 | int err = 0; |
391 | struct iser_device *device; | 396 | struct iser_device *device; |
392 | struct iser_conn *ib_conn = iser_conn->ib_conn; | ||
393 | 397 | ||
394 | /* build the tx desc regd header and add it to the tx desc dto */ | 398 | /* build the tx desc regd header and add it to the tx desc dto */ |
395 | mdesc->type = ISCSI_TX_CONTROL; | 399 | mdesc->type = ISCSI_TX_CONTROL; |
@@ -405,19 +409,9 @@ int iser_send_control(struct iscsi_conn *conn, | |||
405 | iser_err("data present on non login task!!!\n"); | 409 | iser_err("data present on non login task!!!\n"); |
406 | goto send_control_error; | 410 | goto send_control_error; |
407 | } | 411 | } |
408 | 412 | memcpy(iser_conn->ib_conn->login_buf, task->data, | |
409 | ib_dma_sync_single_for_cpu(device->ib_device, | ||
410 | ib_conn->login_req_dma, task->data_count, | ||
411 | DMA_TO_DEVICE); | ||
412 | |||
413 | memcpy(iser_conn->ib_conn->login_req_buf, task->data, | ||
414 | task->data_count); | 413 | task->data_count); |
415 | 414 | tx_dsg->addr = iser_conn->ib_conn->login_dma; | |
416 | ib_dma_sync_single_for_device(device->ib_device, | ||
417 | ib_conn->login_req_dma, task->data_count, | ||
418 | DMA_TO_DEVICE); | ||
419 | |||
420 | tx_dsg->addr = iser_conn->ib_conn->login_req_dma; | ||
421 | tx_dsg->length = task->data_count; | 415 | tx_dsg->length = task->data_count; |
422 | tx_dsg->lkey = device->mr->lkey; | 416 | tx_dsg->lkey = device->mr->lkey; |
423 | mdesc->num_sge = 2; | 417 | mdesc->num_sge = 2; |
@@ -427,9 +421,6 @@ int iser_send_control(struct iscsi_conn *conn, | |||
427 | err = iser_post_recvl(iser_conn->ib_conn); | 421 | err = iser_post_recvl(iser_conn->ib_conn); |
428 | if (err) | 422 | if (err) |
429 | goto send_control_error; | 423 | goto send_control_error; |
430 | err = iser_post_rx_bufs(conn, task->hdr); | ||
431 | if (err) | ||
432 | goto send_control_error; | ||
433 | } | 424 | } |
434 | 425 | ||
435 | err = iser_post_send(iser_conn->ib_conn, mdesc); | 426 | err = iser_post_send(iser_conn->ib_conn, mdesc); |
@@ -454,8 +445,8 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc, | |||
454 | int rx_buflen, outstanding, count, err; | 445 | int rx_buflen, outstanding, count, err; |
455 | 446 | ||
456 | /* differentiate between login to all other PDUs */ | 447 | /* differentiate between login to all other PDUs */ |
457 | if ((char *)rx_desc == ib_conn->login_resp_buf) { | 448 | if ((char *)rx_desc == ib_conn->login_buf) { |
458 | rx_dma = ib_conn->login_resp_dma; | 449 | rx_dma = ib_conn->login_dma; |
459 | rx_buflen = ISER_RX_LOGIN_SIZE; | 450 | rx_buflen = ISER_RX_LOGIN_SIZE; |
460 | } else { | 451 | } else { |
461 | rx_dma = rx_desc->dma_addr; | 452 | rx_dma = rx_desc->dma_addr; |
@@ -482,7 +473,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc, | |||
482 | * for the posted rx bufs refcount to become zero handles everything */ | 473 | * for the posted rx bufs refcount to become zero handles everything */ |
483 | conn->ib_conn->post_recv_buf_count--; | 474 | conn->ib_conn->post_recv_buf_count--; |
484 | 475 | ||
485 | if (rx_dma == ib_conn->login_resp_dma) | 476 | if (rx_dma == ib_conn->login_dma) |
486 | return; | 477 | return; |
487 | 478 | ||
488 | outstanding = ib_conn->post_recv_buf_count; | 479 | outstanding = ib_conn->post_recv_buf_count; |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 2033a928d34..fb88d6896b6 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -73,11 +73,11 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | |||
73 | 73 | ||
74 | p = mem; | 74 | p = mem; |
75 | for_each_sg(sgl, sg, data->size, i) { | 75 | for_each_sg(sgl, sg, data->size, i) { |
76 | from = kmap_atomic(sg_page(sg)); | 76 | from = kmap_atomic(sg_page(sg), KM_USER0); |
77 | memcpy(p, | 77 | memcpy(p, |
78 | from + sg->offset, | 78 | from + sg->offset, |
79 | sg->length); | 79 | sg->length); |
80 | kunmap_atomic(from); | 80 | kunmap_atomic(from, KM_USER0); |
81 | p += sg->length; | 81 | p += sg->length; |
82 | } | 82 | } |
83 | } | 83 | } |
@@ -133,11 +133,11 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, | |||
133 | 133 | ||
134 | p = mem; | 134 | p = mem; |
135 | for_each_sg(sgl, sg, sg_size, i) { | 135 | for_each_sg(sgl, sg, sg_size, i) { |
136 | to = kmap_atomic(sg_page(sg)); | 136 | to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0); |
137 | memcpy(to + sg->offset, | 137 | memcpy(to + sg->offset, |
138 | p, | 138 | p, |
139 | sg->length); | 139 | sg->length); |
140 | kunmap_atomic(to); | 140 | kunmap_atomic(to, KM_SOFTIRQ0); |
141 | p += sg->length; | 141 | p += sg->length; |
142 | } | 142 | } |
143 | } | 143 | } |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 95a49affee4..ede1475bee0 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -70,50 +70,32 @@ static void iser_event_handler(struct ib_event_handler *handler, | |||
70 | */ | 70 | */ |
71 | static int iser_create_device_ib_res(struct iser_device *device) | 71 | static int iser_create_device_ib_res(struct iser_device *device) |
72 | { | 72 | { |
73 | int i, j; | ||
74 | struct iser_cq_desc *cq_desc; | ||
75 | |||
76 | device->cqs_used = min(ISER_MAX_CQ, device->ib_device->num_comp_vectors); | ||
77 | iser_err("using %d CQs, device %s supports %d vectors\n", device->cqs_used, | ||
78 | device->ib_device->name, device->ib_device->num_comp_vectors); | ||
79 | |||
80 | device->cq_desc = kmalloc(sizeof(struct iser_cq_desc) * device->cqs_used, | ||
81 | GFP_KERNEL); | ||
82 | if (device->cq_desc == NULL) | ||
83 | goto cq_desc_err; | ||
84 | cq_desc = device->cq_desc; | ||
85 | |||
86 | device->pd = ib_alloc_pd(device->ib_device); | 73 | device->pd = ib_alloc_pd(device->ib_device); |
87 | if (IS_ERR(device->pd)) | 74 | if (IS_ERR(device->pd)) |
88 | goto pd_err; | 75 | goto pd_err; |
89 | 76 | ||
90 | for (i = 0; i < device->cqs_used; i++) { | 77 | device->rx_cq = ib_create_cq(device->ib_device, |
91 | cq_desc[i].device = device; | 78 | iser_cq_callback, |
92 | cq_desc[i].cq_index = i; | 79 | iser_cq_event_callback, |
80 | (void *)device, | ||
81 | ISER_MAX_RX_CQ_LEN, 0); | ||
82 | if (IS_ERR(device->rx_cq)) | ||
83 | goto rx_cq_err; | ||
93 | 84 | ||
94 | device->rx_cq[i] = ib_create_cq(device->ib_device, | 85 | device->tx_cq = ib_create_cq(device->ib_device, |
95 | iser_cq_callback, | 86 | NULL, iser_cq_event_callback, |
96 | iser_cq_event_callback, | 87 | (void *)device, |
97 | (void *)&cq_desc[i], | 88 | ISER_MAX_TX_CQ_LEN, 0); |
98 | ISER_MAX_RX_CQ_LEN, i); | ||
99 | if (IS_ERR(device->rx_cq[i])) | ||
100 | goto cq_err; | ||
101 | 89 | ||
102 | device->tx_cq[i] = ib_create_cq(device->ib_device, | 90 | if (IS_ERR(device->tx_cq)) |
103 | NULL, iser_cq_event_callback, | 91 | goto tx_cq_err; |
104 | (void *)&cq_desc[i], | ||
105 | ISER_MAX_TX_CQ_LEN, i); | ||
106 | 92 | ||
107 | if (IS_ERR(device->tx_cq[i])) | 93 | if (ib_req_notify_cq(device->rx_cq, IB_CQ_NEXT_COMP)) |
108 | goto cq_err; | 94 | goto cq_arm_err; |
109 | 95 | ||
110 | if (ib_req_notify_cq(device->rx_cq[i], IB_CQ_NEXT_COMP)) | 96 | tasklet_init(&device->cq_tasklet, |
111 | goto cq_err; | 97 | iser_cq_tasklet_fn, |
112 | 98 | (unsigned long)device); | |
113 | tasklet_init(&device->cq_tasklet[i], | ||
114 | iser_cq_tasklet_fn, | ||
115 | (unsigned long)&cq_desc[i]); | ||
116 | } | ||
117 | 99 | ||
118 | device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE | | 100 | device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE | |
119 | IB_ACCESS_REMOTE_WRITE | | 101 | IB_ACCESS_REMOTE_WRITE | |
@@ -131,19 +113,14 @@ static int iser_create_device_ib_res(struct iser_device *device) | |||
131 | handler_err: | 113 | handler_err: |
132 | ib_dereg_mr(device->mr); | 114 | ib_dereg_mr(device->mr); |
133 | dma_mr_err: | 115 | dma_mr_err: |
134 | for (j = 0; j < device->cqs_used; j++) | 116 | tasklet_kill(&device->cq_tasklet); |
135 | tasklet_kill(&device->cq_tasklet[j]); | 117 | cq_arm_err: |
136 | cq_err: | 118 | ib_destroy_cq(device->tx_cq); |
137 | for (j = 0; j < i; j++) { | 119 | tx_cq_err: |
138 | if (device->tx_cq[j]) | 120 | ib_destroy_cq(device->rx_cq); |
139 | ib_destroy_cq(device->tx_cq[j]); | 121 | rx_cq_err: |
140 | if (device->rx_cq[j]) | ||
141 | ib_destroy_cq(device->rx_cq[j]); | ||
142 | } | ||
143 | ib_dealloc_pd(device->pd); | 122 | ib_dealloc_pd(device->pd); |
144 | pd_err: | 123 | pd_err: |
145 | kfree(device->cq_desc); | ||
146 | cq_desc_err: | ||
147 | iser_err("failed to allocate an IB resource\n"); | 124 | iser_err("failed to allocate an IB resource\n"); |
148 | return -1; | 125 | return -1; |
149 | } | 126 | } |
@@ -154,24 +131,18 @@ cq_desc_err: | |||
154 | */ | 131 | */ |
155 | static void iser_free_device_ib_res(struct iser_device *device) | 132 | static void iser_free_device_ib_res(struct iser_device *device) |
156 | { | 133 | { |
157 | int i; | ||
158 | BUG_ON(device->mr == NULL); | 134 | BUG_ON(device->mr == NULL); |
159 | 135 | ||
160 | for (i = 0; i < device->cqs_used; i++) { | 136 | tasklet_kill(&device->cq_tasklet); |
161 | tasklet_kill(&device->cq_tasklet[i]); | ||
162 | (void)ib_destroy_cq(device->tx_cq[i]); | ||
163 | (void)ib_destroy_cq(device->rx_cq[i]); | ||
164 | device->tx_cq[i] = NULL; | ||
165 | device->rx_cq[i] = NULL; | ||
166 | } | ||
167 | |||
168 | (void)ib_unregister_event_handler(&device->event_handler); | 137 | (void)ib_unregister_event_handler(&device->event_handler); |
169 | (void)ib_dereg_mr(device->mr); | 138 | (void)ib_dereg_mr(device->mr); |
139 | (void)ib_destroy_cq(device->tx_cq); | ||
140 | (void)ib_destroy_cq(device->rx_cq); | ||
170 | (void)ib_dealloc_pd(device->pd); | 141 | (void)ib_dealloc_pd(device->pd); |
171 | 142 | ||
172 | kfree(device->cq_desc); | ||
173 | |||
174 | device->mr = NULL; | 143 | device->mr = NULL; |
144 | device->tx_cq = NULL; | ||
145 | device->rx_cq = NULL; | ||
175 | device->pd = NULL; | 146 | device->pd = NULL; |
176 | } | 147 | } |
177 | 148 | ||
@@ -184,40 +155,20 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
184 | { | 155 | { |
185 | struct iser_device *device; | 156 | struct iser_device *device; |
186 | struct ib_qp_init_attr init_attr; | 157 | struct ib_qp_init_attr init_attr; |
187 | int req_err, resp_err, ret = -ENOMEM; | 158 | int ret = -ENOMEM; |
188 | struct ib_fmr_pool_param params; | 159 | struct ib_fmr_pool_param params; |
189 | int index, min_index = 0; | ||
190 | 160 | ||
191 | BUG_ON(ib_conn->device == NULL); | 161 | BUG_ON(ib_conn->device == NULL); |
192 | 162 | ||
193 | device = ib_conn->device; | 163 | device = ib_conn->device; |
194 | 164 | ||
195 | ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN + | 165 | ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); |
196 | ISER_RX_LOGIN_SIZE, GFP_KERNEL); | ||
197 | if (!ib_conn->login_buf) | 166 | if (!ib_conn->login_buf) |
198 | goto out_err; | 167 | goto out_err; |
199 | 168 | ||
200 | ib_conn->login_req_buf = ib_conn->login_buf; | 169 | ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, |
201 | ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN; | 170 | (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, |
202 | 171 | DMA_FROM_DEVICE); | |
203 | ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
204 | (void *)ib_conn->login_req_buf, | ||
205 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
206 | |||
207 | ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device, | ||
208 | (void *)ib_conn->login_resp_buf, | ||
209 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
210 | |||
211 | req_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma); | ||
212 | resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma); | ||
213 | |||
214 | if (req_err || resp_err) { | ||
215 | if (req_err) | ||
216 | ib_conn->login_req_dma = 0; | ||
217 | if (resp_err) | ||
218 | ib_conn->login_resp_dma = 0; | ||
219 | goto out_err; | ||
220 | } | ||
221 | 172 | ||
222 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + | 173 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + |
223 | (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), | 174 | (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), |
@@ -250,20 +201,10 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
250 | 201 | ||
251 | memset(&init_attr, 0, sizeof init_attr); | 202 | memset(&init_attr, 0, sizeof init_attr); |
252 | 203 | ||
253 | mutex_lock(&ig.connlist_mutex); | ||
254 | /* select the CQ with the minimal number of usages */ | ||
255 | for (index = 0; index < device->cqs_used; index++) | ||
256 | if (device->cq_active_qps[index] < | ||
257 | device->cq_active_qps[min_index]) | ||
258 | min_index = index; | ||
259 | device->cq_active_qps[min_index]++; | ||
260 | mutex_unlock(&ig.connlist_mutex); | ||
261 | iser_err("cq index %d used for ib_conn %p\n", min_index, ib_conn); | ||
262 | |||
263 | init_attr.event_handler = iser_qp_event_callback; | 204 | init_attr.event_handler = iser_qp_event_callback; |
264 | init_attr.qp_context = (void *)ib_conn; | 205 | init_attr.qp_context = (void *)ib_conn; |
265 | init_attr.send_cq = device->tx_cq[min_index]; | 206 | init_attr.send_cq = device->tx_cq; |
266 | init_attr.recv_cq = device->rx_cq[min_index]; | 207 | init_attr.recv_cq = device->rx_cq; |
267 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; | 208 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; |
268 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; | 209 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; |
269 | init_attr.cap.max_send_sge = 2; | 210 | init_attr.cap.max_send_sge = 2; |
@@ -292,7 +233,6 @@ out_err: | |||
292 | */ | 233 | */ |
293 | static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) | 234 | static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) |
294 | { | 235 | { |
295 | int cq_index; | ||
296 | BUG_ON(ib_conn == NULL); | 236 | BUG_ON(ib_conn == NULL); |
297 | 237 | ||
298 | iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n", | 238 | iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n", |
@@ -303,12 +243,9 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) | |||
303 | if (ib_conn->fmr_pool != NULL) | 243 | if (ib_conn->fmr_pool != NULL) |
304 | ib_destroy_fmr_pool(ib_conn->fmr_pool); | 244 | ib_destroy_fmr_pool(ib_conn->fmr_pool); |
305 | 245 | ||
306 | if (ib_conn->qp != NULL) { | 246 | if (ib_conn->qp != NULL) |
307 | cq_index = ((struct iser_cq_desc *)ib_conn->qp->recv_cq->cq_context)->cq_index; | ||
308 | ib_conn->device->cq_active_qps[cq_index]--; | ||
309 | |||
310 | rdma_destroy_qp(ib_conn->cma_id); | 247 | rdma_destroy_qp(ib_conn->cma_id); |
311 | } | 248 | |
312 | /* if cma handler context, the caller acts s.t the cma destroy the id */ | 249 | /* if cma handler context, the caller acts s.t the cma destroy the id */ |
313 | if (ib_conn->cma_id != NULL && can_destroy_id) | 250 | if (ib_conn->cma_id != NULL && can_destroy_id) |
314 | rdma_destroy_id(ib_conn->cma_id); | 251 | rdma_destroy_id(ib_conn->cma_id); |
@@ -318,18 +255,6 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) | |||
318 | ib_conn->cma_id = NULL; | 255 | ib_conn->cma_id = NULL; |
319 | kfree(ib_conn->page_vec); | 256 | kfree(ib_conn->page_vec); |
320 | 257 | ||
321 | if (ib_conn->login_buf) { | ||
322 | if (ib_conn->login_req_dma) | ||
323 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
324 | ib_conn->login_req_dma, | ||
325 | ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE); | ||
326 | if (ib_conn->login_resp_dma) | ||
327 | ib_dma_unmap_single(ib_conn->device->ib_device, | ||
328 | ib_conn->login_resp_dma, | ||
329 | ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); | ||
330 | kfree(ib_conn->login_buf); | ||
331 | } | ||
332 | |||
333 | return 0; | 258 | return 0; |
334 | } | 259 | } |
335 | 260 | ||
@@ -657,9 +582,8 @@ id_failure: | |||
657 | ib_conn->cma_id = NULL; | 582 | ib_conn->cma_id = NULL; |
658 | addr_failure: | 583 | addr_failure: |
659 | ib_conn->state = ISER_CONN_DOWN; | 584 | ib_conn->state = ISER_CONN_DOWN; |
660 | iser_conn_put(ib_conn, 1); /* deref ib conn's cma id */ | ||
661 | connect_failure: | 585 | connect_failure: |
662 | iser_conn_put(ib_conn, 1); /* deref ib conn deallocate */ | 586 | iser_conn_release(ib_conn, 1); |
663 | return err; | 587 | return err; |
664 | } | 588 | } |
665 | 589 | ||
@@ -734,11 +658,11 @@ int iser_post_recvl(struct iser_conn *ib_conn) | |||
734 | struct ib_sge sge; | 658 | struct ib_sge sge; |
735 | int ib_ret; | 659 | int ib_ret; |
736 | 660 | ||
737 | sge.addr = ib_conn->login_resp_dma; | 661 | sge.addr = ib_conn->login_dma; |
738 | sge.length = ISER_RX_LOGIN_SIZE; | 662 | sge.length = ISER_RX_LOGIN_SIZE; |
739 | sge.lkey = ib_conn->device->mr->lkey; | 663 | sge.lkey = ib_conn->device->mr->lkey; |
740 | 664 | ||
741 | rx_wr.wr_id = (unsigned long)ib_conn->login_resp_buf; | 665 | rx_wr.wr_id = (unsigned long)ib_conn->login_buf; |
742 | rx_wr.sg_list = &sge; | 666 | rx_wr.sg_list = &sge; |
743 | rx_wr.num_sge = 1; | 667 | rx_wr.num_sge = 1; |
744 | rx_wr.next = NULL; | 668 | rx_wr.next = NULL; |
@@ -835,9 +759,9 @@ static void iser_handle_comp_error(struct iser_tx_desc *desc, | |||
835 | } | 759 | } |
836 | } | 760 | } |
837 | 761 | ||
838 | static int iser_drain_tx_cq(struct iser_device *device, int cq_index) | 762 | static int iser_drain_tx_cq(struct iser_device *device) |
839 | { | 763 | { |
840 | struct ib_cq *cq = device->tx_cq[cq_index]; | 764 | struct ib_cq *cq = device->tx_cq; |
841 | struct ib_wc wc; | 765 | struct ib_wc wc; |
842 | struct iser_tx_desc *tx_desc; | 766 | struct iser_tx_desc *tx_desc; |
843 | struct iser_conn *ib_conn; | 767 | struct iser_conn *ib_conn; |
@@ -866,10 +790,8 @@ static int iser_drain_tx_cq(struct iser_device *device, int cq_index) | |||
866 | 790 | ||
867 | static void iser_cq_tasklet_fn(unsigned long data) | 791 | static void iser_cq_tasklet_fn(unsigned long data) |
868 | { | 792 | { |
869 | struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)data; | 793 | struct iser_device *device = (struct iser_device *)data; |
870 | struct iser_device *device = cq_desc->device; | 794 | struct ib_cq *cq = device->rx_cq; |
871 | int cq_index = cq_desc->cq_index; | ||
872 | struct ib_cq *cq = device->rx_cq[cq_index]; | ||
873 | struct ib_wc wc; | 795 | struct ib_wc wc; |
874 | struct iser_rx_desc *desc; | 796 | struct iser_rx_desc *desc; |
875 | unsigned long xfer_len; | 797 | unsigned long xfer_len; |
@@ -897,21 +819,19 @@ static void iser_cq_tasklet_fn(unsigned long data) | |||
897 | } | 819 | } |
898 | completed_rx++; | 820 | completed_rx++; |
899 | if (!(completed_rx & 63)) | 821 | if (!(completed_rx & 63)) |
900 | completed_tx += iser_drain_tx_cq(device, cq_index); | 822 | completed_tx += iser_drain_tx_cq(device); |
901 | } | 823 | } |
902 | /* #warning "it is assumed here that arming CQ only once its empty" * | 824 | /* #warning "it is assumed here that arming CQ only once its empty" * |
903 | * " would not cause interrupts to be missed" */ | 825 | * " would not cause interrupts to be missed" */ |
904 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); | 826 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); |
905 | 827 | ||
906 | completed_tx += iser_drain_tx_cq(device, cq_index); | 828 | completed_tx += iser_drain_tx_cq(device); |
907 | iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx); | 829 | iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx); |
908 | } | 830 | } |
909 | 831 | ||
910 | static void iser_cq_callback(struct ib_cq *cq, void *cq_context) | 832 | static void iser_cq_callback(struct ib_cq *cq, void *cq_context) |
911 | { | 833 | { |
912 | struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)cq_context; | 834 | struct iser_device *device = (struct iser_device *)cq_context; |
913 | struct iser_device *device = cq_desc->device; | ||
914 | int cq_index = cq_desc->cq_index; | ||
915 | 835 | ||
916 | tasklet_schedule(&device->cq_tasklet[cq_index]); | 836 | tasklet_schedule(&device->cq_tasklet); |
917 | } | 837 | } |