static int __afu_open(struct inode *inode, struct file *file, bool master) { struct cxl *adapter; struct cxl_afu *afu; struct cxl_context *ctx; int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev); int slice = CXL_DEVT_AFU(inode->i_rdev); int rc = -ENODEV; pr_devel("afu_open afu%i.%i\n", slice, adapter_num); if (!(adapter = get_cxl_adapter(adapter_num))) return -ENODEV; if (slice > adapter->slices) goto err_put_adapter; spin_lock(&adapter->afu_list_lock); if (!(afu = adapter->afu[slice])) { spin_unlock(&adapter->afu_list_lock); goto err_put_adapter; } get_device(&afu->dev); spin_unlock(&adapter->afu_list_lock); if (!afu->current_mode) goto err_put_afu; if (!(ctx = cxl_context_alloc())) { rc = -ENOMEM; goto err_put_afu; } if ((rc = cxl_context_init(ctx, afu, master, inode->i_mapping))) goto err_put_afu; pr_devel("afu_open pe: %i\n", ctx->pe); file->private_data = ctx; cxl_ctx_get(); /* Our ref on the AFU will now hold the adapter */ put_device(&adapter->dev); return 0; err_put_afu: put_device(&afu->dev); err_put_adapter: put_device(&adapter->dev); return rc; }
static int __afu_open(struct inode *inode, struct file *file, bool master) { struct cxl *adapter; struct cxl_afu *afu; struct cxl_context *ctx; int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev); int slice = CXL_DEVT_AFU(inode->i_rdev); int rc = -ENODEV; pr_devel("afu_open afu%i.%i\n", slice, adapter_num); if (!(adapter = get_cxl_adapter(adapter_num))) return -ENODEV; if (slice > adapter->slices) goto err_put_adapter; spin_lock(&adapter->afu_list_lock); if (!(afu = adapter->afu[slice])) { spin_unlock(&adapter->afu_list_lock); goto err_put_adapter; } /* * taking a ref to the afu so that it doesn't go away * for rest of the function. This ref is released before * we return. */ cxl_afu_get(afu); spin_unlock(&adapter->afu_list_lock); if (!afu->current_mode) goto err_put_afu; if (!cxl_ops->link_ok(adapter, afu)) { rc = -EIO; goto err_put_afu; } if (!(ctx = cxl_context_alloc())) { rc = -ENOMEM; goto err_put_afu; } rc = cxl_context_init(ctx, afu, master); if (rc) goto err_put_afu; cxl_context_set_mapping(ctx, inode->i_mapping); pr_devel("afu_open pe: %i\n", ctx->pe); file->private_data = ctx; cxl_ctx_get(); /* indicate success */ rc = 0; err_put_afu: /* release the ref taken earlier */ cxl_afu_put(afu); err_put_adapter: put_device(&adapter->dev); return rc; }