mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: Alan Cox <alan@linux.intel.com>, Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 40/79] vt: add an event interface
Date: Sat, 19 Sep 2009 14:36:45 -0700	[thread overview]
Message-ID: <1253396244-7885-40-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <20090919213345.GB7668@kroah.com>

From: Alan Cox <alan@linux.intel.com>

This is needed and requested in various forms for ConsoleKit, screenblank
handling and the like so do the job with a single interface. Also build the
interface so that unlike VT_WAITACTIVE and friends it won't miss events.

FIXME: Should this be a waitactive ioctl or a new device file you can poll
and read events from. We need the code anyway to fix up the existing broken
wait for console switch logic but the ConsoleKit people would prefer the
new device to the ioctl we have here

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/char/vt.c       |    4 +-
 drivers/char/vt_ioctl.c |  185 ++++++++++++++++++++++++++++++++++-------------
 include/linux/vt.h      |   14 ++++
 include/linux/vt_kern.h |    3 +-
 4 files changed, 154 insertions(+), 52 deletions(-)

diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index e47a4c8..33214d9 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -252,7 +252,6 @@ static void notify_update(struct vc_data *vc)
 	struct vt_notifier_param param = { .vc = vc };
 	atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
 }
-
 /*
  *	Low-Level Functions
  */
@@ -935,6 +934,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
 
 	if (CON_IS_VISIBLE(vc))
 		update_screen(vc);
+	vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
 	return err;
 }
 
@@ -3637,6 +3637,7 @@ void do_blank_screen(int entering_gfx)
 		blank_state = blank_vesa_wait;
 		mod_timer(&console_timer, jiffies + vesa_off_interval);
 	}
+	vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_blank_screen);
 
@@ -3681,6 +3682,7 @@ void do_unblank_screen(int leaving_gfx)
 		console_blank_hook(0);
 	set_palette(vc);
 	set_cursor(vc);
+	vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_unblank_screen);
 
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 95189f2..35ad94e 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -62,6 +62,133 @@ extern struct tty_driver *console_driver;
 static void complete_change_console(struct vc_data *vc);
 
 /*
+ *	User space VT_EVENT handlers
+ */
+
+struct vt_event_wait {
+	struct list_head list;
+	struct vt_event event;
+	int done;
+};
+
+static LIST_HEAD(vt_events);
+static DEFINE_SPINLOCK(vt_event_lock);
+static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
+
+/**
+ *	vt_event_post
+ *	@event: the event that occurred
+ *	@old: old console
+ *	@new: new console
+ *
+ *	Post an VT event to interested VT handlers
+ */
+
+void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
+{
+	struct list_head *pos, *head;
+	unsigned long flags;
+	int wake = 0;
+
+	spin_lock_irqsave(&vt_event_lock, flags);
+	head = &vt_events;
+
+	list_for_each(pos, head) {
+		struct vt_event_wait *ve = list_entry(pos,
+						struct vt_event_wait, list);
+		if (!(ve->event.event & event))
+			continue;
+		ve->event.event = event;
+		/* kernel view is consoles 0..n-1, user space view is
+		   console 1..n with 0 meaning current, so we must bias */
+		ve->event.old = old + 1;
+		ve->event.new = new + 1;
+		wake = 1;
+		ve->done = 1;
+	}
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+	if (wake)
+		wake_up_interruptible(&vt_event_waitqueue);
+}
+
+/**
+ *	vt_event_wait		-	wait for an event
+ *	@vw: our event
+ *
+ *	Waits for an event to occur which completes our vt_event_wait
+ *	structure. On return the structure has wv->done set to 1 for success
+ *	or 0 if some event such as a signal ended the wait.
+ */
+
+static void vt_event_wait(struct vt_event_wait *vw)
+{
+	unsigned long flags;
+	/* Prepare the event */
+	INIT_LIST_HEAD(&vw->list);
+	vw->done = 0;
+	/* Queue our event */
+	spin_lock_irqsave(&vt_event_lock, flags);
+	list_add(&vw->list, &vt_events);
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+	/* Wait for it to pass */
+	wait_event_interruptible(vt_event_waitqueue, vw->done);
+	/* Dequeue it */
+	spin_lock_irqsave(&vt_event_lock, flags);
+	list_del(&vw->list);
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+}
+
+/**
+ *	vt_event_wait_ioctl	-	event ioctl handler
+ *	@arg: argument to ioctl
+ *
+ *	Implement the VT_WAITEVENT ioctl using the VT event interface
+ */
+
+static int vt_event_wait_ioctl(struct vt_event __user *event)
+{
+	struct vt_event_wait vw;
+
+	if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
+		return -EFAULT;
+	/* Highest supported event for now */
+	if (vw.event.event & ~VT_MAX_EVENT)
+		return -EINVAL;
+
+	vt_event_wait(&vw);
+	/* If it occurred report it */
+	if (vw.done) {
+		if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINTR;
+}
+
+/**
+ *	vt_waitactive	-	active console wait
+ *	@event: event code
+ *	@n: new console
+ *
+ *	Helper for event waits. Used to implement the legacy
+ *	event waiting ioctls in terms of events
+ */
+
+int vt_waitactive(int n)
+{
+	struct vt_event_wait vw;
+	do {
+		if (n == fg_console + 1)
+			break;
+		vw.event.event = VT_EVENT_SWITCH;
+		vt_event_wait(&vw);
+		if (vw.done == 0)
+			return -EINTR;
+	} while (vw.event.new != n);
+	return 0;
+}
+
+/*
  * these are the valid i/o ports we're allowed to change. they map all the
  * video ports
  */
@@ -360,6 +487,8 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_
 	return 0;
 }
 
+
+
 /*
  * We handle the console-specific ioctl's here.  We allow the
  * capability to modify any console, not just the fg_console. 
@@ -851,7 +980,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		if (arg == 0 || arg > MAX_NR_CONSOLES)
 			ret = -ENXIO;
 		else
-			ret = vt_waitactive(arg - 1);
+			ret = vt_waitactive(arg);
 		break;
 
 	/*
@@ -1159,6 +1288,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		ret = put_user(vc->vc_hi_font_mask,
 					(unsigned short __user *)arg);
 		break;
+	case VT_WAITEVENT:
+		ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -1170,54 +1302,6 @@ eperm:
 	goto out;
 }
 
-/*
- * Sometimes we want to wait until a particular VT has been activated. We
- * do it in a very simple manner. Everybody waits on a single queue and
- * get woken up at once. Those that are satisfied go on with their business,
- * while those not ready go back to sleep. Seems overkill to add a wait
- * to each vt just for this - usually this does nothing!
- */
-static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
-
-/*
- * Sleeps until a vt is activated, or the task is interrupted. Returns
- * 0 if activation, -EINTR if interrupted by a signal handler.
- */
-int vt_waitactive(int vt)
-{
-	int retval;
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&vt_activate_queue, &wait);
-	for (;;) {
-		retval = 0;
-
-		/*
-		 * Synchronize with redraw_screen(). By acquiring the console
-		 * semaphore we make sure that the console switch is completed
-		 * before we return. If we didn't wait for the semaphore, we
-		 * could return at a point where fg_console has already been
-		 * updated, but the console switch hasn't been completed.
-		 */
-		acquire_console_sem();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (vt == fg_console) {
-			release_console_sem();
-			break;
-		}
-		release_console_sem();
-		retval = -ERESTARTNOHAND;
-		if (signal_pending(current))
-			break;
-		schedule();
-	}
-	remove_wait_queue(&vt_activate_queue, &wait);
-	__set_current_state(TASK_RUNNING);
-	return retval;
-}
-
-#define vt_wake_waitactive() wake_up(&vt_activate_queue)
-
 void reset_vc(struct vc_data *vc)
 {
 	vc->vc_mode = KD_TEXT;
@@ -1262,6 +1346,7 @@ void vc_SAK(struct work_struct *work)
 static void complete_change_console(struct vc_data *vc)
 {
 	unsigned char old_vc_mode;
+	int old = fg_console;
 
 	last_console = fg_console;
 
@@ -1325,7 +1410,7 @@ static void complete_change_console(struct vc_data *vc)
 	/*
 	 * Wake anyone waiting for their VT to activate
 	 */
-	vt_wake_waitactive();
+	vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
 	return;
 }
 
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 02c1c02..89c03a1 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -74,4 +74,18 @@ struct vt_consize {
 #define VT_UNLOCKSWITCH 0x560C  /* allow vt switching */
 #define VT_GETHIFONTMASK 0x560D  /* return hi font mask */
 
+struct vt_event {
+	unsigned int event;
+#define VT_EVENT_SWITCH		0x0001	/* Console switch */
+#define VT_EVENT_BLANK		0x0002	/* Screen blank */
+#define VT_EVENT_UNBLANK	0x0004	/* Screen unblank */
+#define VT_EVENT_RESIZE		0x0008	/* Resize display */
+#define VT_MAX_EVENT		0x000F
+	unsigned int old;		/* Old console */
+	unsigned int new;		/* New console (if changing) */
+	unsigned int pad[4];		/* Padding for expansion */
+};
+
+#define VT_WAITEVENT	0x560E	/* Wait for an event */
+
 #endif /* _LINUX_VT_H */
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 2f11134..f8c797d 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -91,7 +91,8 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
 #endif
 
 /* vt.c */
-int vt_waitactive(int vt);
+void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
+int vt_waitactive(int n);
 void change_console(struct vc_data *new_vc);
 void reset_vc(struct vc_data *vc);
 extern int unbind_con_driver(const struct consw *csw, int first, int last,
-- 
1.6.4.2


  parent reply	other threads:[~2009-09-19 21:50 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-19 21:33 [GIT PATCH] TTY patches for 2.6.31-git Greg KH
2009-09-19 21:36 ` [PATCH 01/79] tty: gigaset: really fix chars_in_buffer Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 02/79] serial: bfin_5xx: fix building as module when early printk is enabled Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 03/79] tty: serial/pcmcia: add ID for Advantech card Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 04/79] tty-ldisc: make /proc/tty/ldiscs use ldisc_ops instead of ldiscs Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 05/79] tty-ldisc: get rid of tty_ldisc_try_get() helper function Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 06/79] tty: includecheck fix: drivers/char, vt.c Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 07/79] tty: icom: bit and/or confusion? Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 08/79] cyclades: add tty refcounting Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 09/79] cyclades: remove block_til_ready Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 10/79] cyclades: avoid addresses recomputation Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 11/79] cyclades: switch to tty_port_hangup Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 12/79] cyclades: close cleanup Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 13/79] cyclades: overall cleanup Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 14/79] cyclades: sleep instead busy-wait Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 15/79] cyclades: use dtr_rts helpers Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 16/79] cyclades: merge cy_startup tails Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 17/79] cyclades: ioctls cleanup Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 18/79] cyclades: tiocm cleanup Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 19/79] cyclades: introduce cyy_readb/writeb Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 20/79] cyclades: remove more duplicated code Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 21/79] slip: Clean up create and destroy Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 22/79] kfifo: Use "const" definitions Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 23/79] MOS7720 has no tiocmget method Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 24/79] tty: usb_serial_mos7720: Fix get_lsr_info Greg Kroah-Hartman
2010-01-26 11:08   ` Kees Schoenmakers
2010-01-26 11:09   ` Kees Schoenmakers
2009-09-19 21:36 ` [PATCH 25/79] tty: Fix a typo noted in passing Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 26/79] mos7840: remove old dead modem logic Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 27/79] serial: 8250: add IRQ trigger support Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 28/79] 8250: Now honours baud rate lower bounds Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 29/79] tty: Add a full port_close function Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 30/79] riscom8: split open and close methods up Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 31/79] mxser: Split close ready for a standard tty_port_close method Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 32/79] isicom: Split the close hardware bits out Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 33/79] tty: riscom8 kref and tty_port_close Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 34/79] cyclades: use the full port_close function Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 35/79] tty: make the kref destructor occur asynchronously Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 36/79] cdc_acm: Fix to use modern speed interfaces Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 37/79] tty: USB hangup is racy Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 38/79] tty: remove dtr/rts use from the driver open methods Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 39/79] tty: USB can now use the shutdown method for kref based freeing of ports Greg Kroah-Hartman
2009-09-19 21:36 ` Greg Kroah-Hartman [this message]
2009-09-19 21:36 ` [PATCH 41/79] vt: remove power stuff from kernel/power Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 42/79] vt: move kernel stuff out of vt.h Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 43/79] vt: add an activate and lock Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 44/79] tty: USB does not need the filp argument in the drivers Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 45/79] isicom: split the open method for the isicom device Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 46/79] serial: kill off uart_info Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 47/79] serial: Fold closing_* fields into the tty_port ones Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 48/79] serial: use tty_port pointers in the core code Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 49/79] serial: move count into the tty_port version Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 50/79] serial: move the flags into the tty_port field Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 51/79] serial: kill off uif_t Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 52/79] serial: replace the state mutex with the tty port mutex Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 53/79] serial: move delta_msr_wait into the tty_port Greg Kroah-Hartman
2009-09-19 21:36 ` [PATCH 54/79] serial: move port users helper Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 55/79] serial: kill USF_CLOSING_* definitions Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 56/79] serial: introduce tty krefs Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 57/79] Set proper console speed on resume if console suspend is disabled Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 58/79] tty: USB serial termios bits Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 59/79] n_tty: honor opost flag for echoes Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 60/79] n_tty: move echoctl check and clean up logic Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 61/79] tty: handle VT specific compat ioctls in vt driver Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 62/79] tty: vt: use printk_once Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 63/79] tty: Power: fix suspend vt regression Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 64/79] TTY: fix typos Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 65/79] tty: riscom8, fix shutdown declaration Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 66/79] tty: riscom8, fix tty refcnt Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 67/79] tty: USB: serial/mct_u232, " Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 68/79] uartlite: support shared interrupt lines Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 69/79] tty: Char: mxser, add support for CP112UL Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 70/79] tty: Char: mxser, use THRE for ASPP_OQUEUE ioctl Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 71/79] usb-serial: change referencing of port and serial structures Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 72/79] usb-serial: put subroutines in logical order Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 73/79] usb-serial: change logic of serial lookups Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 74/79] usb-serial: acquire references when a new tty is installed Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 75/79] usb-serial: fix termios initialization logic Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 76/79] usb-serial: rename subroutines Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 77/79] usb-serial: add missing tests and debug lines Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 78/79] usb-serial: straighten out serial_open Greg Kroah-Hartman
2009-09-19 21:37 ` [PATCH 79/79] USB serial: update the console driver Greg Kroah-Hartman
2009-09-30 10:09 ` [origin tree boot crash] Re: [GIT PATCH] TTY patches for 2.6.31-git Ingo Molnar
2009-09-30 10:17   ` Alan Cox
2009-10-01  8:21     ` Ingo Molnar
2009-10-01 10:36       ` Alan Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1253396244-7885-40-git-send-email-gregkh@suse.de \
    --to=gregkh@suse.de \
    --cc=alan@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome