diff options
author | Steve Wise <swise@opengridcomputing.com> | 2011-10-06 12:32:44 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2011-10-06 12:32:44 -0400 |
commit | 9efe10a1e1a1ab1dba0af0f520e0697f6e81ebf1 (patch) | |
tree | 1c5d3c84ee7cdb3c0d668ce5ce77217242c078bc /drivers/infiniband | |
parent | 976d167615b64e14bc1491ca51d424e2ba9a5e84 (diff) |
RDMA/cxgb4: Fail RDMA initialization for unsupported cards
The iw_cxgb4 module crashes at init time if the T4 card does not
support RDMA. So clean up the init logic to correctly deal with
non-RDMA cards.
- If any RDMA resources are not available, then fail the initialization
logging an info message.
- Clean up properly on initialization failures.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 40a13cc633a3..6d0df6ec161b 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
@@ -376,10 +376,8 @@ struct uld_ctx { | |||
376 | struct c4iw_dev *dev; | 376 | struct c4iw_dev *dev; |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static void c4iw_remove(struct uld_ctx *ctx) | 379 | static void c4iw_dealloc(struct uld_ctx *ctx) |
380 | { | 380 | { |
381 | PDBG("%s c4iw_dev %p\n", __func__, ctx->dev); | ||
382 | c4iw_unregister_device(ctx->dev); | ||
383 | c4iw_rdev_close(&ctx->dev->rdev); | 381 | c4iw_rdev_close(&ctx->dev->rdev); |
384 | idr_destroy(&ctx->dev->cqidr); | 382 | idr_destroy(&ctx->dev->cqidr); |
385 | idr_destroy(&ctx->dev->qpidr); | 383 | idr_destroy(&ctx->dev->qpidr); |
@@ -389,11 +387,30 @@ static void c4iw_remove(struct uld_ctx *ctx) | |||
389 | ctx->dev = NULL; | 387 | ctx->dev = NULL; |
390 | } | 388 | } |
391 | 389 | ||
390 | static void c4iw_remove(struct uld_ctx *ctx) | ||
391 | { | ||
392 | PDBG("%s c4iw_dev %p\n", __func__, ctx->dev); | ||
393 | c4iw_unregister_device(ctx->dev); | ||
394 | c4iw_dealloc(ctx); | ||
395 | } | ||
396 | |||
397 | static int rdma_supported(const struct cxgb4_lld_info *infop) | ||
398 | { | ||
399 | return infop->vr->stag.size > 0 && infop->vr->pbl.size > 0 && | ||
400 | infop->vr->rq.size > 0 && infop->vr->qp.size > 0 && | ||
401 | infop->vr->cq.size > 0 && infop->vr->ocq.size > 0; | ||
402 | } | ||
403 | |||
392 | static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | 404 | static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) |
393 | { | 405 | { |
394 | struct c4iw_dev *devp; | 406 | struct c4iw_dev *devp; |
395 | int ret; | 407 | int ret; |
396 | 408 | ||
409 | if (!rdma_supported(infop)) { | ||
410 | printk(KERN_INFO MOD "%s: RDMA not supported on this device.\n", | ||
411 | pci_name(infop->pdev)); | ||
412 | return ERR_PTR(-ENOSYS); | ||
413 | } | ||
397 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); | 414 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); |
398 | if (!devp) { | 415 | if (!devp) { |
399 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); | 416 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); |
@@ -414,7 +431,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
414 | 431 | ||
415 | ret = c4iw_rdev_open(&devp->rdev); | 432 | ret = c4iw_rdev_open(&devp->rdev); |
416 | if (ret) { | 433 | if (ret) { |
417 | mutex_unlock(&dev_mutex); | ||
418 | printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret); | 434 | printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret); |
419 | ib_dealloc_device(&devp->ibdev); | 435 | ib_dealloc_device(&devp->ibdev); |
420 | return ERR_PTR(ret); | 436 | return ERR_PTR(ret); |
@@ -519,15 +535,24 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) | |||
519 | case CXGB4_STATE_UP: | 535 | case CXGB4_STATE_UP: |
520 | printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev)); | 536 | printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev)); |
521 | if (!ctx->dev) { | 537 | if (!ctx->dev) { |
522 | int ret = 0; | 538 | int ret; |
523 | 539 | ||
524 | ctx->dev = c4iw_alloc(&ctx->lldi); | 540 | ctx->dev = c4iw_alloc(&ctx->lldi); |
525 | if (!IS_ERR(ctx->dev)) | 541 | if (IS_ERR(ctx->dev)) { |
526 | ret = c4iw_register_device(ctx->dev); | 542 | printk(KERN_ERR MOD |
527 | if (IS_ERR(ctx->dev) || ret) | 543 | "%s: initialization failed: %ld\n", |
544 | pci_name(ctx->lldi.pdev), | ||
545 | PTR_ERR(ctx->dev)); | ||
546 | ctx->dev = NULL; | ||
547 | break; | ||
548 | } | ||
549 | ret = c4iw_register_device(ctx->dev); | ||
550 | if (ret) { | ||
528 | printk(KERN_ERR MOD | 551 | printk(KERN_ERR MOD |
529 | "%s: RDMA registration failed: %d\n", | 552 | "%s: RDMA registration failed: %d\n", |
530 | pci_name(ctx->lldi.pdev), ret); | 553 | pci_name(ctx->lldi.pdev), ret); |
554 | c4iw_dealloc(ctx); | ||
555 | } | ||
531 | } | 556 | } |
532 | break; | 557 | break; |
533 | case CXGB4_STATE_DOWN: | 558 | case CXGB4_STATE_DOWN: |