diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_cq.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_cq.c | 68 |
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 | */ |
207 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, | 207 | struct 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 | ||
298 | bail_ip: | ||
299 | kfree(cq->ip); | ||
304 | bail_wc: | 300 | bail_wc: |
305 | vfree(wc); | 301 | vfree(wc); |
306 | |||
307 | bail_cq: | 302 | bail_cq: |
308 | kfree(cq); | 303 | kfree(cq); |
309 | |||
310 | done: | 304 | done: |
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 | */ |
350 | int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) | 344 | int 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 | ||