#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/idr.h>
 
 #include "xhci.h"
 #include "xhci-dbgcap.h"
 
 static struct tty_driver *dbc_tty_driver;
+static struct idr dbc_tty_minors;
+static DEFINE_MUTEX(dbc_tty_minors_lock);
 
 static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc)
 {
 
 static int dbc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
-       struct dbc_port         *port = driver->driver_state;
+       struct dbc_port         *port;
+
+       mutex_lock(&dbc_tty_minors_lock);
+       port = idr_find(&dbc_tty_minors, tty->index);
+       mutex_unlock(&dbc_tty_minors_lock);
+
+       if (!port)
+               return -ENXIO;
 
        tty->driver_data = port;
 
 
        xhci_dbc_tty_init_port(dbc, port);
 
+       mutex_lock(&dbc_tty_minors_lock);
+       port->minor = idr_alloc(&dbc_tty_minors, port, 0, 64, GFP_KERNEL);
+       mutex_unlock(&dbc_tty_minors_lock);
+
+       if (port->minor < 0) {
+               ret = port->minor;
+               goto err_idr;
+       }
+
        ret = kfifo_alloc(&port->write_fifo, DBC_WRITE_BUF_SIZE, GFP_KERNEL);
        if (ret)
                goto err_exit_port;
                goto err_free_requests;
 
        tty_dev = tty_port_register_device(&port->port,
-                                          dbc_tty_driver, 0, NULL);
+                                          dbc_tty_driver, port->minor, NULL);
        if (IS_ERR(tty_dev)) {
                ret = PTR_ERR(tty_dev);
                goto err_free_requests;
 err_free_fifo:
        kfifo_free(&port->write_fifo);
 err_exit_port:
+       idr_remove(&dbc_tty_minors, port->minor);
+err_idr:
        xhci_dbc_tty_exit_port(port);
 
        dev_err(dbc->dev, "can't register tty port, err %d\n", ret);
 
        if (!port->registered)
                return;
-       tty_unregister_device(dbc_tty_driver, 0);
+       tty_unregister_device(dbc_tty_driver, port->minor);
        xhci_dbc_tty_exit_port(port);
        port->registered = false;
 
+       mutex_lock(&dbc_tty_minors_lock);
+       idr_remove(&dbc_tty_minors, port->minor);
+       mutex_unlock(&dbc_tty_minors_lock);
+
        kfifo_free(&port->write_fifo);
        xhci_dbc_free_requests(&port->read_pool);
        xhci_dbc_free_requests(&port->read_queue);
        if (!port)
                return -ENOMEM;
 
-       dbc_tty_driver->driver_state = port;
-
        dbc = xhci_alloc_dbc(dev, base, &dbc_driver);
+
        if (!dbc) {
                status = -ENOMEM;
                goto out2;
 {
        int             ret;
 
-       dbc_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
+       idr_init(&dbc_tty_minors);
+
+       dbc_tty_driver = tty_alloc_driver(64, TTY_DRIVER_REAL_RAW |
                                          TTY_DRIVER_DYNAMIC_DEV);
-       if (IS_ERR(dbc_tty_driver))
+       if (IS_ERR(dbc_tty_driver)) {
+               idr_destroy(&dbc_tty_minors);
                return PTR_ERR(dbc_tty_driver);
+       }
 
        dbc_tty_driver->driver_name = "dbc_serial";
        dbc_tty_driver->name = "ttyDBC";
        if (ret) {
                pr_err("Can't register dbc tty driver\n");
                tty_driver_kref_put(dbc_tty_driver);
+               idr_destroy(&dbc_tty_minors);
        }
+
        return ret;
 }
 
                tty_driver_kref_put(dbc_tty_driver);
                dbc_tty_driver = NULL;
        }
+
+       idr_destroy(&dbc_tty_minors);
 }