drivers/infiniband/core/uverbs_uapi.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/uverbs_uapi.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/uverbs_uapi.c
Extension
.c
Size
18989 bytes
Lines
750
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

* struct file_operations.owner to prevent the driver module
		 * code from unloading while the file is open. This provides
		 * enough safety that uverbs_uobject_fd_release() will
		 * continue to work.  Drivers using FD are responsible to
		 * handle disassociation of the device on their own.
		 */
		if (WARN_ON(is_driver &&
			    obj->type_attrs->type_class != &uverbs_idr_class &&
			    obj->type_attrs->type_class != &uverbs_fd_class))
			return -EINVAL;
	}

	if (!obj->methods)
		return 0;

	for (i = 0; i != obj->num_methods; i++) {
		const struct uverbs_method_def *method = (*obj->methods)[i];

		if (!method)
			continue;

		rc = uapi_merge_method(uapi, obj_elm, obj_key, method,
				       is_driver);
		if (rc)
			return rc;
	}

	return 0;
}

static int uapi_disable_elm(struct uverbs_api *uapi,
			    const struct uapi_definition *def,
			    u32 obj_key,
			    u32 method_key)
{
	bool exists;

	if (def->scope == UAPI_SCOPE_OBJECT) {
		struct uverbs_api_object *obj_elm;

		obj_elm = uapi_add_get_elm(
			uapi, obj_key, sizeof(*obj_elm), &exists);
		if (IS_ERR(obj_elm))
			return PTR_ERR(obj_elm);
		obj_elm->disabled = 1;
		return 0;
	}

	if (def->scope == UAPI_SCOPE_METHOD &&
	    uapi_key_is_ioctl_method(method_key)) {
		struct uverbs_api_ioctl_method *method_elm;

		method_elm = uapi_add_get_elm(uapi, method_key,
					      sizeof(*method_elm), &exists);
		if (IS_ERR(method_elm))
			return PTR_ERR(method_elm);
		method_elm->disabled = 1;
		return 0;
	}

	if (def->scope == UAPI_SCOPE_METHOD &&
	    (uapi_key_is_write_method(method_key) ||
	     uapi_key_is_write_ex_method(method_key))) {
		struct uverbs_api_write_method *write_elm;

		write_elm = uapi_add_get_elm(uapi, method_key,
					     sizeof(*write_elm), &exists);
		if (IS_ERR(write_elm))
			return PTR_ERR(write_elm);
		write_elm->disabled = 1;
		return 0;
	}

	WARN_ON(true);
	return -EINVAL;
}

static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
			  const struct uapi_definition *def_list,
			  bool is_driver)
{
	const struct uapi_definition *def = def_list;
	u32 cur_obj_key = UVERBS_API_KEY_ERR;
	u32 cur_method_key = UVERBS_API_KEY_ERR;
	bool exists;
	int rc;

	if (!def_list)
		return 0;

Annotation

Implementation Notes