aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_cq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_cq.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_cq.c68
1 files changed, 34 insertions, 34 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
index ea78e6dddc90..3e9241badba0 100644
--- a/drivers/infiniband/hw/ipath/ipath_cq.c
+++ b/drivers/infiniband/hw/ipath/ipath_cq.c
@@ -204,7 +204,7 @@ static void send_complete(unsigned long data)
204 * 204 *
205 * Called by ib_create_cq() in the generic verbs code. 205 * Called by ib_create_cq() in the generic verbs code.
206 */ 206 */
207struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, 207struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector,
208 struct ib_ucontext *context, 208 struct ib_ucontext *context,
209 struct ib_udata *udata) 209 struct ib_udata *udata)
210{ 210{
@@ -243,33 +243,21 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
243 * See ipath_mmap() for details. 243 * See ipath_mmap() for details.
244 */ 244 */
245 if (udata && udata->outlen >= sizeof(__u64)) { 245 if (udata && udata->outlen >= sizeof(__u64)) {
246 struct ipath_mmap_info *ip;
247 __u64 offset = (__u64) wc;
248 int err; 246 int err;
247 u32 s = sizeof *wc + sizeof(struct ib_wc) * entries;
249 248
250 err = ib_copy_to_udata(udata, &offset, sizeof(offset)); 249 cq->ip = ipath_create_mmap_info(dev, s, context, wc);
251 if (err) { 250 if (!cq->ip) {
252 ret = ERR_PTR(err); 251 ret = ERR_PTR(-ENOMEM);
253 goto bail_wc; 252 goto bail_wc;
254 } 253 }
255 254
256 /* Allocate info for ipath_mmap(). */ 255 err = ib_copy_to_udata(udata, &cq->ip->offset,
257 ip = kmalloc(sizeof(*ip), GFP_KERNEL); 256 sizeof(cq->ip->offset));
258 if (!ip) { 257 if (err) {
259 ret = ERR_PTR(-ENOMEM); 258 ret = ERR_PTR(err);
260 goto bail_wc; 259 goto bail_ip;
261 } 260 }
262 cq->ip = ip;
263 ip->context = context;
264 ip->obj = wc;
265 kref_init(&ip->ref);
266 ip->mmap_cnt = 0;
267 ip->size = PAGE_ALIGN(sizeof(*wc) +
268 sizeof(struct ib_wc) * entries);
269 spin_lock_irq(&dev->pending_lock);
270 ip->next = dev->pending_mmaps;
271 dev->pending_mmaps = ip;
272 spin_unlock_irq(&dev->pending_lock);
273 } else 261 } else
274 cq->ip = NULL; 262 cq->ip = NULL;
275 263
@@ -277,12 +265,18 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
277 if (dev->n_cqs_allocated == ib_ipath_max_cqs) { 265 if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
278 spin_unlock(&dev->n_cqs_lock); 266 spin_unlock(&dev->n_cqs_lock);
279 ret = ERR_PTR(-ENOMEM); 267 ret = ERR_PTR(-ENOMEM);
280 goto bail_wc; 268 goto bail_ip;
281 } 269 }
282 270
283 dev->n_cqs_allocated++; 271 dev->n_cqs_allocated++;
284 spin_unlock(&dev->n_cqs_lock); 272 spin_unlock(&dev->n_cqs_lock);
285 273
274 if (cq->ip) {
275 spin_lock_irq(&dev->pending_lock);
276 list_add(&cq->ip->pending_mmaps, &dev->pending_mmaps);
277 spin_unlock_irq(&dev->pending_lock);
278 }
279
286 /* 280 /*
287 * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe. 281 * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe.
288 * The number of entries should be >= the number requested or return 282 * The number of entries should be >= the number requested or return
@@ -301,12 +295,12 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
301 295
302 goto done; 296 goto done;
303 297
298bail_ip:
299 kfree(cq->ip);
304bail_wc: 300bail_wc:
305 vfree(wc); 301 vfree(wc);
306
307bail_cq: 302bail_cq:
308 kfree(cq); 303 kfree(cq);
309
310done: 304done:
311 return ret; 305 return ret;
312} 306}
@@ -340,17 +334,18 @@ int ipath_destroy_cq(struct ib_cq *ibcq)
340/** 334/**
341 * ipath_req_notify_cq - change the notification type for a completion queue 335 * ipath_req_notify_cq - change the notification type for a completion queue
342 * @ibcq: the completion queue 336 * @ibcq: the completion queue
343 * @notify: the type of notification to request 337 * @notify_flags: the type of notification to request
344 * 338 *
345 * Returns 0 for success. 339 * Returns 0 for success.
346 * 340 *
347 * This may be called from interrupt context. Also called by 341 * This may be called from interrupt context. Also called by
348 * ib_req_notify_cq() in the generic verbs code. 342 * ib_req_notify_cq() in the generic verbs code.
349 */ 343 */
350int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) 344int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags)
351{ 345{
352 struct ipath_cq *cq = to_icq(ibcq); 346 struct ipath_cq *cq = to_icq(ibcq);
353 unsigned long flags; 347 unsigned long flags;
348 int ret = 0;
354 349
355 spin_lock_irqsave(&cq->lock, flags); 350 spin_lock_irqsave(&cq->lock, flags);
356 /* 351 /*
@@ -358,9 +353,15 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
358 * any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2). 353 * any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2).
359 */ 354 */
360 if (cq->notify != IB_CQ_NEXT_COMP) 355 if (cq->notify != IB_CQ_NEXT_COMP)
361 cq->notify = notify; 356 cq->notify = notify_flags & IB_CQ_SOLICITED_MASK;
357
358 if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) &&
359 cq->queue->head != cq->queue->tail)
360 ret = 1;
361
362 spin_unlock_irqrestore(&cq->lock, flags); 362 spin_unlock_irqrestore(&cq->lock, flags);
363 return 0; 363
364 return ret;
364} 365}
365 366
366/** 367/**
@@ -443,13 +444,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
443 if (cq->ip) { 444 if (cq->ip) {
444 struct ipath_ibdev *dev = to_idev(ibcq->device); 445 struct ipath_ibdev *dev = to_idev(ibcq->device);
445 struct ipath_mmap_info *ip = cq->ip; 446 struct ipath_mmap_info *ip = cq->ip;
447 u32 s = sizeof *wc + sizeof(struct ib_wc) * cqe;
446 448
447 ip->obj = wc; 449 ipath_update_mmap_info(dev, ip, s, wc);
448 ip->size = PAGE_ALIGN(sizeof(*wc) +
449 sizeof(struct ib_wc) * cqe);
450 spin_lock_irq(&dev->pending_lock); 450 spin_lock_irq(&dev->pending_lock);
451 ip->next = dev->pending_mmaps; 451 if (list_empty(&ip->pending_mmaps))
452 dev->pending_mmaps = ip; 452 list_add(&ip->pending_mmaps, &dev->pending_mmaps);
453 spin_unlock_irq(&dev->pending_lock); 453 spin_unlock_irq(&dev->pending_lock);
454 } 454 }
455 455