in mailbox-test.c [162:232]
static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct mbox_test_device *tdev = filp->private_data;
unsigned long flags;
char *touser, *ptr;
int l = 0;
int ret;
DECLARE_WAITQUEUE(wait, current);
touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
if (!touser)
return -ENOMEM;
if (!tdev->rx_channel) {
ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
ret = simple_read_from_buffer(userbuf, count, ppos,
touser, ret);
goto kfree_err;
}
add_wait_queue(&tdev->waitq, &wait);
do {
__set_current_state(TASK_INTERRUPTIBLE);
if (mbox_test_message_data_ready(tdev))
break;
if (filp->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
goto waitq_err;
}
if (signal_pending(current)) {
ret = -ERESTARTSYS;
goto waitq_err;
}
schedule();
} while (1);
spin_lock_irqsave(&tdev->lock, flags);
ptr = tdev->rx_buffer;
while (l < MBOX_HEXDUMP_MAX_LEN) {
hex_dump_to_buffer(ptr,
MBOX_BYTES_PER_LINE,
MBOX_BYTES_PER_LINE, 1, touser + l,
MBOX_HEXDUMP_LINE_LEN, true);
ptr += MBOX_BYTES_PER_LINE;
l += MBOX_HEXDUMP_LINE_LEN;
*(touser + (l - 1)) = '\n';
}
*(touser + l) = '\0';
memset(tdev->rx_buffer, 0, MBOX_MAX_MSG_LEN);
mbox_data_ready = false;
spin_unlock_irqrestore(&tdev->lock, flags);
ret = simple_read_from_buffer(userbuf, count, ppos, touser, MBOX_HEXDUMP_MAX_LEN);
waitq_err:
__set_current_state(TASK_RUNNING);
remove_wait_queue(&tdev->waitq, &wait);
kfree_err:
kfree(touser);
return ret;
}