drivers/accessibility/speakup/selection.c
Source file repositories/reference/linux-study-clean/drivers/accessibility/speakup/selection.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accessibility/speakup/selection.c- Extension
.c- Size
- 3588 bytes
- Lines
- 142
- Domain
- Driver Families
- Bucket
- drivers/accessibility
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/consolemap.hlinux/interrupt.hlinux/sched.hlinux/device.hlinux/selection.hlinux/workqueue.hlinux/tty.hlinux/tty_flip.hlinux/atomic.hlinux/console.hspeakup.h
Detected Declarations
struct speakup_selection_workfunction __speakup_set_selectionfunction speakup_set_selectionfunction speakup_cancel_selectionfunction __speakup_paste_selectionfunction speakup_paste_selectionfunction speakup_cancel_paste
Annotated Snippet
struct speakup_selection_work {
struct work_struct work;
struct tiocl_selection sel;
struct tty_struct *tty;
};
static void __speakup_set_selection(struct work_struct *work)
{
struct speakup_selection_work *ssw =
container_of(work, struct speakup_selection_work, work);
struct tty_struct *tty;
struct tiocl_selection sel;
sel = ssw->sel;
/* this ensures we copy sel before releasing the lock below */
rmb();
/* release the lock by setting tty of the struct to NULL */
tty = xchg(&ssw->tty, NULL);
if (spk_sel_cons != vc_cons[fg_console].d) {
spk_sel_cons = vc_cons[fg_console].d;
pr_warn("Selection: mark console not the same as cut\n");
goto unref;
}
console_lock();
clear_selection();
console_unlock();
set_selection_kernel(&sel, tty);
unref:
tty_kref_put(tty);
}
static struct speakup_selection_work speakup_sel_work = {
.work = __WORK_INITIALIZER(speakup_sel_work.work,
__speakup_set_selection)
};
int speakup_set_selection(struct tty_struct *tty)
{
/* we get kref here first in order to avoid a subtle race when
* cancelling selection work. getting kref first establishes the
* invariant that if speakup_sel_work.tty is not NULL when
* speakup_cancel_selection() is called, it must be the case that a put
* kref is pending.
*/
tty_kref_get(tty);
if (cmpxchg(&speakup_sel_work.tty, NULL, tty)) {
tty_kref_put(tty);
return -EBUSY;
}
/* now we have the 'lock' by setting tty member of
* speakup_selection_work. wmb() ensures that writes to
* speakup_sel_work don't happen before cmpxchg() above.
*/
wmb();
speakup_sel_work.sel.xs = spk_xs + 1;
speakup_sel_work.sel.ys = spk_ys + 1;
speakup_sel_work.sel.xe = spk_xe + 1;
speakup_sel_work.sel.ye = spk_ye + 1;
speakup_sel_work.sel.sel_mode = TIOCL_SELCHAR;
schedule_work_on(WORK_CPU_UNBOUND, &speakup_sel_work.work);
return 0;
}
void speakup_cancel_selection(void)
{
struct tty_struct *tty;
cancel_work_sync(&speakup_sel_work.work);
/* setting to null so that if work fails to run and we cancel it,
* we can run it again without getting EBUSY forever from there on.
* we need to use xchg here to avoid race with speakup_set_selection()
*/
tty = xchg(&speakup_sel_work.tty, NULL);
if (tty)
tty_kref_put(tty);
}
static void __speakup_paste_selection(struct work_struct *work)
{
struct speakup_selection_work *ssw =
Annotation
- Immediate include surface: `linux/slab.h`, `linux/consolemap.h`, `linux/interrupt.h`, `linux/sched.h`, `linux/device.h`, `linux/selection.h`, `linux/workqueue.h`, `linux/tty.h`.
- Detected declarations: `struct speakup_selection_work`, `function __speakup_set_selection`, `function speakup_set_selection`, `function speakup_cancel_selection`, `function __speakup_paste_selection`, `function speakup_paste_selection`, `function speakup_cancel_paste`.
- Atlas domain: Driver Families / drivers/accessibility.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.