>From 60b1e6e5d9401f10f584928d4feeb8a3b72b46a9 Mon Sep 17 00:00:00 2001
From: Daeseok Youn <daeseok.y...@gmail.com>
Date: Mon, 29 Feb 2016 11:04:02 +0900
Subject: [PATCH 2/2] staging: dgap: use tty_alloc_driver instead of kcalloc

the tty_alloc_driver() can allocate memory for ttys and termios.
And also it can release allocated memory easly with using
put_tty_driver().

Signed-off-by: Daeseok Youn <daeseok.y...@gmail.com>
---
 drivers/staging/dgnc/dgnc_tty.c | 86 +++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 01a0018..da5cba7 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -176,9 +176,15 @@ int dgnc_tty_preinit(void)
  */
 int dgnc_tty_register(struct dgnc_board *brd)
 {
-       int rc = 0;
+       int rc;
+
+       brd->serial_driver = tty_alloc_driver(brd->maxports,
+                                             TTY_DRIVER_REAL_RAW |
+                                             TTY_DRIVER_DYNAMIC_DEV |
+                                             TTY_DRIVER_HARDWARE_BREAK);
 
-       brd->serial_driver->magic = TTY_DRIVER_MAGIC;
+       if (IS_ERR(brd->serial_driver))
+               return PTR_ERR(brd->serial_driver);
 
        snprintf(brd->SerialName, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
 
@@ -186,31 +192,10 @@ int dgnc_tty_register(struct dgnc_board *brd)
        brd->serial_driver->name_base = 0;
        brd->serial_driver->major = 0;
        brd->serial_driver->minor_start = 0;
-       brd->serial_driver->num = brd->maxports;
        brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
        brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
        brd->serial_driver->init_termios = DgncDefaultTermios;
        brd->serial_driver->driver_name = DRVSTR;
-       brd->serial_driver->flags = (TTY_DRIVER_REAL_RAW |
-                                  TTY_DRIVER_DYNAMIC_DEV |
-                                  TTY_DRIVER_HARDWARE_BREAK);
-
-       /*
-        * The kernel wants space to store pointers to
-        * tty_struct's and termios's.
-        */
-       brd->serial_driver->ttys = kcalloc(brd->maxports,
-                                        sizeof(*brd->serial_driver->ttys),
-                                        GFP_KERNEL);
-       if (!brd->serial_driver->ttys)
-               return -ENOMEM;
-
-       kref_init(&brd->serial_driver->kref);
-       brd->serial_driver->termios = kcalloc(brd->maxports,
-                                           
sizeof(*brd->serial_driver->termios),
-                                           GFP_KERNEL);
-       if (!brd->serial_driver->termios)
-               return -ENOMEM;
 
        /*
         * Entry points for driver.  Called by the kernel from
@@ -224,7 +209,7 @@ int dgnc_tty_register(struct dgnc_board *brd)
                if (rc < 0) {
                        dev_dbg(&brd->pdev->dev,
                                "Can't register tty device (%d)\n", rc);
-                       return rc;
+                       goto free_serial_driver;
                }
                brd->dgnc_Major_Serial_Registered = true;
        }
@@ -234,38 +219,26 @@ int dgnc_tty_register(struct dgnc_board *brd)
         * again, separately so we don't get the LD confused about what major
         * we are when we get into the dgnc_tty_open() routine.
         */
-       brd->print_driver->magic = TTY_DRIVER_MAGIC;
+       brd->print_driver = tty_alloc_driver(brd->maxports,
+                                            TTY_DRIVER_REAL_RAW |
+                                            TTY_DRIVER_DYNAMIC_DEV |
+                                            TTY_DRIVER_HARDWARE_BREAK);
+
+       if (IS_ERR(brd->print_driver)) {
+               rc = PTR_ERR(brd->print_driver);
+               goto unregister_serial_driver;
+       }
+
        snprintf(brd->PrintName, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum);
 
        brd->print_driver->name = brd->PrintName;
        brd->print_driver->name_base = 0;
        brd->print_driver->major = brd->serial_driver->major;
        brd->print_driver->minor_start = 0x80;
-       brd->print_driver->num = brd->maxports;
        brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
        brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
        brd->print_driver->init_termios = DgncDefaultTermios;
        brd->print_driver->driver_name = DRVSTR;
-       brd->print_driver->flags = (TTY_DRIVER_REAL_RAW |
-                                 TTY_DRIVER_DYNAMIC_DEV |
-                                 TTY_DRIVER_HARDWARE_BREAK);
-
-       /*
-        * The kernel wants space to store pointers to
-        * tty_struct's and termios's.  Must be separated from
-        * the Serial Driver so we don't get confused
-        */
-       brd->print_driver->ttys = kcalloc(brd->maxports,
-                                       sizeof(*brd->print_driver->ttys),
-                                       GFP_KERNEL);
-       if (!brd->print_driver->ttys)
-               return -ENOMEM;
-       kref_init(&brd->print_driver->kref);
-       brd->print_driver->termios = kcalloc(brd->maxports,
-                                          sizeof(*brd->print_driver->termios),
-                                          GFP_KERNEL);
-       if (!brd->print_driver->termios)
-               return -ENOMEM;
 
        /*
         * Entry points for driver.  Called by the kernel from
@@ -280,7 +253,7 @@ int dgnc_tty_register(struct dgnc_board *brd)
                        dev_dbg(&brd->pdev->dev,
                                "Can't register Transparent Print device(%d)\n",
                                rc);
-                       return rc;
+                       goto free_print_driver;
                }
                brd->dgnc_Major_TransparentPrint_Registered = true;
        }
@@ -289,6 +262,15 @@ int dgnc_tty_register(struct dgnc_board *brd)
        brd->dgnc_Serial_Major = brd->serial_driver->major;
        brd->dgnc_TransparentPrint_Major = brd->print_driver->major;
 
+       return 0;
+
+free_print_driver:
+       put_tty_driver(brd->print_driver);
+unregister_serial_driver:
+       tty_unregister_driver(brd->serial_driver);
+free_serial_driver:
+       put_tty_driver(brd->serial_driver);
+
        return rc;
 }
 
@@ -433,14 +415,8 @@ void dgnc_tty_uninit(struct dgnc_board *brd)
                brd->dgnc_Major_TransparentPrint_Registered = false;
        }
 
-       kfree(brd->serial_driver->ttys);
-       brd->serial_driver->ttys = NULL;
-       kfree(brd->serial_driver->termios);
-       brd->serial_driver->termios = NULL;
-       kfree(brd->print_driver->ttys);
-       brd->print_driver->ttys = NULL;
-       kfree(brd->print_driver->termios);
-       brd->print_driver->termios = NULL;
+       put_tty_driver(brd->serial_driver);
+       put_tty_driver(brd->print_driver);
 }
 
 /*=======================================================================
-- 
1.9.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to