diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 120 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 27 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_eq.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 2 |
7 files changed, 104 insertions, 71 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index b1897bed14ad..cc124344dd2c 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -69,6 +69,7 @@ struct ib_uverbs_event_file { | |||
69 | 69 | ||
70 | struct ib_uverbs_file { | 70 | struct ib_uverbs_file { |
71 | struct kref ref; | 71 | struct kref ref; |
72 | struct semaphore mutex; | ||
72 | struct ib_uverbs_device *device; | 73 | struct ib_uverbs_device *device; |
73 | struct ib_ucontext *ucontext; | 74 | struct ib_ucontext *ucontext; |
74 | struct ib_event_handler event_handler; | 75 | struct ib_event_handler event_handler; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index e91ebde46481..562445165d2b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
76 | struct ib_uverbs_get_context_resp resp; | 76 | struct ib_uverbs_get_context_resp resp; |
77 | struct ib_udata udata; | 77 | struct ib_udata udata; |
78 | struct ib_device *ibdev = file->device->ib_dev; | 78 | struct ib_device *ibdev = file->device->ib_dev; |
79 | struct ib_ucontext *ucontext; | ||
79 | int i; | 80 | int i; |
80 | int ret = in_len; | 81 | int ret; |
81 | 82 | ||
82 | if (out_len < sizeof resp) | 83 | if (out_len < sizeof resp) |
83 | return -ENOSPC; | 84 | return -ENOSPC; |
@@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
85 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 86 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
86 | return -EFAULT; | 87 | return -EFAULT; |
87 | 88 | ||
89 | down(&file->mutex); | ||
90 | |||
91 | if (file->ucontext) { | ||
92 | ret = -EINVAL; | ||
93 | goto err; | ||
94 | } | ||
95 | |||
88 | INIT_UDATA(&udata, buf + sizeof cmd, | 96 | INIT_UDATA(&udata, buf + sizeof cmd, |
89 | (unsigned long) cmd.response + sizeof resp, | 97 | (unsigned long) cmd.response + sizeof resp, |
90 | in_len - sizeof cmd, out_len - sizeof resp); | 98 | in_len - sizeof cmd, out_len - sizeof resp); |
91 | 99 | ||
92 | file->ucontext = ibdev->alloc_ucontext(ibdev, &udata); | 100 | ucontext = ibdev->alloc_ucontext(ibdev, &udata); |
93 | if (IS_ERR(file->ucontext)) { | 101 | if (IS_ERR(ucontext)) |
94 | ret = PTR_ERR(file->ucontext); | 102 | return PTR_ERR(file->ucontext); |
95 | file->ucontext = NULL; | ||
96 | return ret; | ||
97 | } | ||
98 | 103 | ||
99 | file->ucontext->device = ibdev; | 104 | ucontext->device = ibdev; |
100 | INIT_LIST_HEAD(&file->ucontext->pd_list); | 105 | INIT_LIST_HEAD(&ucontext->pd_list); |
101 | INIT_LIST_HEAD(&file->ucontext->mr_list); | 106 | INIT_LIST_HEAD(&ucontext->mr_list); |
102 | INIT_LIST_HEAD(&file->ucontext->mw_list); | 107 | INIT_LIST_HEAD(&ucontext->mw_list); |
103 | INIT_LIST_HEAD(&file->ucontext->cq_list); | 108 | INIT_LIST_HEAD(&ucontext->cq_list); |
104 | INIT_LIST_HEAD(&file->ucontext->qp_list); | 109 | INIT_LIST_HEAD(&ucontext->qp_list); |
105 | INIT_LIST_HEAD(&file->ucontext->srq_list); | 110 | INIT_LIST_HEAD(&ucontext->srq_list); |
106 | INIT_LIST_HEAD(&file->ucontext->ah_list); | 111 | INIT_LIST_HEAD(&ucontext->ah_list); |
107 | spin_lock_init(&file->ucontext->lock); | ||
108 | 112 | ||
109 | resp.async_fd = file->async_file.fd; | 113 | resp.async_fd = file->async_file.fd; |
110 | for (i = 0; i < file->device->num_comp; ++i) | 114 | for (i = 0; i < file->device->num_comp; ++i) |
111 | if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + | 115 | if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + |
112 | i * sizeof (__u32), | 116 | i * sizeof (__u32), |
113 | &file->comp_file[i].fd, sizeof (__u32))) | 117 | &file->comp_file[i].fd, sizeof (__u32))) { |
114 | goto err; | 118 | ret = -EFAULT; |
119 | goto err_free; | ||
120 | } | ||
115 | 121 | ||
116 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 122 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
117 | &resp, sizeof resp)) | 123 | &resp, sizeof resp)) { |
118 | goto err; | 124 | ret = -EFAULT; |
125 | goto err_free; | ||
126 | } | ||
127 | |||
128 | file->ucontext = ucontext; | ||
129 | up(&file->mutex); | ||
119 | 130 | ||
120 | return in_len; | 131 | return in_len; |
121 | 132 | ||
122 | err: | 133 | err_free: |
123 | ibdev->dealloc_ucontext(file->ucontext); | 134 | ibdev->dealloc_ucontext(ucontext); |
124 | file->ucontext = NULL; | ||
125 | 135 | ||
126 | return -EFAULT; | 136 | err: |
137 | up(&file->mutex); | ||
138 | return ret; | ||
127 | } | 139 | } |
128 | 140 | ||
129 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, | 141 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, |
@@ -352,9 +364,9 @@ retry: | |||
352 | if (ret) | 364 | if (ret) |
353 | goto err_pd; | 365 | goto err_pd; |
354 | 366 | ||
355 | spin_lock_irq(&file->ucontext->lock); | 367 | down(&file->mutex); |
356 | list_add_tail(&uobj->list, &file->ucontext->pd_list); | 368 | list_add_tail(&uobj->list, &file->ucontext->pd_list); |
357 | spin_unlock_irq(&file->ucontext->lock); | 369 | up(&file->mutex); |
358 | 370 | ||
359 | memset(&resp, 0, sizeof resp); | 371 | memset(&resp, 0, sizeof resp); |
360 | resp.pd_handle = uobj->id; | 372 | resp.pd_handle = uobj->id; |
@@ -368,9 +380,9 @@ retry: | |||
368 | return in_len; | 380 | return in_len; |
369 | 381 | ||
370 | err_list: | 382 | err_list: |
371 | spin_lock_irq(&file->ucontext->lock); | 383 | down(&file->mutex); |
372 | list_del(&uobj->list); | 384 | list_del(&uobj->list); |
373 | spin_unlock_irq(&file->ucontext->lock); | 385 | up(&file->mutex); |
374 | 386 | ||
375 | down(&ib_uverbs_idr_mutex); | 387 | down(&ib_uverbs_idr_mutex); |
376 | idr_remove(&ib_uverbs_pd_idr, uobj->id); | 388 | idr_remove(&ib_uverbs_pd_idr, uobj->id); |
@@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, | |||
410 | 422 | ||
411 | idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); | 423 | idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); |
412 | 424 | ||
413 | spin_lock_irq(&file->ucontext->lock); | 425 | down(&file->mutex); |
414 | list_del(&uobj->list); | 426 | list_del(&uobj->list); |
415 | spin_unlock_irq(&file->ucontext->lock); | 427 | up(&file->mutex); |
416 | 428 | ||
417 | kfree(uobj); | 429 | kfree(uobj); |
418 | 430 | ||
@@ -512,9 +524,9 @@ retry: | |||
512 | 524 | ||
513 | resp.mr_handle = obj->uobject.id; | 525 | resp.mr_handle = obj->uobject.id; |
514 | 526 | ||
515 | spin_lock_irq(&file->ucontext->lock); | 527 | down(&file->mutex); |
516 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); | 528 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); |
517 | spin_unlock_irq(&file->ucontext->lock); | 529 | up(&file->mutex); |
518 | 530 | ||
519 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 531 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
520 | &resp, sizeof resp)) { | 532 | &resp, sizeof resp)) { |
@@ -527,9 +539,9 @@ retry: | |||
527 | return in_len; | 539 | return in_len; |
528 | 540 | ||
529 | err_list: | 541 | err_list: |
530 | spin_lock_irq(&file->ucontext->lock); | 542 | down(&file->mutex); |
531 | list_del(&obj->uobject.list); | 543 | list_del(&obj->uobject.list); |
532 | spin_unlock_irq(&file->ucontext->lock); | 544 | up(&file->mutex); |
533 | 545 | ||
534 | err_unreg: | 546 | err_unreg: |
535 | ib_dereg_mr(mr); | 547 | ib_dereg_mr(mr); |
@@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, | |||
570 | 582 | ||
571 | idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); | 583 | idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); |
572 | 584 | ||
573 | spin_lock_irq(&file->ucontext->lock); | 585 | down(&file->mutex); |
574 | list_del(&memobj->uobject.list); | 586 | list_del(&memobj->uobject.list); |
575 | spin_unlock_irq(&file->ucontext->lock); | 587 | up(&file->mutex); |
576 | 588 | ||
577 | ib_umem_release(file->device->ib_dev, &memobj->umem); | 589 | ib_umem_release(file->device->ib_dev, &memobj->umem); |
578 | kfree(memobj); | 590 | kfree(memobj); |
@@ -647,9 +659,9 @@ retry: | |||
647 | if (ret) | 659 | if (ret) |
648 | goto err_cq; | 660 | goto err_cq; |
649 | 661 | ||
650 | spin_lock_irq(&file->ucontext->lock); | 662 | down(&file->mutex); |
651 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); | 663 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); |
652 | spin_unlock_irq(&file->ucontext->lock); | 664 | up(&file->mutex); |
653 | 665 | ||
654 | memset(&resp, 0, sizeof resp); | 666 | memset(&resp, 0, sizeof resp); |
655 | resp.cq_handle = uobj->uobject.id; | 667 | resp.cq_handle = uobj->uobject.id; |
@@ -664,9 +676,9 @@ retry: | |||
664 | return in_len; | 676 | return in_len; |
665 | 677 | ||
666 | err_list: | 678 | err_list: |
667 | spin_lock_irq(&file->ucontext->lock); | 679 | down(&file->mutex); |
668 | list_del(&uobj->uobject.list); | 680 | list_del(&uobj->uobject.list); |
669 | spin_unlock_irq(&file->ucontext->lock); | 681 | up(&file->mutex); |
670 | 682 | ||
671 | down(&ib_uverbs_idr_mutex); | 683 | down(&ib_uverbs_idr_mutex); |
672 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); | 684 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); |
@@ -712,9 +724,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, | |||
712 | 724 | ||
713 | idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); | 725 | idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); |
714 | 726 | ||
715 | spin_lock_irq(&file->ucontext->lock); | 727 | down(&file->mutex); |
716 | list_del(&uobj->uobject.list); | 728 | list_del(&uobj->uobject.list); |
717 | spin_unlock_irq(&file->ucontext->lock); | 729 | up(&file->mutex); |
718 | 730 | ||
719 | spin_lock_irq(&file->comp_file[0].lock); | 731 | spin_lock_irq(&file->comp_file[0].lock); |
720 | list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { | 732 | list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { |
@@ -847,9 +859,9 @@ retry: | |||
847 | 859 | ||
848 | resp.qp_handle = uobj->uobject.id; | 860 | resp.qp_handle = uobj->uobject.id; |
849 | 861 | ||
850 | spin_lock_irq(&file->ucontext->lock); | 862 | down(&file->mutex); |
851 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); | 863 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); |
852 | spin_unlock_irq(&file->ucontext->lock); | 864 | up(&file->mutex); |
853 | 865 | ||
854 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 866 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
855 | &resp, sizeof resp)) { | 867 | &resp, sizeof resp)) { |
@@ -862,9 +874,9 @@ retry: | |||
862 | return in_len; | 874 | return in_len; |
863 | 875 | ||
864 | err_list: | 876 | err_list: |
865 | spin_lock_irq(&file->ucontext->lock); | 877 | down(&file->mutex); |
866 | list_del(&uobj->uobject.list); | 878 | list_del(&uobj->uobject.list); |
867 | spin_unlock_irq(&file->ucontext->lock); | 879 | up(&file->mutex); |
868 | 880 | ||
869 | err_destroy: | 881 | err_destroy: |
870 | ib_destroy_qp(qp); | 882 | ib_destroy_qp(qp); |
@@ -989,9 +1001,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, | |||
989 | 1001 | ||
990 | idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); | 1002 | idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); |
991 | 1003 | ||
992 | spin_lock_irq(&file->ucontext->lock); | 1004 | down(&file->mutex); |
993 | list_del(&uobj->uobject.list); | 1005 | list_del(&uobj->uobject.list); |
994 | spin_unlock_irq(&file->ucontext->lock); | 1006 | up(&file->mutex); |
995 | 1007 | ||
996 | spin_lock_irq(&file->async_file.lock); | 1008 | spin_lock_irq(&file->async_file.lock); |
997 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { | 1009 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { |
@@ -1136,9 +1148,9 @@ retry: | |||
1136 | 1148 | ||
1137 | resp.srq_handle = uobj->uobject.id; | 1149 | resp.srq_handle = uobj->uobject.id; |
1138 | 1150 | ||
1139 | spin_lock_irq(&file->ucontext->lock); | 1151 | down(&file->mutex); |
1140 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); | 1152 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); |
1141 | spin_unlock_irq(&file->ucontext->lock); | 1153 | up(&file->mutex); |
1142 | 1154 | ||
1143 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 1155 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
1144 | &resp, sizeof resp)) { | 1156 | &resp, sizeof resp)) { |
@@ -1151,9 +1163,9 @@ retry: | |||
1151 | return in_len; | 1163 | return in_len; |
1152 | 1164 | ||
1153 | err_list: | 1165 | err_list: |
1154 | spin_lock_irq(&file->ucontext->lock); | 1166 | down(&file->mutex); |
1155 | list_del(&uobj->uobject.list); | 1167 | list_del(&uobj->uobject.list); |
1156 | spin_unlock_irq(&file->ucontext->lock); | 1168 | up(&file->mutex); |
1157 | 1169 | ||
1158 | err_destroy: | 1170 | err_destroy: |
1159 | ib_destroy_srq(srq); | 1171 | ib_destroy_srq(srq); |
@@ -1227,9 +1239,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
1227 | 1239 | ||
1228 | idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); | 1240 | idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); |
1229 | 1241 | ||
1230 | spin_lock_irq(&file->ucontext->lock); | 1242 | down(&file->mutex); |
1231 | list_del(&uobj->uobject.list); | 1243 | list_del(&uobj->uobject.list); |
1232 | spin_unlock_irq(&file->ucontext->lock); | 1244 | up(&file->mutex); |
1233 | 1245 | ||
1234 | spin_lock_irq(&file->async_file.lock); | 1246 | spin_lock_irq(&file->async_file.lock); |
1235 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { | 1247 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index ce5bdb7af306..12511808de21 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -448,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
448 | if (hdr.in_words * 4 != count) | 448 | if (hdr.in_words * 4 != count) |
449 | return -EINVAL; | 449 | return -EINVAL; |
450 | 450 | ||
451 | if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table)) | 451 | if (hdr.command < 0 || |
452 | hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || | ||
453 | !uverbs_cmd_table[hdr.command]) | ||
452 | return -EINVAL; | 454 | return -EINVAL; |
453 | 455 | ||
454 | if (!file->ucontext && | 456 | if (!file->ucontext && |
@@ -484,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) | |||
484 | file = kmalloc(sizeof *file + | 486 | file = kmalloc(sizeof *file + |
485 | (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), | 487 | (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), |
486 | GFP_KERNEL); | 488 | GFP_KERNEL); |
487 | if (!file) | 489 | if (!file) { |
488 | return -ENOMEM; | 490 | ret = -ENOMEM; |
491 | goto err; | ||
492 | } | ||
489 | 493 | ||
490 | file->device = dev; | 494 | file->device = dev; |
491 | kref_init(&file->ref); | 495 | kref_init(&file->ref); |
496 | init_MUTEX(&file->mutex); | ||
492 | 497 | ||
493 | file->ucontext = NULL; | 498 | file->ucontext = NULL; |
494 | 499 | ||
500 | kref_get(&file->ref); | ||
495 | ret = ib_uverbs_event_init(&file->async_file, file); | 501 | ret = ib_uverbs_event_init(&file->async_file, file); |
496 | if (ret) | 502 | if (ret) |
497 | goto err; | 503 | goto err_kref; |
498 | 504 | ||
499 | file->async_file.is_async = 1; | 505 | file->async_file.is_async = 1; |
500 | 506 | ||
501 | kref_get(&file->ref); | ||
502 | |||
503 | for (i = 0; i < dev->num_comp; ++i) { | 507 | for (i = 0; i < dev->num_comp; ++i) { |
508 | kref_get(&file->ref); | ||
504 | ret = ib_uverbs_event_init(&file->comp_file[i], file); | 509 | ret = ib_uverbs_event_init(&file->comp_file[i], file); |
505 | if (ret) | 510 | if (ret) |
506 | goto err_async; | 511 | goto err_async; |
507 | kref_get(&file->ref); | ||
508 | file->comp_file[i].is_async = 0; | 512 | file->comp_file[i].is_async = 0; |
509 | } | 513 | } |
510 | 514 | ||
@@ -524,9 +528,16 @@ err_async: | |||
524 | 528 | ||
525 | ib_uverbs_event_release(&file->async_file); | 529 | ib_uverbs_event_release(&file->async_file); |
526 | 530 | ||
527 | err: | 531 | err_kref: |
532 | /* | ||
533 | * One extra kref_put() because we took a reference before the | ||
534 | * event file creation that failed and got us here. | ||
535 | */ | ||
536 | kref_put(&file->ref, ib_uverbs_release_file); | ||
528 | kref_put(&file->ref, ib_uverbs_release_file); | 537 | kref_put(&file->ref, ib_uverbs_release_file); |
529 | 538 | ||
539 | err: | ||
540 | module_put(dev->ib_dev->owner); | ||
530 | return ret; | 541 | return ret; |
531 | } | 542 | } |
532 | 543 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index cc758a2d2bc6..f6a8ac026557 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
605 | err = -EINVAL; | 605 | err = -EINVAL; |
606 | goto out; | 606 | goto out; |
607 | } | 607 | } |
608 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) { | 608 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) { |
609 | if (virt != -1) { | 609 | if (virt != -1) { |
610 | pages[nent * 2] = cpu_to_be64(virt); | 610 | pages[nent * 2] = cpu_to_be64(virt); |
611 | virt += 1 << lg; | 611 | virt += 1 << lg; |
@@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
616 | ts += 1 << (lg - 10); | 616 | ts += 1 << (lg - 10); |
617 | ++tc; | 617 | ++tc; |
618 | 618 | ||
619 | if (nent == MTHCA_MAILBOX_SIZE / 16) { | 619 | if (++nent == MTHCA_MAILBOX_SIZE / 16) { |
620 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, | 620 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, |
621 | CMD_TIME_CLASS_B, status); | 621 | CMD_TIME_CLASS_B, status); |
622 | if (err || *status) | 622 | if (err || *status) |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 78152a8ad17d..c81fa8e975ef 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
@@ -836,7 +836,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) | |||
836 | dev->eq_table.clr_mask = | 836 | dev->eq_table.clr_mask = |
837 | swab32(1 << (dev->eq_table.inta_pin & 31)); | 837 | swab32(1 << (dev->eq_table.inta_pin & 31)); |
838 | dev->eq_table.clr_int = dev->clr_base + | 838 | dev->eq_table.clr_int = dev->clr_base + |
839 | (dev->eq_table.inta_pin < 31 ? 4 : 0); | 839 | (dev->eq_table.inta_pin < 32 ? 4 : 0); |
840 | } | 840 | } |
841 | 841 | ||
842 | dev->eq_table.arm_mask = 0; | 842 | dev->eq_table.arm_mask = 0; |
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 1827400f189b..7bd7a4bec7b4 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, | |||
290 | int i; | 290 | int i; |
291 | u8 status; | 291 | u8 status; |
292 | 292 | ||
293 | num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE; | 293 | num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE; |
294 | 294 | ||
295 | table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); | 295 | table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); |
296 | if (!table) | 296 | if (!table) |
@@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) | |||
529 | goto found; | 529 | goto found; |
530 | } | 530 | } |
531 | 531 | ||
532 | for (i = start; i != end; i += dir) | ||
533 | if (!dev->db_tab->page[i].db_rec) { | ||
534 | page = dev->db_tab->page + i; | ||
535 | goto alloc; | ||
536 | } | ||
537 | |||
532 | if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) { | 538 | if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) { |
533 | ret = -ENOMEM; | 539 | ret = -ENOMEM; |
534 | goto out; | 540 | goto out; |
535 | } | 541 | } |
536 | 542 | ||
543 | if (group == 0) | ||
544 | ++dev->db_tab->max_group1; | ||
545 | else | ||
546 | --dev->db_tab->min_group2; | ||
547 | |||
537 | page = dev->db_tab->page + end; | 548 | page = dev->db_tab->page + end; |
549 | |||
550 | alloc: | ||
538 | page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096, | 551 | page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096, |
539 | &page->mapping, GFP_KERNEL); | 552 | &page->mapping, GFP_KERNEL); |
540 | if (!page->db_rec) { | 553 | if (!page->db_rec) { |
@@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) | |||
554 | } | 567 | } |
555 | 568 | ||
556 | bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE); | 569 | bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE); |
557 | if (group == 0) | ||
558 | ++dev->db_tab->max_group1; | ||
559 | else | ||
560 | --dev->db_tab->min_group2; | ||
561 | 570 | ||
562 | found: | 571 | found: |
563 | j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE); | 572 | j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE); |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 1c1c2e230871..3f5319a46577 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev, | |||
84 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & | 84 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & |
85 | 0xffffff; | 85 | 0xffffff; |
86 | props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); | 86 | props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); |
87 | props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32)); | 87 | props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32)); |
88 | memcpy(&props->sys_image_guid, out_mad->data + 4, 8); | 88 | memcpy(&props->sys_image_guid, out_mad->data + 4, 8); |
89 | memcpy(&props->node_guid, out_mad->data + 12, 8); | 89 | memcpy(&props->node_guid, out_mad->data + 12, 8); |
90 | 90 | ||