diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index f09a9403b600..0504e7376f1e 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
@@ -1820,24 +1820,42 @@ static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr, | |||
1820 | memset(sge, 0, sizeof(*sge)); | 1820 | memset(sge, 0, sizeof(*sge)); |
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | static inline uint32_t ocrdma_sglist_len(struct ib_sge *sg_list, int num_sge) | ||
1824 | { | ||
1825 | uint32_t total_len = 0, i; | ||
1826 | |||
1827 | for (i = 0; i < num_sge; i++) | ||
1828 | total_len += sg_list[i].length; | ||
1829 | return total_len; | ||
1830 | } | ||
1831 | |||
1832 | |||
1823 | static int ocrdma_build_inline_sges(struct ocrdma_qp *qp, | 1833 | static int ocrdma_build_inline_sges(struct ocrdma_qp *qp, |
1824 | struct ocrdma_hdr_wqe *hdr, | 1834 | struct ocrdma_hdr_wqe *hdr, |
1825 | struct ocrdma_sge *sge, | 1835 | struct ocrdma_sge *sge, |
1826 | struct ib_send_wr *wr, u32 wqe_size) | 1836 | struct ib_send_wr *wr, u32 wqe_size) |
1827 | { | 1837 | { |
1838 | int i; | ||
1839 | char *dpp_addr; | ||
1840 | |||
1828 | if (wr->send_flags & IB_SEND_INLINE && qp->qp_type != IB_QPT_UD) { | 1841 | if (wr->send_flags & IB_SEND_INLINE && qp->qp_type != IB_QPT_UD) { |
1829 | if (wr->sg_list[0].length > qp->max_inline_data) { | 1842 | hdr->total_len = ocrdma_sglist_len(wr->sg_list, wr->num_sge); |
1843 | if (unlikely(hdr->total_len > qp->max_inline_data)) { | ||
1830 | pr_err("%s() supported_len=0x%x,\n" | 1844 | pr_err("%s() supported_len=0x%x,\n" |
1831 | " unspported len req=0x%x\n", __func__, | 1845 | " unspported len req=0x%x\n", __func__, |
1832 | qp->max_inline_data, wr->sg_list[0].length); | 1846 | qp->max_inline_data, hdr->total_len); |
1833 | return -EINVAL; | 1847 | return -EINVAL; |
1834 | } | 1848 | } |
1835 | memcpy(sge, | 1849 | dpp_addr = (char *)sge; |
1836 | (void *)(unsigned long)wr->sg_list[0].addr, | 1850 | for (i = 0; i < wr->num_sge; i++) { |
1837 | wr->sg_list[0].length); | 1851 | memcpy(dpp_addr, |
1838 | hdr->total_len = wr->sg_list[0].length; | 1852 | (void *)(unsigned long)wr->sg_list[i].addr, |
1853 | wr->sg_list[i].length); | ||
1854 | dpp_addr += wr->sg_list[i].length; | ||
1855 | } | ||
1856 | |||
1839 | wqe_size += roundup(hdr->total_len, OCRDMA_WQE_ALIGN_BYTES); | 1857 | wqe_size += roundup(hdr->total_len, OCRDMA_WQE_ALIGN_BYTES); |
1840 | if (0 == wr->sg_list[0].length) | 1858 | if (0 == hdr->total_len) |
1841 | wqe_size += sizeof(struct ocrdma_sge); | 1859 | wqe_size += sizeof(struct ocrdma_sge); |
1842 | hdr->cw |= (OCRDMA_TYPE_INLINE << OCRDMA_WQE_TYPE_SHIFT); | 1860 | hdr->cw |= (OCRDMA_TYPE_INLINE << OCRDMA_WQE_TYPE_SHIFT); |
1843 | } else { | 1861 | } else { |