aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/nozomi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/nozomi.c')
-rw-r--r--drivers/char/nozomi.c115
1 files changed, 68 insertions, 47 deletions
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 2ad7d37afbd0..cd405bcf53a6 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -371,6 +371,8 @@ struct port {
371 struct mutex tty_sem; 371 struct mutex tty_sem;
372 wait_queue_head_t tty_wait; 372 wait_queue_head_t tty_wait;
373 struct async_icount tty_icount; 373 struct async_icount tty_icount;
374
375 struct nozomi *dc;
374}; 376};
375 377
376/* Private data one for each card in the system */ 378/* Private data one for each card in the system */
@@ -414,6 +416,8 @@ MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
414static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; 416static struct nozomi *ndevs[NOZOMI_MAX_CARDS];
415static struct tty_driver *ntty_driver; 417static struct tty_driver *ntty_driver;
416 418
419static const struct tty_port_operations noz_tty_port_ops;
420
417/* 421/*
418 * find card by tty_index 422 * find card by tty_index
419 */ 423 */
@@ -1473,9 +1477,11 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
1473 1477
1474 for (i = 0; i < MAX_PORT; i++) { 1478 for (i = 0; i < MAX_PORT; i++) {
1475 struct device *tty_dev; 1479 struct device *tty_dev;
1476 1480 struct port *port = &dc->port[i];
1477 mutex_init(&dc->port[i].tty_sem); 1481 port->dc = dc;
1478 tty_port_init(&dc->port[i].port); 1482 mutex_init(&port->tty_sem);
1483 tty_port_init(&port->port);
1484 port->port.ops = &noz_tty_port_ops;
1479 tty_dev = tty_register_device(ntty_driver, dc->index_start + i, 1485 tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
1480 &pdev->dev); 1486 &pdev->dev);
1481 1487
@@ -1600,67 +1606,74 @@ static void set_dtr(const struct tty_struct *tty, int dtr)
1600 * ---------------------------------------------------------------------------- 1606 * ----------------------------------------------------------------------------
1601 */ 1607 */
1602 1608
1603/* Called when the userspace process opens the tty, /dev/noz*. */ 1609static int ntty_install(struct tty_driver *driver, struct tty_struct *tty)
1604static int ntty_open(struct tty_struct *tty, struct file *file)
1605{ 1610{
1606 struct port *port = get_port_by_tty(tty); 1611 struct port *port = get_port_by_tty(tty);
1607 struct nozomi *dc = get_dc_by_tty(tty); 1612 struct nozomi *dc = get_dc_by_tty(tty);
1608 unsigned long flags; 1613 int ret;
1609
1610 if (!port || !dc || dc->state != NOZOMI_STATE_READY) 1614 if (!port || !dc || dc->state != NOZOMI_STATE_READY)
1611 return -ENODEV; 1615 return -ENODEV;
1612 1616 ret = tty_init_termios(tty);
1613 if (mutex_lock_interruptible(&port->tty_sem)) 1617 if (ret == 0) {
1614 return -ERESTARTSYS; 1618 tty_driver_kref_get(driver);
1615 1619 driver->ttys[tty->index] = tty;
1616 port->port.count++;
1617 dc->open_ttys++;
1618
1619 /* Enable interrupt downlink for channel */
1620 if (port->port.count == 1) {
1621 tty->driver_data = port;
1622 tty_port_tty_set(&port->port, tty);
1623 DBG1("open: %d", port->token_dl);
1624 spin_lock_irqsave(&dc->spin_mutex, flags);
1625 dc->last_ier = dc->last_ier | port->token_dl;
1626 writew(dc->last_ier, dc->reg_ier);
1627 spin_unlock_irqrestore(&dc->spin_mutex, flags);
1628 } 1620 }
1629 mutex_unlock(&port->tty_sem); 1621 return ret;
1630 return 0;
1631} 1622}
1632 1623
1633/* Called when the userspace process close the tty, /dev/noz*. Also 1624static void ntty_cleanup(struct tty_struct *tty)
1634 called immediately if ntty_open fails in which case tty->driver_data 1625{
1635 will be NULL an we exit by the first return */ 1626 tty->driver_data = NULL;
1627}
1636 1628
1637static void ntty_close(struct tty_struct *tty, struct file *file) 1629static int ntty_activate(struct tty_port *tport, struct tty_struct *tty)
1638{ 1630{
1639 struct nozomi *dc = get_dc_by_tty(tty); 1631 struct port *port = container_of(tport, struct port, port);
1640 struct port *nport = tty->driver_data; 1632 struct nozomi *dc = port->dc;
1641 struct tty_port *port = &nport->port;
1642 unsigned long flags; 1633 unsigned long flags;
1643 1634
1644 if (!dc || !nport) 1635 DBG1("open: %d", port->token_dl);
1645 return; 1636 spin_lock_irqsave(&dc->spin_mutex, flags);
1637 dc->last_ier = dc->last_ier | port->token_dl;
1638 writew(dc->last_ier, dc->reg_ier);
1639 dc->open_ttys++;
1640 spin_unlock_irqrestore(&dc->spin_mutex, flags);
1641 printk("noz: activated %d: %p\n", tty->index, tport);
1642 return 0;
1643}
1646 1644
1647 /* Users cannot interrupt a close */ 1645static int ntty_open(struct tty_struct *tty, struct file *filp)
1648 mutex_lock(&nport->tty_sem); 1646{
1647 struct port *port = get_port_by_tty(tty);
1648 return tty_port_open(&port->port, tty, filp);
1649}
1649 1650
1650 WARN_ON(!port->count); 1651static void ntty_shutdown(struct tty_port *tport)
1652{
1653 struct port *port = container_of(tport, struct port, port);
1654 struct nozomi *dc = port->dc;
1655 unsigned long flags;
1651 1656
1657 DBG1("close: %d", port->token_dl);
1658 spin_lock_irqsave(&dc->spin_mutex, flags);
1659 dc->last_ier &= ~(port->token_dl);
1660 writew(dc->last_ier, dc->reg_ier);
1652 dc->open_ttys--; 1661 dc->open_ttys--;
1653 port->count--; 1662 spin_unlock_irqrestore(&dc->spin_mutex, flags);
1663 printk("noz: shutdown %p\n", tport);
1664}
1654 1665
1655 if (port->count == 0) { 1666static void ntty_close(struct tty_struct *tty, struct file *filp)
1656 DBG1("close: %d", nport->token_dl); 1667{
1657 tty_port_tty_set(port, NULL); 1668 struct port *port = tty->driver_data;
1658 spin_lock_irqsave(&dc->spin_mutex, flags); 1669 if (port)
1659 dc->last_ier &= ~(nport->token_dl); 1670 tty_port_close(&port->port, tty, filp);
1660 writew(dc->last_ier, dc->reg_ier); 1671}
1661 spin_unlock_irqrestore(&dc->spin_mutex, flags); 1672
1662 } 1673static void ntty_hangup(struct tty_struct *tty)
1663 mutex_unlock(&nport->tty_sem); 1674{
1675 struct port *port = tty->driver_data;
1676 tty_port_hangup(&port->port);
1664} 1677}
1665 1678
1666/* 1679/*
@@ -1906,10 +1919,16 @@ exit_in_buffer:
1906 return rval; 1919 return rval;
1907} 1920}
1908 1921
1922static const struct tty_port_operations noz_tty_port_ops = {
1923 .activate = ntty_activate,
1924 .shutdown = ntty_shutdown,
1925};
1926
1909static const struct tty_operations tty_ops = { 1927static const struct tty_operations tty_ops = {
1910 .ioctl = ntty_ioctl, 1928 .ioctl = ntty_ioctl,
1911 .open = ntty_open, 1929 .open = ntty_open,
1912 .close = ntty_close, 1930 .close = ntty_close,
1931 .hangup = ntty_hangup,
1913 .write = ntty_write, 1932 .write = ntty_write,
1914 .write_room = ntty_write_room, 1933 .write_room = ntty_write_room,
1915 .unthrottle = ntty_unthrottle, 1934 .unthrottle = ntty_unthrottle,
@@ -1917,6 +1936,8 @@ static const struct tty_operations tty_ops = {
1917 .chars_in_buffer = ntty_chars_in_buffer, 1936 .chars_in_buffer = ntty_chars_in_buffer,
1918 .tiocmget = ntty_tiocmget, 1937 .tiocmget = ntty_tiocmget,
1919 .tiocmset = ntty_tiocmset, 1938 .tiocmset = ntty_tiocmset,
1939 .install = ntty_install,
1940 .cleanup = ntty_cleanup,
1920}; 1941};
1921 1942
1922/* Module initialization */ 1943/* Module initialization */