diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 19:55:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 19:55:18 -0400 |
commit | da579dd6a180693368ade74b3ac38701d35f686e (patch) | |
tree | 21d02a66dd18ee9d902a2e9ee38c928586cb0feb /drivers | |
parent | fad01e866afdbe01a1f3ec06a39c3a8b9e197014 (diff) | |
parent | 9326c5ca0982f548cc08c0cffb14dcbd020f3d43 (diff) |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/comedi/drivers/ni_daq_700.c | 2 | ||||
-rw-r--r-- | drivers/staging/rtl8192e/rtllib_tx.c | 2 | ||||
-rw-r--r-- | drivers/staging/speakup/main.c | 1 | ||||
-rw-r--r-- | drivers/staging/speakup/selection.c | 52 | ||||
-rw-r--r-- | drivers/staging/speakup/speakup.h | 1 | ||||
-rw-r--r-- | drivers/staging/speakup/speakup_acntsa.c | 8 | ||||
-rw-r--r-- | drivers/tty/tty_buffer.c | 2 |
7 files changed, 54 insertions, 14 deletions
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 171a71d20c88..728bf7f14f7b 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c | |||
@@ -139,6 +139,8 @@ static int daq700_ai_rinsn(struct comedi_device *dev, | |||
139 | /* write channel to multiplexer */ | 139 | /* write channel to multiplexer */ |
140 | /* set mask scan bit high to disable scanning */ | 140 | /* set mask scan bit high to disable scanning */ |
141 | outb(chan | 0x80, dev->iobase + CMD_R1); | 141 | outb(chan | 0x80, dev->iobase + CMD_R1); |
142 | /* mux needs 2us to really settle [Fred Brooks]. */ | ||
143 | udelay(2); | ||
142 | 144 | ||
143 | /* convert n samples */ | 145 | /* convert n samples */ |
144 | for (n = 0; n < insn->n; n++) { | 146 | for (n = 0; n < insn->n; n++) { |
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 11d0a9d8ee59..b7dd1539bbc4 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c | |||
@@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto) | |||
171 | snap->oui[1] = oui[1]; | 171 | snap->oui[1] = oui[1]; |
172 | snap->oui[2] = oui[2]; | 172 | snap->oui[2] = oui[2]; |
173 | 173 | ||
174 | *(u16 *)(data + SNAP_SIZE) = h_proto; | 174 | *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); |
175 | 175 | ||
176 | return SNAP_SIZE + sizeof(u16); | 176 | return SNAP_SIZE + sizeof(u16); |
177 | } | 177 | } |
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 3b6e5358c723..7de79d59a4cd 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c | |||
@@ -2218,6 +2218,7 @@ static void __exit speakup_exit(void) | |||
2218 | unregister_keyboard_notifier(&keyboard_notifier_block); | 2218 | unregister_keyboard_notifier(&keyboard_notifier_block); |
2219 | unregister_vt_notifier(&vt_notifier_block); | 2219 | unregister_vt_notifier(&vt_notifier_block); |
2220 | speakup_unregister_devsynth(); | 2220 | speakup_unregister_devsynth(); |
2221 | speakup_cancel_paste(); | ||
2221 | del_timer(&cursor_timer); | 2222 | del_timer(&cursor_timer); |
2222 | kthread_stop(speakup_task); | 2223 | kthread_stop(speakup_task); |
2223 | speakup_task = NULL; | 2224 | speakup_task = NULL; |
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index f0fb00392d6b..ca04d3669acc 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c | |||
@@ -4,6 +4,10 @@ | |||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/device.h> /* for dev_warn */ | 5 | #include <linux/device.h> /* for dev_warn */ |
6 | #include <linux/selection.h> | 6 | #include <linux/selection.h> |
7 | #include <linux/workqueue.h> | ||
8 | #include <linux/tty.h> | ||
9 | #include <linux/tty_flip.h> | ||
10 | #include <asm/cmpxchg.h> | ||
7 | 11 | ||
8 | #include "speakup.h" | 12 | #include "speakup.h" |
9 | 13 | ||
@@ -121,31 +125,61 @@ int speakup_set_selection(struct tty_struct *tty) | |||
121 | return 0; | 125 | return 0; |
122 | } | 126 | } |
123 | 127 | ||
124 | /* TODO: move to some helper thread, probably. That'd fix having to check for | 128 | struct speakup_paste_work { |
125 | * in_atomic(). */ | 129 | struct work_struct work; |
126 | int speakup_paste_selection(struct tty_struct *tty) | 130 | struct tty_struct *tty; |
131 | }; | ||
132 | |||
133 | static void __speakup_paste_selection(struct work_struct *work) | ||
127 | { | 134 | { |
135 | struct speakup_paste_work *spw = | ||
136 | container_of(work, struct speakup_paste_work, work); | ||
137 | struct tty_struct *tty = xchg(&spw->tty, NULL); | ||
128 | struct vc_data *vc = (struct vc_data *) tty->driver_data; | 138 | struct vc_data *vc = (struct vc_data *) tty->driver_data; |
129 | int pasted = 0, count; | 139 | int pasted = 0, count; |
140 | struct tty_ldisc *ld; | ||
130 | DECLARE_WAITQUEUE(wait, current); | 141 | DECLARE_WAITQUEUE(wait, current); |
142 | |||
143 | ld = tty_ldisc_ref_wait(tty); | ||
144 | tty_buffer_lock_exclusive(&vc->port); | ||
145 | |||
131 | add_wait_queue(&vc->paste_wait, &wait); | 146 | add_wait_queue(&vc->paste_wait, &wait); |
132 | while (sel_buffer && sel_buffer_lth > pasted) { | 147 | while (sel_buffer && sel_buffer_lth > pasted) { |
133 | set_current_state(TASK_INTERRUPTIBLE); | 148 | set_current_state(TASK_INTERRUPTIBLE); |
134 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 149 | if (test_bit(TTY_THROTTLED, &tty->flags)) { |
135 | if (in_atomic()) | ||
136 | /* if we are in an interrupt handler, abort */ | ||
137 | break; | ||
138 | schedule(); | 150 | schedule(); |
139 | continue; | 151 | continue; |
140 | } | 152 | } |
141 | count = sel_buffer_lth - pasted; | 153 | count = sel_buffer_lth - pasted; |
142 | count = min_t(int, count, tty->receive_room); | 154 | count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL, |
143 | tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | 155 | count); |
144 | NULL, count); | ||
145 | pasted += count; | 156 | pasted += count; |
146 | } | 157 | } |
147 | remove_wait_queue(&vc->paste_wait, &wait); | 158 | remove_wait_queue(&vc->paste_wait, &wait); |
148 | current->state = TASK_RUNNING; | 159 | current->state = TASK_RUNNING; |
160 | |||
161 | tty_buffer_unlock_exclusive(&vc->port); | ||
162 | tty_ldisc_deref(ld); | ||
163 | tty_kref_put(tty); | ||
164 | } | ||
165 | |||
166 | static struct speakup_paste_work speakup_paste_work = { | ||
167 | .work = __WORK_INITIALIZER(speakup_paste_work.work, | ||
168 | __speakup_paste_selection) | ||
169 | }; | ||
170 | |||
171 | int speakup_paste_selection(struct tty_struct *tty) | ||
172 | { | ||
173 | if (cmpxchg(&speakup_paste_work.tty, NULL, tty) != NULL) | ||
174 | return -EBUSY; | ||
175 | |||
176 | tty_kref_get(tty); | ||
177 | schedule_work_on(WORK_CPU_UNBOUND, &speakup_paste_work.work); | ||
149 | return 0; | 178 | return 0; |
150 | } | 179 | } |
151 | 180 | ||
181 | void speakup_cancel_paste(void) | ||
182 | { | ||
183 | cancel_work_sync(&speakup_paste_work.work); | ||
184 | tty_kref_put(speakup_paste_work.tty); | ||
185 | } | ||
diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index a7bcceec436a..898dce5e1243 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h | |||
@@ -75,6 +75,7 @@ extern void synth_buffer_clear(void); | |||
75 | extern void speakup_clear_selection(void); | 75 | extern void speakup_clear_selection(void); |
76 | extern int speakup_set_selection(struct tty_struct *tty); | 76 | extern int speakup_set_selection(struct tty_struct *tty); |
77 | extern int speakup_paste_selection(struct tty_struct *tty); | 77 | extern int speakup_paste_selection(struct tty_struct *tty); |
78 | extern void speakup_cancel_paste(void); | ||
78 | extern void speakup_register_devsynth(void); | 79 | extern void speakup_register_devsynth(void); |
79 | extern void speakup_unregister_devsynth(void); | 80 | extern void speakup_unregister_devsynth(void); |
80 | extern void synth_write(const char *buf, size_t count); | 81 | extern void synth_write(const char *buf, size_t count); |
diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c index c7f014ed9628..5079dbd5d7ad 100644 --- a/drivers/staging/speakup/speakup_acntsa.c +++ b/drivers/staging/speakup/speakup_acntsa.c | |||
@@ -60,15 +60,15 @@ static struct kobj_attribute vol_attribute = | |||
60 | __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); | 60 | __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); |
61 | 61 | ||
62 | static struct kobj_attribute delay_time_attribute = | 62 | static struct kobj_attribute delay_time_attribute = |
63 | __ATTR(delay_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); | 63 | __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); |
64 | static struct kobj_attribute direct_attribute = | 64 | static struct kobj_attribute direct_attribute = |
65 | __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); | 65 | __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); |
66 | static struct kobj_attribute full_time_attribute = | 66 | static struct kobj_attribute full_time_attribute = |
67 | __ATTR(full_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); | 67 | __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); |
68 | static struct kobj_attribute jiffy_delta_attribute = | 68 | static struct kobj_attribute jiffy_delta_attribute = |
69 | __ATTR(jiffy_delta, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); | 69 | __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); |
70 | static struct kobj_attribute trigger_time_attribute = | 70 | static struct kobj_attribute trigger_time_attribute = |
71 | __ATTR(trigger_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); | 71 | __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Create a group of attributes so that we can create and destroy them all | 74 | * Create a group of attributes so that we can create and destroy them all |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index cf78d1985cd8..143deb62467d 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -60,6 +60,7 @@ void tty_buffer_lock_exclusive(struct tty_port *port) | |||
60 | atomic_inc(&buf->priority); | 60 | atomic_inc(&buf->priority); |
61 | mutex_lock(&buf->lock); | 61 | mutex_lock(&buf->lock); |
62 | } | 62 | } |
63 | EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive); | ||
63 | 64 | ||
64 | void tty_buffer_unlock_exclusive(struct tty_port *port) | 65 | void tty_buffer_unlock_exclusive(struct tty_port *port) |
65 | { | 66 | { |
@@ -73,6 +74,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port) | |||
73 | if (restart) | 74 | if (restart) |
74 | queue_work(system_unbound_wq, &buf->work); | 75 | queue_work(system_unbound_wq, &buf->work); |
75 | } | 76 | } |
77 | EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive); | ||
76 | 78 | ||
77 | /** | 79 | /** |
78 | * tty_buffer_space_avail - return unused buffer space | 80 | * tty_buffer_space_avail - return unused buffer space |