diff options
Diffstat (limited to 'drivers/infiniband/core/device.c')
-rw-r--r-- | drivers/infiniband/core/device.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index e711de400a01..18c1ece765f2 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
@@ -707,18 +707,28 @@ int ib_find_pkey(struct ib_device *device, | |||
707 | { | 707 | { |
708 | int ret, i; | 708 | int ret, i; |
709 | u16 tmp_pkey; | 709 | u16 tmp_pkey; |
710 | int partial_ix = -1; | ||
710 | 711 | ||
711 | for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)]; ++i) { | 712 | for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)]; ++i) { |
712 | ret = ib_query_pkey(device, port_num, i, &tmp_pkey); | 713 | ret = ib_query_pkey(device, port_num, i, &tmp_pkey); |
713 | if (ret) | 714 | if (ret) |
714 | return ret; | 715 | return ret; |
715 | |||
716 | if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { | 716 | if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { |
717 | *index = i; | 717 | /* if there is full-member pkey take it.*/ |
718 | return 0; | 718 | if (tmp_pkey & 0x8000) { |
719 | *index = i; | ||
720 | return 0; | ||
721 | } | ||
722 | if (partial_ix < 0) | ||
723 | partial_ix = i; | ||
719 | } | 724 | } |
720 | } | 725 | } |
721 | 726 | ||
727 | /*no full-member, if exists take the limited*/ | ||
728 | if (partial_ix >= 0) { | ||
729 | *index = partial_ix; | ||
730 | return 0; | ||
731 | } | ||
722 | return -ENOENT; | 732 | return -ENOENT; |
723 | } | 733 | } |
724 | EXPORT_SYMBOL(ib_find_pkey); | 734 | EXPORT_SYMBOL(ib_find_pkey); |