drivers/mailbox/mailbox-test.c

Source file repositories/reference/linux-study-clean/drivers/mailbox/mailbox-test.c

File Facts

System
Linux kernel
Corpus path
drivers/mailbox/mailbox-test.c
Extension
.c
Size
11393 bytes
Lines
464
Domain
Driver Families
Bucket
drivers/mailbox
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

static const struct file_operations mbox_test_signal_ops = {
	.write	= mbox_test_signal_write,
	.open	= simple_open,
	.llseek	= generic_file_llseek,
};

static int mbox_test_message_fasync(int fd, struct file *filp, int on)
{
	struct mbox_test_device *tdev = filp->private_data;

	return fasync_helper(fd, filp, on, &tdev->async_queue);
}

static ssize_t mbox_test_message_write(struct file *filp,
				       const char __user *userbuf,
				       size_t count, loff_t *ppos)
{
	struct mbox_test_device *tdev = filp->private_data;
	char *message;
	void *data;
	int ret;

	if (!tdev->tx_channel) {
		dev_err(tdev->dev, "Channel cannot do Tx\n");
		return -EINVAL;
	}

	if (count > MBOX_MAX_MSG_LEN) {
		dev_err(tdev->dev,
			"Message length %zd greater than max allowed %d\n",
			count, MBOX_MAX_MSG_LEN);
		return -EINVAL;
	}

	message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
	if (!message)
		return -ENOMEM;

	mutex_lock(&tdev->mutex);

	tdev->message = message;
	ret = copy_from_user(tdev->message, userbuf, count);
	if (ret) {
		ret = -EFAULT;
		goto out;
	}

	/*
	 * A separate signal is only of use if there is
	 * MMIO to subsequently pass the message through
	 */
	if (tdev->tx_mmio && tdev->signal) {
		print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
				     tdev->signal, MBOX_MAX_SIG_LEN);

		data = tdev->signal;
	} else
		data = tdev->message;

	print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
			     tdev->message, MBOX_MAX_MSG_LEN);

	ret = mbox_send_message(tdev->tx_channel, data);
	if (ret < 0)
		dev_err(tdev->dev, "Failed to send message via mailbox\n");

out:
	kfree(tdev->signal);
	kfree(tdev->message);
	tdev->signal = NULL;

	mutex_unlock(&tdev->mutex);

	return ret < 0 ? ret : count;
}

static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
{
	bool data_ready;
	unsigned long flags;

	spin_lock_irqsave(&tdev->lock, flags);
	data_ready = tdev->data_ready;
	spin_unlock_irqrestore(&tdev->lock, flags);

	return data_ready;
}

static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
				      size_t count, loff_t *ppos)

Annotation

Implementation Notes