Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da579dd6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull staging driver fixes from Greg KH:
 "Here are some staging driver fixes for 3.15.

  Three are for the speakup drivers (one fixes a regression caused in
  3.15-rc, and the other two resolve a tty issue found by Ben Hutchings)
  The comedi and r8192e_pci driver fixes also resolve reported issues"

* tag 'staging-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: r8192e_pci: fix htons error
  Staging: speakup: Update __speakup_paste_selection() tty (ab)usage to match vt
  Staging: speakup: Move pasting into a work item
  staging: comedi: ni_daq_700: add mux settling delay
  speakup: fix incorrect perms on speakup_acntsa.c
parents fad01e86 9326c5ca
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -139,6 +139,8 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
	/* write channel to multiplexer */
	/* write channel to multiplexer */
	/* set mask scan bit high to disable scanning */
	/* set mask scan bit high to disable scanning */
	outb(chan | 0x80, dev->iobase + CMD_R1);
	outb(chan | 0x80, dev->iobase + CMD_R1);
	/* mux needs 2us to really settle [Fred Brooks]. */
	udelay(2);


	/* convert n samples */
	/* convert n samples */
	for (n = 0; n < insn->n; n++) {
	for (n = 0; n < insn->n; n++) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto)
	snap->oui[1] = oui[1];
	snap->oui[1] = oui[1];
	snap->oui[2] = oui[2];
	snap->oui[2] = oui[2];


	*(u16 *)(data + SNAP_SIZE) = h_proto;
	*(__be16 *)(data + SNAP_SIZE) = htons(h_proto);


	return SNAP_SIZE + sizeof(u16);
	return SNAP_SIZE + sizeof(u16);
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -2218,6 +2218,7 @@ static void __exit speakup_exit(void)
	unregister_keyboard_notifier(&keyboard_notifier_block);
	unregister_keyboard_notifier(&keyboard_notifier_block);
	unregister_vt_notifier(&vt_notifier_block);
	unregister_vt_notifier(&vt_notifier_block);
	speakup_unregister_devsynth();
	speakup_unregister_devsynth();
	speakup_cancel_paste();
	del_timer(&cursor_timer);
	del_timer(&cursor_timer);
	kthread_stop(speakup_task);
	kthread_stop(speakup_task);
	speakup_task = NULL;
	speakup_task = NULL;
+43 −9
Original line number Original line Diff line number Diff line
@@ -4,6 +4,10 @@
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/device.h> /* for dev_warn */
#include <linux/device.h> /* for dev_warn */
#include <linux/selection.h>
#include <linux/selection.h>
#include <linux/workqueue.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <asm/cmpxchg.h>


#include "speakup.h"
#include "speakup.h"


@@ -121,31 +125,61 @@ int speakup_set_selection(struct tty_struct *tty)
	return 0;
	return 0;
}
}


/* TODO: move to some helper thread, probably.  That'd fix having to check for
struct speakup_paste_work {
 * in_atomic().  */
	struct work_struct work;
int speakup_paste_selection(struct tty_struct *tty)
	struct tty_struct *tty;
};

static void __speakup_paste_selection(struct work_struct *work)
{
{
	struct speakup_paste_work *spw =
		container_of(work, struct speakup_paste_work, work);
	struct tty_struct *tty = xchg(&spw->tty, NULL);
	struct vc_data *vc = (struct vc_data *) tty->driver_data;
	struct vc_data *vc = (struct vc_data *) tty->driver_data;
	int pasted = 0, count;
	int pasted = 0, count;
	struct tty_ldisc *ld;
	DECLARE_WAITQUEUE(wait, current);
	DECLARE_WAITQUEUE(wait, current);

	ld = tty_ldisc_ref_wait(tty);
	tty_buffer_lock_exclusive(&vc->port);

	add_wait_queue(&vc->paste_wait, &wait);
	add_wait_queue(&vc->paste_wait, &wait);
	while (sel_buffer && sel_buffer_lth > pasted) {
	while (sel_buffer && sel_buffer_lth > pasted) {
		set_current_state(TASK_INTERRUPTIBLE);
		set_current_state(TASK_INTERRUPTIBLE);
		if (test_bit(TTY_THROTTLED, &tty->flags)) {
		if (test_bit(TTY_THROTTLED, &tty->flags)) {
			if (in_atomic())
				/* if we are in an interrupt handler, abort */
				break;
			schedule();
			schedule();
			continue;
			continue;
		}
		}
		count = sel_buffer_lth - pasted;
		count = sel_buffer_lth - pasted;
		count = min_t(int, count, tty->receive_room);
		count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,
		tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
					      count);
			NULL, count);
		pasted += count;
		pasted += count;
	}
	}
	remove_wait_queue(&vc->paste_wait, &wait);
	remove_wait_queue(&vc->paste_wait, &wait);
	current->state = TASK_RUNNING;
	current->state = TASK_RUNNING;

	tty_buffer_unlock_exclusive(&vc->port);
	tty_ldisc_deref(ld);
	tty_kref_put(tty);
}

static struct speakup_paste_work speakup_paste_work = {
	.work = __WORK_INITIALIZER(speakup_paste_work.work,
				   __speakup_paste_selection)
};

int speakup_paste_selection(struct tty_struct *tty)
{
	if (cmpxchg(&speakup_paste_work.tty, NULL, tty) != NULL)
		return -EBUSY;

	tty_kref_get(tty);
	schedule_work_on(WORK_CPU_UNBOUND, &speakup_paste_work.work);
	return 0;
	return 0;
}
}


void speakup_cancel_paste(void)
{
	cancel_work_sync(&speakup_paste_work.work);
	tty_kref_put(speakup_paste_work.tty);
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -75,6 +75,7 @@ extern void synth_buffer_clear(void);
extern void speakup_clear_selection(void);
extern void speakup_clear_selection(void);
extern int speakup_set_selection(struct tty_struct *tty);
extern int speakup_set_selection(struct tty_struct *tty);
extern int speakup_paste_selection(struct tty_struct *tty);
extern int speakup_paste_selection(struct tty_struct *tty);
extern void speakup_cancel_paste(void);
extern void speakup_register_devsynth(void);
extern void speakup_register_devsynth(void);
extern void speakup_unregister_devsynth(void);
extern void speakup_unregister_devsynth(void);
extern void synth_write(const char *buf, size_t count);
extern void synth_write(const char *buf, size_t count);
Loading