Beispiel #1
0
static ssize_t softsynth_read(struct file *fp, char __user *buf, size_t count,
			      loff_t *pos)
{
	int chars_sent = 0;
	char __user *cp;
	char *init;
	char ch;
	int empty;
	unsigned long flags;
	DEFINE_WAIT(wait);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	while (1) {
		prepare_to_wait(&speakup_event, &wait, TASK_INTERRUPTIBLE);
		if (!synth_buffer_empty() || speakup_info.flushing)
			break;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (fp->f_flags & O_NONBLOCK) {
			finish_wait(&speakup_event, &wait);
			return -EAGAIN;
		}
		if (signal_pending(current)) {
			finish_wait(&speakup_event, &wait);
			return -ERESTARTSYS;
		}
		schedule();
		spin_lock_irqsave(&speakup_info.spinlock, flags);
	}
	finish_wait(&speakup_event, &wait);

	cp = buf;
	init = get_initstring();
	while (chars_sent < count) {
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			ch = '\x18';
		} else if (synth_buffer_empty()) {
			break;
		} else if (init[init_pos]) {
			ch = init[init_pos++];
		} else {
			ch = synth_buffer_getc();
		}
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (copy_to_user(cp, &ch, 1))
			return -EFAULT;
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		chars_sent++;
		cp++;
	}
	*pos += chars_sent;
	empty = synth_buffer_empty();
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	if (empty) {
		speakup_start_ttys();
		*pos = 0;
	}
	return chars_sent;
}
Beispiel #2
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val;
	int delay_time_val;

	jiffy_delta = get_var(JIFFY);
	delay_time = get_var(DELAY);
	spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);
	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		spk_unlock(flags);
		if (synth_full()) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spk_lock(flags);
		ch = synth_buffer_getc();
		spk_unlock(flags);
		if (ch == '\n')
			ch = PROCSPEECH;
		spk_out(ch);
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			spk_out(PROCSPEECH);
			spk_lock(flags);
			delay_time_val = delay_time->u.n.value;
			jiffy_delta_val = jiffy_delta->u.n.value;
			spk_unlock(flags);
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			jiff_max = jiffies + jiffy_delta_val;
		}
	}
	spk_out(PROCSPEECH);
}
static unsigned int softsynth_poll(struct file *fp,
		struct poll_table_struct *wait)
{
	unsigned long flags;
	int ret = 0;
	poll_wait(fp, &speakup_event, wait);

	spk_lock(flags);
	if (!synth_buffer_empty() || speakup_info.flushing)
		ret = POLLIN | POLLRDNORM;
	spk_unlock(flags);
	return ret;
}
Beispiel #4
0
int speakup_thread(void *data)
{
	unsigned long flags;
	int should_break;
	struct bleep our_sound;

	our_sound.active = 0;
	our_sound.freq = 0;
	our_sound.jiffies = 0;

	mutex_lock(&spk_mutex);
	while (1) {
		DEFINE_WAIT(wait);

		while (1) {
			spin_lock_irqsave(&speakup_info.spinlock, flags);
			our_sound = spk_unprocessed_sound;
			spk_unprocessed_sound.active = 0;
			prepare_to_wait(&speakup_event, &wait,
				TASK_INTERRUPTIBLE);
			should_break = kthread_should_stop() ||
				our_sound.active ||
				(synth && synth->catch_up && synth->alive &&
					(speakup_info.flushing ||
					!synth_buffer_empty()));
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			if (should_break)
				break;
			mutex_unlock(&spk_mutex);
			schedule();
			mutex_lock(&spk_mutex);
		}
		finish_wait(&speakup_event, &wait);
		if (kthread_should_stop())
			break;

		if (our_sound.active)
			kd_mksound(our_sound.freq, our_sound.jiffies);
		if (synth && synth->catch_up && synth->alive) {
			/* It is up to the callee to take the lock, so that it
			 * can sleep whenever it likes */
			synth->catch_up(synth);
		}

		speakup_start_ttys();
	}
	mutex_unlock(&spk_mutex);
	return 0;
}
Beispiel #5
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	int timeout;
	int delay_time_val;
	int jiffy_delta_val;
	int full_time_val;
	struct var_t *delay_time;
	struct var_t *full_time;
	struct var_t *jiffy_delta;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	full_time = spk_get_var(FULL);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (synth_full()) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		timeout = SPK_XMITR_TIMEOUT;
		while (synth_writable()) {
			if (!--timeout)
				break;
			udelay(1);
		}
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		ch = synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = PROCSPEECH;
		outb_p(ch, speakup_info.port_tts);
		if (time_after_eq(jiffies, jiff_max) && ch == SPACE) {
			timeout = SPK_XMITR_TIMEOUT;
			while (synth_writable()) {
				if (!--timeout)
					break;
				udelay(1);
			}
			outb_p(PROCSPEECH, speakup_info.port_tts);
			spin_lock_irqsave(&speakup_info.spinlock, flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			jiff_max = jiffies+jiffy_delta_val;
		}
	}
	timeout = SPK_XMITR_TIMEOUT;
	while (synth_writable()) {
		if (!--timeout)
			break;
		udelay(1);
	}
	outb_p(PROCSPEECH, speakup_info.port_tts);
}
Beispiel #6
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	static u_char last;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val;
	int delay_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = 0x0D;
		if (dt_sendchar(ch)) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '[')
			in_escape = 1;
		else if (ch == ']')
			in_escape = 0;
		else if (ch <= SPACE) {
			if (!in_escape && strchr(",.!?;:", last))
				dt_sendchar(PROCSPEECH);
			if (jiffies >= jiff_max) {
				if (!in_escape)
					dt_sendchar(PROCSPEECH);
				spin_lock_irqsave(&speakup_info.spinlock, flags);
				jiffy_delta_val = jiffy_delta->u.n.value;
				delay_time_val = delay_time->u.n.value;
				spin_unlock_irqrestore(&speakup_info.spinlock, flags);
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
				jiff_max = jiffies + jiffy_delta_val;
			}
		}
		last = ch;
		ch = 0;
	}
	if (!in_escape)
		dt_sendchar(PROCSPEECH);
}
static void do_catch_up(struct spk_synth *synth)
{
	int synth_full_val = 0;
	static u_char ch;
	static u_char last = '\0';
	unsigned long flags;
	unsigned long jiff_max;
	unsigned long timeout = msecs_to_jiffies(4000);
	DEFINE_WAIT(wait);
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val;
	int delay_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		/* if no ctl-a in 4, send data anyway */
		spin_lock_irqsave(&flush_lock, flags);
		while (is_flushing && timeout) {
			prepare_to_wait(&flush, &wait, TASK_INTERRUPTIBLE);
			spin_unlock_irqrestore(&flush_lock, flags);
			timeout = schedule_timeout(timeout);
			spin_lock_irqsave(&flush_lock, flags);
		}
		finish_wait(&flush, &wait);
		is_flushing = 0;
		spin_unlock_irqrestore(&flush_lock, flags);

		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		synth_full_val = synth_full();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = 0x0D;
		if (synth_full_val || !spk_serial_out(ch)) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '[')
			in_escape = 1;
		else if (ch == ']')
			in_escape = 0;
		else if (ch <= SPACE) {
			if (!in_escape && strchr(",.!?;:", last))
				spk_serial_out(PROCSPEECH);
			if (jiffies >= jiff_max) {
				if (!in_escape)
					spk_serial_out(PROCSPEECH);
				spin_lock_irqsave(&speakup_info.spinlock,
						flags);
				jiffy_delta_val = jiffy_delta->u.n.value;
				delay_time_val = delay_time->u.n.value;
				spin_unlock_irqrestore(&speakup_info.spinlock,
						flags);
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
				jiff_max = jiffies + jiffy_delta_val;
			}
		}
		last = ch;
	}
	if (!in_escape)
		spk_serial_out(PROCSPEECH);
}
Beispiel #8
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	struct var_t *full_time;
	int full_time_val = 0;
	int delay_time_val = 0;
	int jiffy_delta_val = 0;

	jiffy_delta = get_var(JIFFY);
	delay_time = get_var(DELAY);
	full_time = get_var(FULL);
	spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		spk_lock(flags);
		jiffy_delta_val = jiffy_delta->u.n.value;
		full_time_val = full_time->u.n.value;
		delay_time_val = delay_time->u.n.value;
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spk_unlock(flags);
		if (!spk_serial_out(ch)) {
			outb(UART_MCR_DTR, speakup_info.port_tts + UART_MCR);
			outb(UART_MCR_DTR | UART_MCR_RTS,
					speakup_info.port_tts + UART_MCR);
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			spk_lock(flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			full_time_val = full_time->u.n.value;
			delay_time_val = delay_time->u.n.value;
			spk_unlock(flags);
			if (spk_serial_out(synth->procspeech))
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
			else
				schedule_timeout(msecs_to_jiffies
						 (full_time_val));
			jiff_max = jiffies + jiffy_delta_val;
		}
		set_current_state(TASK_RUNNING);
		spk_lock(flags);
		synth_buffer_getc();
		spk_unlock(flags);
	}
	spk_serial_out(PROCSPEECH);
}
Beispiel #9
0
/* Main loop of the progression thread: keep eating from the buffer
 * and push to the serial port, waiting as needed
 *
 * For devices that have a "full" notification mechanism, the driver can
 * adapt the loop the way they prefer.
 */
void spk_do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *delay_time;
	struct var_t *full_time;
	struct var_t *jiffy_delta;
	int jiffy_delta_val;
	int delay_time_val;
	int full_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	full_time = spk_get_var(FULL);
	delay_time = spk_get_var(DELAY);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = synth->procspeech;
		if (!spk_serial_out(ch)) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) {
			spin_lock_irqsave(&speakup_info.spinlock, flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			full_time_val = full_time->u.n.value;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			if (spk_serial_out(synth->procspeech))
				schedule_timeout(
					msecs_to_jiffies(delay_time_val));
			else
				schedule_timeout(
					msecs_to_jiffies(full_time_val));
			jiff_max = jiffies + jiffy_delta_val;
		}
		set_current_state(TASK_RUNNING);
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	}
	spk_serial_out(synth->procspeech);
}
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	int timeout;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	struct var_t *full_time;
	int delay_time_val;
	int full_time_val;
	int jiffy_delta_val;

	jiffy_delta = get_var(JIFFY);
	delay_time = get_var(DELAY);
	full_time = get_var(FULL);
spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spk_unlock(flags);
		if (synth_full()) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		timeout = 1000;
		while (synth_writable())
			if (--timeout <= 0)
				break;
		if (timeout <= 0) {
			oops();
			break;
		}
		spk_lock(flags);
		ch = synth_buffer_getc();
		spk_unlock(flags);
		if (ch == '\n')
			ch = PROCSPEECH;
		outb_p(ch, synth_port);
		SWAIT;
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			timeout = 1000;
			while (synth_writable())
				if (--timeout <= 0)
					break;
			if (timeout <= 0) {
				oops();
				break;
			}
			outb_p(PROCSPEECH, synth_port);
			spk_lock(flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			spk_unlock(flags);
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			jiff_max = jiffies+jiffy_delta_val;
		}
	}
	timeout = 1000;
	while (synth_writable())
		if (--timeout <= 0)
			break;
	if (timeout <= 0)
		oops();
	else
		outb_p(PROCSPEECH, synth_port);
}