static ssize_t cs_char_read()

in clients/cmt_speech.c [1129:1174]


static ssize_t cs_char_read(struct file *file, char __user *buf, size_t count,
								loff_t *unused)
{
	struct cs_char *csdata = file->private_data;
	u32 data;
	ssize_t retval;

	if (count < sizeof(data))
		return -EINVAL;

	for (;;) {
		DEFINE_WAIT(wait);

		spin_lock_bh(&csdata->lock);
		if (!list_empty(&csdata->chardev_queue)) {
			data = cs_pop_entry(&csdata->chardev_queue);
		} else if (!list_empty(&csdata->dataind_queue)) {
			data = cs_pop_entry(&csdata->dataind_queue);
			csdata->dataind_pending--;
		} else {
			data = 0;
		}
		spin_unlock_bh(&csdata->lock);

		if (data)
			break;
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			goto out;
		} else if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			goto out;
		}
		prepare_to_wait_exclusive(&csdata->wait, &wait,
						TASK_INTERRUPTIBLE);
		schedule();
		finish_wait(&csdata->wait, &wait);
	}

	retval = put_user(data, (u32 __user *)buf);
	if (!retval)
		retval = sizeof(data);

out:
	return retval;
}