Can you please review this patch?

Thanks,
//richard

---
>From d8f5e7953def150bcc1e6a39dbbe589f1c68bcbd Mon Sep 17 00:00:00 2001
From: Richard Weinberger <rich...@nod.at>
Date: Sun, 12 Feb 2012 01:12:49 +0100
Subject: [PATCH] um: Use tty_port

UML's line driver has to use tty_port.

Signed-off-by: Richard Weinberger <rich...@nod.at>
---
 arch/um/drivers/line.c          |  212 +++++++++++---------------------------
 arch/um/drivers/line.h          |   13 ++-
 arch/um/drivers/ssl.c           |   16 +++-
 arch/um/drivers/stdio_console.c |   14 ++-
 4 files changed, 94 insertions(+), 161 deletions(-)

diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index c1cf220..c789748 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -19,19 +19,29 @@ static irqreturn_t line_interrupt(int irq, void *data)
 {
        struct chan *chan = data;
        struct line *line = chan->line;
+       struct tty_struct *tty;
+
+       if (line) {
+               tty = tty_port_tty_get(&line->port);
+               chan_interrupt(&line->chan_list, &line->task, tty, irq);
+               tty_kref_put(tty);
+       }
 
-       if (line)
-               chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
        return IRQ_HANDLED;
 }
 
 static void line_timer_cb(struct work_struct *work)
 {
        struct line *line = container_of(work, struct line, task.work);
+       struct tty_struct *tty;
 
-       if (!line->throttled)
-               chan_interrupt(&line->chan_list, &line->task, line->tty,
+       if (!line->throttled) {
+               tty = tty_port_tty_get(&line->port);
+               chan_interrupt(&line->chan_list, &line->task, tty,
                               line->driver->read_irq);
+
+               tty_kref_put(tty);
+       }
 }
 
 /*
@@ -228,92 +238,6 @@ void line_set_termios(struct tty_struct *tty, struct 
ktermios * old)
        /* nothing */
 }
 
-static const struct {
-       int  cmd;
-       char *level;
-       char *name;
-} tty_ioctls[] = {
-       /* don't print these, they flood the log ... */
-       { TCGETS,      NULL,       "TCGETS"      },
-       { TCSETS,      NULL,       "TCSETS"      },
-       { TCSETSW,     NULL,       "TCSETSW"     },
-       { TCFLSH,      NULL,       "TCFLSH"      },
-       { TCSBRK,      NULL,       "TCSBRK"      },
-
-       /* general tty stuff */
-       { TCSETSF,     KERN_DEBUG, "TCSETSF"     },
-       { TCGETA,      KERN_DEBUG, "TCGETA"      },
-       { TIOCMGET,    KERN_DEBUG, "TIOCMGET"    },
-       { TCSBRKP,     KERN_DEBUG, "TCSBRKP"     },
-       { TIOCMSET,    KERN_DEBUG, "TIOCMSET"    },
-
-       /* linux-specific ones */
-       { TIOCLINUX,   KERN_INFO,  "TIOCLINUX"   },
-       { KDGKBMODE,   KERN_INFO,  "KDGKBMODE"   },
-       { KDGKBTYPE,   KERN_INFO,  "KDGKBTYPE"   },
-       { KDSIGACCEPT, KERN_INFO,  "KDSIGACCEPT" },
-};
-
-int line_ioctl(struct tty_struct *tty, unsigned int cmd,
-                               unsigned long arg)
-{
-       int ret;
-       int i;
-
-       ret = 0;
-       switch(cmd) {
-#ifdef TIOCGETP
-       case TIOCGETP:
-       case TIOCSETP:
-       case TIOCSETN:
-#endif
-#ifdef TIOCGETC
-       case TIOCGETC:
-       case TIOCSETC:
-#endif
-#ifdef TIOCGLTC
-       case TIOCGLTC:
-       case TIOCSLTC:
-#endif
-       /* Note: these are out of date as we now have TCGETS2 etc but this
-          whole lot should probably go away */
-       case TCGETS:
-       case TCSETSF:
-       case TCSETSW:
-       case TCSETS:
-       case TCGETA:
-       case TCSETAF:
-       case TCSETAW:
-       case TCSETA:
-       case TCXONC:
-       case TCFLSH:
-       case TIOCOUTQ:
-       case TIOCINQ:
-       case TIOCGLCKTRMIOS:
-       case TIOCSLCKTRMIOS:
-       case TIOCPKT:
-       case TIOCGSOFTCAR:
-       case TIOCSSOFTCAR:
-               return -ENOIOCTLCMD;
-#if 0
-       case TCwhatever:
-               /* do something */
-               break;
-#endif
-       default:
-               for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
-                       if (cmd == tty_ioctls[i].cmd)
-                               break;
-               if (i == ARRAY_SIZE(tty_ioctls)) {
-                       printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
-                              __func__, tty->name, cmd);
-               }
-               ret = -ENOIOCTLCMD;
-               break;
-       }
-       return ret;
-}
-
 void line_throttle(struct tty_struct *tty)
 {
        struct line *line = tty->driver_data;
@@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
 {
        struct chan *chan = data;
        struct line *line = chan->line;
-       struct tty_struct *tty = line->tty;
+       struct tty_struct *tty = tty_port_tty_get(&line->port);
        int err;
 
        /*
@@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
        spin_lock(&line->lock);
        err = flush_buffer(line);
        if (err == 0) {
+               tty_kref_put(tty);
+
+               spin_unlock(&line->lock);
                return IRQ_NONE;
        } else if (err < 0) {
                line->head = line->buffer;
@@ -365,9 +292,12 @@ static irqreturn_t line_write_interrupt(int irq, void 
*data)
                return IRQ_NONE;
 
        tty_wakeup(tty);
+       tty_kref_put(tty);
        return IRQ_HANDLED;
 }
 
+static const struct tty_port_operations line_port_ops;
+
 int line_setup_irq(int fd, int input, int output, struct line *line, void 
*data)
 {
        const struct line_driver *driver = line->driver;
@@ -404,27 +334,27 @@ int line_setup_irq(int fd, int input, int output, struct 
line *line, void *data)
  * first open or last close.  Otherwise, open and close just return.
  */
 
-int line_open(struct line *lines, struct tty_struct *tty)
+int line_open(struct tty_struct *tty, struct file *filp)
 {
-       struct line *line = &lines[tty->index];
-       int err = -ENODEV;
+       struct line *line = tty->driver_data;
+       return tty_port_open(&line->port, tty, filp);
+}
 
-       spin_lock(&line->count_lock);
-       if (!line->valid)
-               goto out_unlock;
+int line_install(struct tty_driver *driver, struct tty_struct *tty, struct 
line *line)
+{
+       int ret = tty_init_termios(tty);
 
-       err = 0;
-       if (line->count++)
-               goto out_unlock;
+       if (ret)
+               return ret;
 
-       BUG_ON(tty->driver_data);
+       tty_driver_kref_get(driver);
+       tty->count++;
        tty->driver_data = line;
-       line->tty = tty;
+       driver->ttys[tty->index] = tty;
 
-       spin_unlock(&line->count_lock);
-       err = enable_chan(line);
-       if (err) /* line_close() will be called by our caller */
-               return err;
+       ret = enable_chan(line);
+       if (ret)
+               return ret;
 
        INIT_DELAYED_WORK(&line->task, line_timer_cb);
 
@@ -437,48 +367,36 @@ int line_open(struct line *lines, struct tty_struct *tty)
                         &tty->winsize.ws_col);
 
        return 0;
-
-out_unlock:
-       spin_unlock(&line->count_lock);
-       return err;
 }
 
 static void unregister_winch(struct tty_struct *tty);
 
-void line_close(struct tty_struct *tty, struct file * filp)
+void line_cleanup(struct tty_struct *tty)
 {
        struct line *line = tty->driver_data;
 
-       /*
-        * If line_open fails (and tty->driver_data is never set),
-        * tty_open will call line_close.  So just return in this case.
-        */
-       if (line == NULL)
-               return;
-
-       /* We ignore the error anyway! */
-       flush_buffer(line);
-
-       spin_lock(&line->count_lock);
-       BUG_ON(!line->valid);
-
-       if (--line->count)
-               goto out_unlock;
-
-       line->tty = NULL;
-       tty->driver_data = NULL;
-
-       spin_unlock(&line->count_lock);
-
        if (line->sigio) {
                unregister_winch(tty);
                line->sigio = 0;
        }
 
-       return;
+       tty->driver_data = NULL;
+}
+
+void line_close(struct tty_struct *tty, struct file * filp)
+{
+       struct line *line = tty->driver_data;
+
+       if (!line)
+               return;
+
+       tty_port_close(&line->port, tty, filp);
+}
 
-out_unlock:
-       spin_unlock(&line->count_lock);
+void line_hangup(struct tty_struct *tty)
+{
+       struct line *line = tty->driver_data;
+       tty_port_hangup(&line->port);
 }
 
 void close_lines(struct line *lines, int nlines)
@@ -495,13 +413,6 @@ static int setup_one_line(struct line *lines, int n, char 
*init, int init_prio,
        struct line *line = &lines[n];
        int err = -EINVAL;
 
-       spin_lock(&line->count_lock);
-
-       if (line->count) {
-               *error_out = "Device is already open";
-               goto out;
-       }
-
        if (line->init_pri <= init_prio) {
                line->init_pri = init_prio;
                if (!strcmp(init, "none"))
@@ -512,8 +423,7 @@ static int setup_one_line(struct line *lines, int n, char 
*init, int init_prio,
                }
        }
        err = 0;
-out:
-       spin_unlock(&line->count_lock);
+
        return err;
 }
 
@@ -598,6 +508,7 @@ int line_get_config(char *name, struct line *lines, 
unsigned int num, char *str,
        struct line *line;
        char *end;
        int dev, n = 0;
+       struct tty_struct *tty;
 
        dev = simple_strtoul(name, &end, 0);
        if ((*end != '\0') || (end == name)) {
@@ -612,13 +523,15 @@ int line_get_config(char *name, struct line *lines, 
unsigned int num, char *str,
 
        line = &lines[dev];
 
-       spin_lock(&line->count_lock);
+       tty = tty_port_tty_get(&line->port);
+
        if (!line->valid)
                CONFIG_CHUNK(str, size, n, "none", 1);
-       else if (line->tty == NULL)
+       else if (tty == NULL)
                CONFIG_CHUNK(str, size, n, line->init_str, 1);
        else n = chan_config_string(&line->chan_list, str, size, error_out);
-       spin_unlock(&line->count_lock);
+
+       tty_kref_put(tty);
 
        return n;
 }
@@ -678,8 +591,8 @@ struct tty_driver *register_lines(struct line_driver 
*line_driver,
        }
 
        for(i = 0; i < nlines; i++) {
-               if (!lines[i].valid)
-                       tty_unregister_device(driver, i);
+               tty_port_init(&lines[i].port);
+               lines[i].port.ops = &line_port_ops;
        }
 
        mconsole_register_dev(&line_driver->mc);
@@ -805,7 +718,6 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct 
tty_struct *tty,
                                   .pid         = pid,
                                   .tty         = tty,
                                   .stack       = stack });
-
        if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
                           IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                           "winch", winch) < 0) {
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
index 63df3ca..54adfc6 100644
--- a/arch/um/drivers/line.h
+++ b/arch/um/drivers/line.h
@@ -31,9 +31,8 @@ struct line_driver {
 };
 
 struct line {
-       struct tty_struct *tty;
-       spinlock_t count_lock;
-       unsigned long count;
+       struct tty_port port;
+
        int valid;
 
        char *init_str;
@@ -59,15 +58,17 @@ struct line {
 };
 
 #define LINE_INIT(str, d) \
-       { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \
-         .init_str =   str,    \
+       { .init_str =   str,    \
          .init_pri =   INIT_STATIC, \
          .valid =      1, \
          .lock =       __SPIN_LOCK_UNLOCKED((str).lock), \
          .driver =     d }
 
 extern void line_close(struct tty_struct *tty, struct file * filp);
-extern int line_open(struct line *lines, struct tty_struct *tty);
+extern int line_open(struct tty_struct *tty, struct file *filp);
+extern int line_install(struct tty_driver *driver, struct tty_struct *tty, 
struct line *line);
+extern void line_cleanup(struct tty_struct *tty);
+extern void line_hangup(struct tty_struct *tty);
 extern int line_setup(struct line *lines, unsigned int sizeof_lines,
                      char *init, char **error_out);
 extern int line_write(struct tty_struct *tty, const unsigned char *buf,
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 9d8c20a..89e4e75 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -92,6 +92,7 @@ static int ssl_remove(int n, char **error_out)
                           error_out);
 }
 
+#if 0
 static int ssl_open(struct tty_struct *tty, struct file *filp)
 {
        int err = line_open(serial_lines, tty);
@@ -103,7 +104,6 @@ static int ssl_open(struct tty_struct *tty, struct file 
*filp)
        return err;
 }
 
-#if 0
 static void ssl_flush_buffer(struct tty_struct *tty)
 {
        return;
@@ -124,8 +124,16 @@ void ssl_hangup(struct tty_struct *tty)
 }
 #endif
 
+static int ssl_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       if (tty->index < NR_PORTS)
+               return line_install(driver, tty, &serial_lines[tty->index]);
+       else
+               return -ENODEV;
+}
+
 static const struct tty_operations ssl_ops = {
-       .open                   = ssl_open,
+       .open                   = line_open,
        .close                  = line_close,
        .write                  = line_write,
        .put_char               = line_put_char,
@@ -134,9 +142,11 @@ static const struct tty_operations ssl_ops = {
        .flush_buffer           = line_flush_buffer,
        .flush_chars            = line_flush_chars,
        .set_termios            = line_set_termios,
-       .ioctl                  = line_ioctl,
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
+       .install                = ssl_install,
+       .cleanup                = line_cleanup,
+       .hangup                 = line_hangup,
 #if 0
        .stop                   = ssl_stop,
        .start                  = ssl_start,
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 088776f..014f3ee 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -97,7 +97,7 @@ static int con_remove(int n, char **error_out)
 
 static int con_open(struct tty_struct *tty, struct file *filp)
 {
-       int err = line_open(vts, tty);
+       int err = line_open(tty, filp);
        if (err)
                printk(KERN_ERR "Failed to open console %d, err = %d\n",
                       tty->index, err);
@@ -105,6 +105,14 @@ static int con_open(struct tty_struct *tty, struct file 
*filp)
        return err;
 }
 
+static int con_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       if (tty->index < MAX_TTYS)
+               return line_install(driver, tty, &vts[tty->index]);
+       else
+               return -ENODEV;
+}
+
 /* Set in an initcall, checked in an exitcall */
 static int con_init_done = 0;
 
@@ -118,9 +126,11 @@ static const struct tty_operations console_ops = {
        .flush_buffer           = line_flush_buffer,
        .flush_chars            = line_flush_chars,
        .set_termios            = line_set_termios,
-       .ioctl                  = line_ioctl,
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
+       .cleanup                = line_cleanup,
+       .install                = con_install,
+       .hangup                 = line_hangup,
 };
 
 static void uml_console_write(struct console *console, const char *string,
-- 
1.7.7.3


------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

Reply via email to