aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
diff options
context:
space:
mode:
authorNaresh Gottumukkala <bgottumukkala@emulex.com>2013-08-26 05:57:48 -0400
committerRoland Dreier <roland@purestorage.com>2013-09-03 00:18:44 -0400
commit117e6dd1c5c96ef1edd6e5def4dd9937d98cae94 (patch)
tree26c73a5fecf0701e6e468fd28f45b7581c100fce /drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
parentf24ceba6b6454f68f456981be2a337b6390d9aa0 (diff)
RDMA/ocrdma: Consider multiple SGES in case of DPP
While posting inline DPP data, we are not considering multiple sges. Fix this. Signed-off-by: Naresh Gottumukkala <bgottumukkala@emulex.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/ocrdma/ocrdma_verbs.c')
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c32
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
1823static 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
1823static int ocrdma_build_inline_sges(struct ocrdma_qp *qp, 1833static 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 {