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.c85
1 files changed, 45 insertions, 40 deletions
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 9a34a1935283..d6102b644b55 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -353,6 +353,7 @@ struct ctrl_ul {
353 353
354/* This holds all information that is needed regarding a port */ 354/* This holds all information that is needed regarding a port */
355struct port { 355struct port {
356 struct tty_port port;
356 u8 update_flow_control; 357 u8 update_flow_control;
357 struct ctrl_ul ctrl_ul; 358 struct ctrl_ul ctrl_ul;
358 struct ctrl_dl ctrl_dl; 359 struct ctrl_dl ctrl_dl;
@@ -365,8 +366,6 @@ struct port {
365 u8 toggle_ul; 366 u8 toggle_ul;
366 u16 token_dl; 367 u16 token_dl;
367 368
368 struct tty_struct *tty;
369 int tty_open_count;
370 /* mutex to ensure one access patch to this port */ 369 /* mutex to ensure one access patch to this port */
371 struct mutex tty_sem; 370 struct mutex tty_sem;
372 wait_queue_head_t tty_wait; 371 wait_queue_head_t tty_wait;
@@ -788,14 +787,14 @@ static void disable_transmit_dl(enum port_type port, struct nozomi *dc)
788 * Return 1 - send buffer to card and ack. 787 * Return 1 - send buffer to card and ack.
789 * Return 0 - don't ack, don't send buffer to card. 788 * Return 0 - don't ack, don't send buffer to card.
790 */ 789 */
791static int send_data(enum port_type index, const struct nozomi *dc) 790static int send_data(enum port_type index, struct nozomi *dc)
792{ 791{
793 u32 size = 0; 792 u32 size = 0;
794 const struct port *port = &dc->port[index]; 793 struct port *port = &dc->port[index];
795 const u8 toggle = port->toggle_ul; 794 const u8 toggle = port->toggle_ul;
796 void __iomem *addr = port->ul_addr[toggle]; 795 void __iomem *addr = port->ul_addr[toggle];
797 const u32 ul_size = port->ul_size[toggle]; 796 const u32 ul_size = port->ul_size[toggle];
798 struct tty_struct *tty = port->tty; 797 struct tty_struct *tty = tty_port_tty_get(&port->port);
799 798
800 /* Get data from tty and place in buf for now */ 799 /* Get data from tty and place in buf for now */
801 size = __kfifo_get(port->fifo_ul, dc->send_buf, 800 size = __kfifo_get(port->fifo_ul, dc->send_buf,
@@ -803,6 +802,7 @@ static int send_data(enum port_type index, const struct nozomi *dc)
803 802
804 if (size == 0) { 803 if (size == 0) {
805 DBG4("No more data to send, disable link:"); 804 DBG4("No more data to send, disable link:");
805 tty_kref_put(tty);
806 return 0; 806 return 0;
807 } 807 }
808 808
@@ -815,6 +815,7 @@ static int send_data(enum port_type index, const struct nozomi *dc)
815 if (tty) 815 if (tty)
816 tty_wakeup(tty); 816 tty_wakeup(tty);
817 817
818 tty_kref_put(tty);
818 return 1; 819 return 1;
819} 820}
820 821
@@ -826,7 +827,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
826 u32 offset = 4; 827 u32 offset = 4;
827 struct port *port = &dc->port[index]; 828 struct port *port = &dc->port[index];
828 void __iomem *addr = port->dl_addr[port->toggle_dl]; 829 void __iomem *addr = port->dl_addr[port->toggle_dl];
829 struct tty_struct *tty = port->tty; 830 struct tty_struct *tty = tty_port_tty_get(&port->port);
830 int i; 831 int i;
831 832
832 if (unlikely(!tty)) { 833 if (unlikely(!tty)) {
@@ -870,7 +871,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
870 } 871 }
871 872
872 set_bit(index, &dc->flip); 873 set_bit(index, &dc->flip);
873 874 tty_kref_put(tty);
874 return 1; 875 return 1;
875} 876}
876 877
@@ -1276,9 +1277,15 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)
1276 1277
1277exit_handler: 1278exit_handler:
1278 spin_unlock(&dc->spin_mutex); 1279 spin_unlock(&dc->spin_mutex);
1279 for (a = 0; a < NOZOMI_MAX_PORTS; a++) 1280 for (a = 0; a < NOZOMI_MAX_PORTS; a++) {
1280 if (test_and_clear_bit(a, &dc->flip)) 1281 struct tty_struct *tty;
1281 tty_flip_buffer_push(dc->port[a].tty); 1282 if (test_and_clear_bit(a, &dc->flip)) {
1283 tty = tty_port_tty_get(&dc->port[a].port);
1284 if (tty)
1285 tty_flip_buffer_push(tty);
1286 tty_kref_put(tty);
1287 }
1288 }
1282 return IRQ_HANDLED; 1289 return IRQ_HANDLED;
1283none: 1290none:
1284 spin_unlock(&dc->spin_mutex); 1291 spin_unlock(&dc->spin_mutex);
@@ -1453,12 +1460,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
1453 1460
1454 for (i = 0; i < MAX_PORT; i++) { 1461 for (i = 0; i < MAX_PORT; i++) {
1455 mutex_init(&dc->port[i].tty_sem); 1462 mutex_init(&dc->port[i].tty_sem);
1456 dc->port[i].tty_open_count = 0; 1463 tty_port_init(&dc->port[i].port);
1457 dc->port[i].tty = NULL;
1458 tty_register_device(ntty_driver, dc->index_start + i, 1464 tty_register_device(ntty_driver, dc->index_start + i,
1459 &pdev->dev); 1465 &pdev->dev);
1460 } 1466 }
1461
1462 return 0; 1467 return 0;
1463 1468
1464err_free_sbuf: 1469err_free_sbuf:
@@ -1482,14 +1487,16 @@ static void __devexit tty_exit(struct nozomi *dc)
1482 1487
1483 flush_scheduled_work(); 1488 flush_scheduled_work();
1484 1489
1485 for (i = 0; i < MAX_PORT; ++i) 1490 for (i = 0; i < MAX_PORT; ++i) {
1486 if (dc->port[i].tty && \ 1491 struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port);
1487 list_empty(&dc->port[i].tty->hangup_work.entry)) 1492 if (tty && list_empty(&tty->hangup_work.entry))
1488 tty_hangup(dc->port[i].tty); 1493 tty_hangup(tty);
1489 1494 tty_kref_put(tty);
1495 }
1496 /* Racy below - surely should wait for scheduled work to be done or
1497 complete off a hangup method ? */
1490 while (dc->open_ttys) 1498 while (dc->open_ttys)
1491 msleep(1); 1499 msleep(1);
1492
1493 for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) 1500 for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
1494 tty_unregister_device(ntty_driver, i); 1501 tty_unregister_device(ntty_driver, i);
1495} 1502}
@@ -1579,23 +1586,22 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
1579 if (mutex_lock_interruptible(&port->tty_sem)) 1586 if (mutex_lock_interruptible(&port->tty_sem))
1580 return -ERESTARTSYS; 1587 return -ERESTARTSYS;
1581 1588
1582 port->tty_open_count++; 1589 port->port.count++;
1583 dc->open_ttys++; 1590 dc->open_ttys++;
1584 1591
1585 /* Enable interrupt downlink for channel */ 1592 /* Enable interrupt downlink for channel */
1586 if (port->tty_open_count == 1) { 1593 if (port->port.count == 1) {
1594 /* FIXME: is this needed now ? */
1587 tty->low_latency = 1; 1595 tty->low_latency = 1;
1588 tty->driver_data = port; 1596 tty->driver_data = port;
1589 port->tty = tty; 1597 tty_port_tty_set(&port->port, tty);
1590 DBG1("open: %d", port->token_dl); 1598 DBG1("open: %d", port->token_dl);
1591 spin_lock_irqsave(&dc->spin_mutex, flags); 1599 spin_lock_irqsave(&dc->spin_mutex, flags);
1592 dc->last_ier = dc->last_ier | port->token_dl; 1600 dc->last_ier = dc->last_ier | port->token_dl;
1593 writew(dc->last_ier, dc->reg_ier); 1601 writew(dc->last_ier, dc->reg_ier);
1594 spin_unlock_irqrestore(&dc->spin_mutex, flags); 1602 spin_unlock_irqrestore(&dc->spin_mutex, flags);
1595 } 1603 }
1596
1597 mutex_unlock(&port->tty_sem); 1604 mutex_unlock(&port->tty_sem);
1598
1599 return 0; 1605 return 0;
1600} 1606}
1601 1607
@@ -1606,31 +1612,30 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
1606static void ntty_close(struct tty_struct *tty, struct file *file) 1612static void ntty_close(struct tty_struct *tty, struct file *file)
1607{ 1613{
1608 struct nozomi *dc = get_dc_by_tty(tty); 1614 struct nozomi *dc = get_dc_by_tty(tty);
1609 struct port *port = tty->driver_data; 1615 struct port *nport = tty->driver_data;
1616 struct tty_port *port = &nport->port;
1610 unsigned long flags; 1617 unsigned long flags;
1611 1618
1612 if (!dc || !port) 1619 if (!dc || !nport)
1613 return; 1620 return;
1614 1621
1615 if (mutex_lock_interruptible(&port->tty_sem)) 1622 /* Users cannot interrupt a close */
1616 return; 1623 mutex_lock(&nport->tty_sem);
1617 1624
1618 if (!port->tty_open_count) 1625 WARN_ON(!port->count);
1619 goto exit;
1620 1626
1621 dc->open_ttys--; 1627 dc->open_ttys--;
1622 port->tty_open_count--; 1628 port->count--;
1629 tty_port_tty_set(port, NULL);
1623 1630
1624 if (port->tty_open_count == 0) { 1631 if (port->count == 0) {
1625 DBG1("close: %d", port->token_dl); 1632 DBG1("close: %d", nport->token_dl);
1626 spin_lock_irqsave(&dc->spin_mutex, flags); 1633 spin_lock_irqsave(&dc->spin_mutex, flags);
1627 dc->last_ier &= ~(port->token_dl); 1634 dc->last_ier &= ~(nport->token_dl);
1628 writew(dc->last_ier, dc->reg_ier); 1635 writew(dc->last_ier, dc->reg_ier);
1629 spin_unlock_irqrestore(&dc->spin_mutex, flags); 1636 spin_unlock_irqrestore(&dc->spin_mutex, flags);
1630 } 1637 }
1631 1638 mutex_unlock(&nport->tty_sem);
1632exit:
1633 mutex_unlock(&port->tty_sem);
1634} 1639}
1635 1640
1636/* 1641/*
@@ -1660,7 +1665,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
1660 return -EAGAIN; 1665 return -EAGAIN;
1661 } 1666 }
1662 1667
1663 if (unlikely(!port->tty_open_count)) { 1668 if (unlikely(!port->port.count)) {
1664 DBG1(" "); 1669 DBG1(" ");
1665 goto exit; 1670 goto exit;
1666 } 1671 }
@@ -1710,7 +1715,7 @@ static int ntty_write_room(struct tty_struct *tty)
1710 if (!mutex_trylock(&port->tty_sem)) 1715 if (!mutex_trylock(&port->tty_sem))
1711 return 0; 1716 return 0;
1712 1717
1713 if (!port->tty_open_count) 1718 if (!port->port.count)
1714 goto exit; 1719 goto exit;
1715 1720
1716 room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); 1721 room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
@@ -1866,7 +1871,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
1866 goto exit_in_buffer; 1871 goto exit_in_buffer;
1867 } 1872 }
1868 1873
1869 if (unlikely(!port->tty_open_count)) { 1874 if (unlikely(!port->port.count)) {
1870 dev_err(&dc->pdev->dev, "No tty open?\n"); 1875 dev_err(&dc->pdev->dev, "No tty open?\n");
1871 rval = -ENODEV; 1876 rval = -ENODEV;
1872 goto exit_in_buffer; 1877 goto exit_in_buffer;