Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9efe10a1 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier
Browse files

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: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 976d1676
Loading
Loading
Loading
Loading
+33 −8
Original line number Diff line number Diff line
@@ -376,10 +376,8 @@ struct uld_ctx {
	struct c4iw_dev *dev;
};

static void c4iw_remove(struct uld_ctx *ctx)
static void c4iw_dealloc(struct uld_ctx *ctx)
{
	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
	c4iw_unregister_device(ctx->dev);
	c4iw_rdev_close(&ctx->dev->rdev);
	idr_destroy(&ctx->dev->cqidr);
	idr_destroy(&ctx->dev->qpidr);
@@ -389,11 +387,30 @@ static void c4iw_remove(struct uld_ctx *ctx)
	ctx->dev = NULL;
}

static void c4iw_remove(struct uld_ctx *ctx)
{
	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
	c4iw_unregister_device(ctx->dev);
	c4iw_dealloc(ctx);
}

static int rdma_supported(const struct cxgb4_lld_info *infop)
{
	return infop->vr->stag.size > 0 && infop->vr->pbl.size > 0 &&
	       infop->vr->rq.size > 0 && infop->vr->qp.size > 0 &&
	       infop->vr->cq.size > 0 && infop->vr->ocq.size > 0;
}

static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
{
	struct c4iw_dev *devp;
	int ret;

	if (!rdma_supported(infop)) {
		printk(KERN_INFO MOD "%s: RDMA not supported on this device.\n",
		       pci_name(infop->pdev));
		return ERR_PTR(-ENOSYS);
	}
	devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
	if (!devp) {
		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)

	ret = c4iw_rdev_open(&devp->rdev);
	if (ret) {
		mutex_unlock(&dev_mutex);
		printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret);
		ib_dealloc_device(&devp->ibdev);
		return ERR_PTR(ret);
@@ -519,15 +535,24 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
	case CXGB4_STATE_UP:
		printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev));
		if (!ctx->dev) {
			int ret = 0;
			int ret;

			ctx->dev = c4iw_alloc(&ctx->lldi);
			if (!IS_ERR(ctx->dev))
			if (IS_ERR(ctx->dev)) {
				printk(KERN_ERR MOD
				       "%s: initialization failed: %ld\n",
				       pci_name(ctx->lldi.pdev),
				       PTR_ERR(ctx->dev));
				ctx->dev = NULL;
				break;
			}
			ret = c4iw_register_device(ctx->dev);
			if (IS_ERR(ctx->dev) || ret)
			if (ret) {
				printk(KERN_ERR MOD
				       "%s: RDMA registration failed: %d\n",
				       pci_name(ctx->lldi.pdev), ret);
				c4iw_dealloc(ctx);
			}
		}
		break;
	case CXGB4_STATE_DOWN: