aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2007-11-09 18:22:31 -0500
committerRoland Dreier <rolandd@cisco.com>2007-11-20 14:04:41 -0500
commit14de986a0ba560b54340fd277a3579e95a2d3838 (patch)
tree853ca35f6c93dfc940cc359009cb315dbb28084e /drivers/infiniband
parent8a278e6d571ebe10b96f2b53c74f01fd0a3f005a (diff)
IB/ipath: Fix offset returned to ibv_modify_srq()
The wrong offset was being returned to libipathverbs so that when ibv_modify_srq() calls mmap(), it always fails. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index 40c36ec19016..434da6270f65 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -211,11 +211,11 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
211 struct ib_udata *udata) 211 struct ib_udata *udata)
212{ 212{
213 struct ipath_srq *srq = to_isrq(ibsrq); 213 struct ipath_srq *srq = to_isrq(ibsrq);
214 struct ipath_rwq *wq;
214 int ret = 0; 215 int ret = 0;
215 216
216 if (attr_mask & IB_SRQ_MAX_WR) { 217 if (attr_mask & IB_SRQ_MAX_WR) {
217 struct ipath_rwq *owq; 218 struct ipath_rwq *owq;
218 struct ipath_rwq *wq;
219 struct ipath_rwqe *p; 219 struct ipath_rwqe *p;
220 u32 sz, size, n, head, tail; 220 u32 sz, size, n, head, tail;
221 221
@@ -236,27 +236,20 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
236 goto bail; 236 goto bail;
237 } 237 }
238 238
239 /* 239 /* Check that we can write the offset to mmap. */
240 * Return the address of the RWQ as the offset to mmap.
241 * See ipath_mmap() for details.
242 */
243 if (udata && udata->inlen >= sizeof(__u64)) { 240 if (udata && udata->inlen >= sizeof(__u64)) {
244 __u64 offset_addr; 241 __u64 offset_addr;
245 __u64 offset = (__u64) wq; 242 __u64 offset = 0;
246 243
247 ret = ib_copy_from_udata(&offset_addr, udata, 244 ret = ib_copy_from_udata(&offset_addr, udata,
248 sizeof(offset_addr)); 245 sizeof(offset_addr));
249 if (ret) { 246 if (ret)
250 vfree(wq); 247 goto bail_free;
251 goto bail;
252 }
253 udata->outbuf = (void __user *) offset_addr; 248 udata->outbuf = (void __user *) offset_addr;
254 ret = ib_copy_to_udata(udata, &offset, 249 ret = ib_copy_to_udata(udata, &offset,
255 sizeof(offset)); 250 sizeof(offset));
256 if (ret) { 251 if (ret)
257 vfree(wq); 252 goto bail_free;
258 goto bail;
259 }
260 } 253 }
261 254
262 spin_lock_irq(&srq->rq.lock); 255 spin_lock_irq(&srq->rq.lock);
@@ -277,10 +270,8 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
277 else 270 else
278 n -= tail; 271 n -= tail;
279 if (size <= n) { 272 if (size <= n) {
280 spin_unlock_irq(&srq->rq.lock);
281 vfree(wq);
282 ret = -EINVAL; 273 ret = -EINVAL;
283 goto bail; 274 goto bail_unlock;
284 } 275 }
285 n = 0; 276 n = 0;
286 p = wq->wq; 277 p = wq->wq;
@@ -314,6 +305,18 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
314 u32 s = sizeof(struct ipath_rwq) + size * sz; 305 u32 s = sizeof(struct ipath_rwq) + size * sz;
315 306
316 ipath_update_mmap_info(dev, ip, s, wq); 307 ipath_update_mmap_info(dev, ip, s, wq);
308
309 /*
310 * Return the offset to mmap.
311 * See ipath_mmap() for details.
312 */
313 if (udata && udata->inlen >= sizeof(__u64)) {
314 ret = ib_copy_to_udata(udata, &ip->offset,
315 sizeof(ip->offset));
316 if (ret)
317 goto bail;
318 }
319
317 spin_lock_irq(&dev->pending_lock); 320 spin_lock_irq(&dev->pending_lock);
318 if (list_empty(&ip->pending_mmaps)) 321 if (list_empty(&ip->pending_mmaps))
319 list_add(&ip->pending_mmaps, 322 list_add(&ip->pending_mmaps,
@@ -328,7 +331,12 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
328 srq->limit = attr->srq_limit; 331 srq->limit = attr->srq_limit;
329 spin_unlock_irq(&srq->rq.lock); 332 spin_unlock_irq(&srq->rq.lock);
330 } 333 }
334 goto bail;
331 335
336bail_unlock:
337 spin_unlock_irq(&srq->rq.lock);
338bail_free:
339 vfree(wq);
332bail: 340bail:
333 return ret; 341 return ret;
334} 342}