drivers/misc/vmw_vmci/vmci_datagram.c

Source file repositories/reference/linux-study-clean/drivers/misc/vmw_vmci/vmci_datagram.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/vmw_vmci/vmci_datagram.c
Extension
.c
Size
13868 bytes
Lines
497
Domain
Driver Families
Bucket
drivers/misc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 datagram_entry {
	struct vmci_resource resource;
	u32 flags;
	bool run_delayed;
	vmci_datagram_recv_cb recv_cb;
	void *client_data;
	u32 priv_flags;
};

struct delayed_datagram_info {
	struct datagram_entry *entry;
	struct work_struct work;
	bool in_dg_host_queue;
	/* msg and msg_payload must be together. */
	struct vmci_datagram msg;
	u8 msg_payload[];
};

/* Number of in-flight host->host datagrams */
static atomic_t delayed_dg_host_queue_size = ATOMIC_INIT(0);

/*
 * Create a datagram entry given a handle pointer.
 */
static int dg_create_handle(u32 resource_id,
			    u32 flags,
			    u32 priv_flags,
			    vmci_datagram_recv_cb recv_cb,
			    void *client_data, struct vmci_handle *out_handle)
{
	int result;
	u32 context_id;
	struct vmci_handle handle;
	struct datagram_entry *entry;

	if ((flags & VMCI_FLAG_WELLKNOWN_DG_HND) != 0)
		return VMCI_ERROR_INVALID_ARGS;

	if ((flags & VMCI_FLAG_ANYCID_DG_HND) != 0) {
		context_id = VMCI_INVALID_ID;
	} else {
		context_id = vmci_get_context_id();
		if (context_id == VMCI_INVALID_ID)
			return VMCI_ERROR_NO_RESOURCES;
	}

	handle = vmci_make_handle(context_id, resource_id);

	entry = kmalloc_obj(*entry);
	if (!entry) {
		pr_warn("Failed allocating memory for datagram entry\n");
		return VMCI_ERROR_NO_MEM;
	}

	entry->run_delayed = (flags & VMCI_FLAG_DG_DELAYED_CB) ? true : false;
	entry->flags = flags;
	entry->recv_cb = recv_cb;
	entry->client_data = client_data;
	entry->priv_flags = priv_flags;

	/* Make datagram resource live. */
	result = vmci_resource_add(&entry->resource,
				   VMCI_RESOURCE_TYPE_DATAGRAM,
				   handle);
	if (result != VMCI_SUCCESS) {
		pr_warn("Failed to add new resource (handle=0x%x:0x%x), error: %d\n",
			handle.context, handle.resource, result);
		kfree(entry);
		return result;
	}

	*out_handle = vmci_resource_handle(&entry->resource);
	return VMCI_SUCCESS;
}

/*
 * Internal utility function with the same purpose as
 * vmci_datagram_get_priv_flags that also takes a context_id.
 */
static int vmci_datagram_get_priv_flags(u32 context_id,
					struct vmci_handle handle,
					u32 *priv_flags)
{
	if (context_id == VMCI_INVALID_ID)
		return VMCI_ERROR_INVALID_ARGS;

	if (context_id == VMCI_HOST_CONTEXT_ID) {
		struct datagram_entry *src_entry;
		struct vmci_resource *resource;

Annotation

Implementation Notes