sound/virtio/virtio_ctl_msg.c

Source file repositories/reference/linux-study-clean/sound/virtio/virtio_ctl_msg.c

File Facts

System
Linux kernel
Corpus path
sound/virtio/virtio_ctl_msg.c
Extension
.c
Size
7865 bytes
Lines
304
Domain
Driver Families
Bucket
sound/virtio
Inferred role
Driver Families: implementation source
Status
source 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 virtio_snd_msg {
	struct scatterlist sg_request;
	struct scatterlist sg_response;
	struct list_head list;
	struct completion notify;
	refcount_t ref_count;
};

/**
 * virtsnd_ctl_msg_ref() - Increment reference counter for the message.
 * @msg: Control message.
 *
 * Context: Any context.
 */
void virtsnd_ctl_msg_ref(struct virtio_snd_msg *msg)
{
	refcount_inc(&msg->ref_count);
}

/**
 * virtsnd_ctl_msg_unref() - Decrement reference counter for the message.
 * @msg: Control message.
 *
 * The message will be freed when the ref_count value is 0.
 *
 * Context: Any context.
 */
void virtsnd_ctl_msg_unref(struct virtio_snd_msg *msg)
{
	if (refcount_dec_and_test(&msg->ref_count))
		kfree(msg);
}

/**
 * virtsnd_ctl_msg_request() - Get a pointer to the request header.
 * @msg: Control message.
 *
 * Context: Any context.
 */
void *virtsnd_ctl_msg_request(struct virtio_snd_msg *msg)
{
	return sg_virt(&msg->sg_request);
}

/**
 * virtsnd_ctl_msg_response() - Get a pointer to the response header.
 * @msg: Control message.
 *
 * Context: Any context.
 */
void *virtsnd_ctl_msg_response(struct virtio_snd_msg *msg)
{
	return sg_virt(&msg->sg_response);
}

/**
 * virtsnd_ctl_msg_alloc() - Allocate and initialize a control message.
 * @request_size: Size of request header.
 * @response_size: Size of response header.
 * @gfp: Kernel flags for memory allocation.
 *
 * The message will be automatically freed when the ref_count value is 0.
 *
 * Context: Any context. May sleep if @gfp flags permit.
 * Return: Allocated message on success, NULL on failure.
 */
struct virtio_snd_msg *virtsnd_ctl_msg_alloc(size_t request_size,
					     size_t response_size, gfp_t gfp)
{
	struct virtio_snd_msg *msg;

	if (!request_size || !response_size)
		return NULL;

	msg = kzalloc(sizeof(*msg) + request_size + response_size, gfp);
	if (!msg)
		return NULL;

	sg_init_one(&msg->sg_request, (u8 *)msg + sizeof(*msg), request_size);
	sg_init_one(&msg->sg_response, (u8 *)msg + sizeof(*msg) + request_size,
		    response_size);

	INIT_LIST_HEAD(&msg->list);
	init_completion(&msg->notify);
	/* This reference is dropped in virtsnd_ctl_msg_complete(). */
	refcount_set(&msg->ref_count, 1);

	return msg;
}

Annotation

Implementation Notes