]> Zhao Yanbai Git Server - minix.git/commitdiff
TTY: allow selecting on translated minors 98/998/2
authorDavid van Moolenbroek <david@minix3.org>
Fri, 27 Sep 2013 11:56:29 +0000 (11:56 +0000)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:55 +0000 (09:04 +0100)
Due to the existence of /dev/console and /dev/log, and the new
"console=" setting, it is now possible that a single non-PTY object
(e.g. serial) is accessible through two different minor numbers.  This
poses a problem when sending late select replies (CDEV_SEL2_REPLY),
because the object's minor number can not be used to identify the
device.  Since selecting on such objects through translated minor
numbers is actually required, we now save the minor number used to
initiate the select query in order to send a late reply.

The solution is suboptimal, as it is not possible to use two different
minors to select on the same object at once.  In the future, there
should be at least one select record for each minor that can be used
with each object.

Change-Id: I4d39681d2ffd68b4047daf933d45b7bafe3c885e

drivers/tty/tty.c
drivers/tty/tty.h

index bdfdd142e4064eb2787e2de00da89cb7ca411621..655becf06ae997a0edb2bf130b37d846f22a411d 100644 (file)
@@ -873,8 +873,8 @@ int select_retry(struct tty *tp)
        int ops;
 
        if (tp->tty_select_ops && (ops = select_try(tp, tp->tty_select_ops))) {
-               chardriver_reply_select(tp->tty_select_proc, tp->tty_minor,
-                       ops);
+               chardriver_reply_select(tp->tty_select_proc,
+                       tp->tty_select_minor, ops);
                tp->tty_select_ops &= ~ops;
        }
        return OK;
@@ -891,10 +891,6 @@ static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
   if ((tp = line2tty(minor)) == NULL)
        return ENXIO;
 
-  /* Translated minor numbers are a problem when sending late replies. */
-  if (tp->tty_minor != minor)
-       return EBADF;
-
   watch = (ops & CDEV_NOTIFY);
   ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
 
@@ -902,11 +898,21 @@ static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
 
   ops &= ~ready_ops;
   if (ops && watch) {
+       /* Translated minor numbers are a problem with late select replies. We
+        * have to save the minor number used to do the select, since otherwise
+        * VFS won't be able to make sense of those late replies. We do not
+        * support selecting on two different minors for the same object.
+        */
+       if (tp->tty_select_ops != 0 && tp->tty_select_minor != minor) {
+               printf("TTY: select on one object with two minors (%d, %d)\n",
+                       tp->tty_select_minor, minor);
+               return EBADF;
+       }
        tp->tty_select_ops |= ops;
        tp->tty_select_proc = endpt;
+       tp->tty_select_minor = minor;
   }
 
-  assert(tp->tty_minor == minor);
   return ready_ops;
 }
 
index bc68262955d06ea619086124c5314da319a5aaf8..de5605b794d333fb293ef50b3ba6bf6f81ccc056 100644 (file)
@@ -75,8 +75,9 @@ typedef struct tty {
   cp_grant_id_t tty_iogrant;   /* virtual address of ioctl buffer or grant */
 
   /* select() data */
-  int tty_select_ops;          /* which operations are interesting */
+  unsigned int tty_select_ops; /* which operations are interesting */
   endpoint_t tty_select_proc;  /* which process wants notification */
+  devminor_t tty_select_minor; /* minor used to start select query */
 
   /* Miscellaneous. */
   devfun_t tty_ioctl;          /* set line speed, etc. at the device level */