diff options
| -rw-r--r-- | drivers/char/nozomi.c | 115 |
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); | |||
| 414 | static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; | 416 | static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; |
| 415 | static struct tty_driver *ntty_driver; | 417 | static struct tty_driver *ntty_driver; |
| 416 | 418 | ||
| 419 | static 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*. */ | 1609 | static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) |
| 1604 | static 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 | 1624 | static 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 | ||
| 1637 | static void ntty_close(struct tty_struct *tty, struct file *file) | 1629 | static 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 */ | 1645 | static 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); | 1651 | static 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) { | 1666 | static 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 | } | 1673 | static 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 | ||
| 1922 | static const struct tty_port_operations noz_tty_port_ops = { | ||
| 1923 | .activate = ntty_activate, | ||
| 1924 | .shutdown = ntty_shutdown, | ||
| 1925 | }; | ||
| 1926 | |||
| 1909 | static const struct tty_operations tty_ops = { | 1927 | static 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 */ |
