forked from Minki/linux
Staging driver fixes for 3.15-rc8
Here are some staging driver fixes for 3.15. 3 are for the speakup drivers (one fix a regression caused in 3.15-rc, and the other 2 resolve a tty issue found by Ben Hutchings) The comedi and r8192e_pci driver fixes also resolve reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEABECAAYFAlOM9eUACgkQMUfUDdst+ykETACbBTSOZVE1pAIKGjGY2bcOtQET yKMAnil04hAbmz5L/5TNvdkUWu+7SfGi =K8cr -----END PGP SIGNATURE----- Merge tag 'staging-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging 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
This commit is contained in:
commit
da579dd6a1
@ -139,6 +139,8 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
|
||||
/* write channel to multiplexer */
|
||||
/* set mask scan bit high to disable scanning */
|
||||
outb(chan | 0x80, dev->iobase + CMD_R1);
|
||||
/* mux needs 2us to really settle [Fred Brooks]. */
|
||||
udelay(2);
|
||||
|
||||
/* convert n samples */
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
|
@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto)
|
||||
snap->oui[1] = oui[1];
|
||||
snap->oui[2] = oui[2];
|
||||
|
||||
*(u16 *)(data + SNAP_SIZE) = h_proto;
|
||||
*(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
|
||||
|
||||
return SNAP_SIZE + sizeof(u16);
|
||||
}
|
||||
|
@ -2218,6 +2218,7 @@ static void __exit speakup_exit(void)
|
||||
unregister_keyboard_notifier(&keyboard_notifier_block);
|
||||
unregister_vt_notifier(&vt_notifier_block);
|
||||
speakup_unregister_devsynth();
|
||||
speakup_cancel_paste();
|
||||
del_timer(&cursor_timer);
|
||||
kthread_stop(speakup_task);
|
||||
speakup_task = NULL;
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/device.h> /* for dev_warn */
|
||||
#include <linux/selection.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
|
||||
#include "speakup.h"
|
||||
|
||||
@ -121,31 +125,61 @@ int speakup_set_selection(struct tty_struct *tty)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: move to some helper thread, probably. That'd fix having to check for
|
||||
* in_atomic(). */
|
||||
int speakup_paste_selection(struct tty_struct *tty)
|
||||
struct speakup_paste_work {
|
||||
struct work_struct work;
|
||||
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;
|
||||
int pasted = 0, count;
|
||||
struct tty_ldisc *ld;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
ld = tty_ldisc_ref_wait(tty);
|
||||
tty_buffer_lock_exclusive(&vc->port);
|
||||
|
||||
add_wait_queue(&vc->paste_wait, &wait);
|
||||
while (sel_buffer && sel_buffer_lth > pasted) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (test_bit(TTY_THROTTLED, &tty->flags)) {
|
||||
if (in_atomic())
|
||||
/* if we are in an interrupt handler, abort */
|
||||
break;
|
||||
schedule();
|
||||
continue;
|
||||
}
|
||||
count = sel_buffer_lth - pasted;
|
||||
count = min_t(int, count, tty->receive_room);
|
||||
tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
|
||||
NULL, count);
|
||||
count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,
|
||||
count);
|
||||
pasted += count;
|
||||
}
|
||||
remove_wait_queue(&vc->paste_wait, &wait);
|
||||
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;
|
||||
}
|
||||
|
||||
void speakup_cancel_paste(void)
|
||||
{
|
||||
cancel_work_sync(&speakup_paste_work.work);
|
||||
tty_kref_put(speakup_paste_work.tty);
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ extern void synth_buffer_clear(void);
|
||||
extern void speakup_clear_selection(void);
|
||||
extern int speakup_set_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_unregister_devsynth(void);
|
||||
extern void synth_write(const char *buf, size_t count);
|
||||
|
@ -60,15 +60,15 @@ static struct kobj_attribute vol_attribute =
|
||||
__ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
|
||||
|
||||
static struct kobj_attribute delay_time_attribute =
|
||||
__ATTR(delay_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
__ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
static struct kobj_attribute direct_attribute =
|
||||
__ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
|
||||
static struct kobj_attribute full_time_attribute =
|
||||
__ATTR(full_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
__ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
static struct kobj_attribute jiffy_delta_attribute =
|
||||
__ATTR(jiffy_delta, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
__ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
static struct kobj_attribute trigger_time_attribute =
|
||||
__ATTR(trigger_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
__ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
|
||||
|
||||
/*
|
||||
* Create a group of attributes so that we can create and destroy them all
|
||||
|
@ -60,6 +60,7 @@ void tty_buffer_lock_exclusive(struct tty_port *port)
|
||||
atomic_inc(&buf->priority);
|
||||
mutex_lock(&buf->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive);
|
||||
|
||||
void tty_buffer_unlock_exclusive(struct tty_port *port)
|
||||
{
|
||||
@ -73,6 +74,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
|
||||
if (restart)
|
||||
queue_work(system_unbound_wq, &buf->work);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
|
||||
|
||||
/**
|
||||
* tty_buffer_space_avail - return unused buffer space
|
||||
|
Loading…
Reference in New Issue
Block a user