aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/isicom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/isicom.c')
-rw-r--r--drivers/char/isicom.c108
1 files changed, 48 insertions, 60 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 01084abffddf..43ab9edc76f5 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -183,7 +183,7 @@ static DEFINE_TIMER(tx, isicom_tx, 0, 0);
183/* baud index mappings from linux defns to isi */ 183/* baud index mappings from linux defns to isi */
184 184
185static signed char linuxb_to_isib[] = { 185static signed char linuxb_to_isib[] = {
186 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19 186 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
187}; 187};
188 188
189struct isi_board { 189struct isi_board {
@@ -213,8 +213,6 @@ struct isi_port {
213 struct tty_struct * tty; 213 struct tty_struct * tty;
214 wait_queue_head_t close_wait; 214 wait_queue_head_t close_wait;
215 wait_queue_head_t open_wait; 215 wait_queue_head_t open_wait;
216 struct work_struct hangup_tq;
217 struct work_struct bh_tqueue;
218 unsigned char * xmit_buf; 216 unsigned char * xmit_buf;
219 int xmit_head; 217 int xmit_head;
220 int xmit_tail; 218 int xmit_tail;
@@ -510,7 +508,7 @@ static void isicom_tx(unsigned long _data)
510 if (port->xmit_cnt <= 0) 508 if (port->xmit_cnt <= 0)
511 port->status &= ~ISI_TXOK; 509 port->status &= ~ISI_TXOK;
512 if (port->xmit_cnt <= WAKEUP_CHARS) 510 if (port->xmit_cnt <= WAKEUP_CHARS)
513 schedule_work(&port->bh_tqueue); 511 tty_wakeup(tty);
514 unlock_card(&isi_card[card]); 512 unlock_card(&isi_card[card]);
515 } 513 }
516 514
@@ -524,21 +522,6 @@ sched_again:
524 mod_timer(&tx, jiffies + msecs_to_jiffies(10)); 522 mod_timer(&tx, jiffies + msecs_to_jiffies(10));
525} 523}
526 524
527/* Interrupt handlers */
528
529
530static void isicom_bottomhalf(struct work_struct *work)
531{
532 struct isi_port *port = container_of(work, struct isi_port, bh_tqueue);
533 struct tty_struct *tty = port->tty;
534
535 if (!tty)
536 return;
537
538 tty_wakeup(tty);
539 wake_up_interruptible(&tty->write_wait);
540}
541
542/* 525/*
543 * Main interrupt handler routine 526 * Main interrupt handler routine
544 */ 527 */
@@ -557,6 +540,11 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
557 return IRQ_NONE; 540 return IRQ_NONE;
558 541
559 base = card->base; 542 base = card->base;
543
544 /* did the card interrupt us? */
545 if (!(inw(base + 0x0e) & 0x02))
546 return IRQ_NONE;
547
560 spin_lock(&card->card_lock); 548 spin_lock(&card->card_lock);
561 549
562 /* 550 /*
@@ -581,6 +569,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
581 port = card->ports + channel; 569 port = card->ports + channel;
582 if (!(port->flags & ASYNC_INITIALIZED)) { 570 if (!(port->flags & ASYNC_INITIALIZED)) {
583 outw(0x0000, base+0x04); /* enable interrupts */ 571 outw(0x0000, base+0x04); /* enable interrupts */
572 spin_unlock(&card->card_lock);
584 return IRQ_HANDLED; 573 return IRQ_HANDLED;
585 } 574 }
586 575
@@ -609,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
609 pr_dbg("interrupt: DCD->low.\n" 598 pr_dbg("interrupt: DCD->low.\n"
610 ); 599 );
611 port->status &= ~ISI_DCD; 600 port->status &= ~ISI_DCD;
612 schedule_work(&port->hangup_tq); 601 tty_hangup(tty);
613 } 602 }
614 } else if (header & ISI_DCD) { 603 } else if (header & ISI_DCD) {
615 /* Carrier has been detected */ 604 /* Carrier has been detected */
@@ -631,7 +620,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
631 /* start tx ing */ 620 /* start tx ing */
632 port->status |= (ISI_TXOK 621 port->status |= (ISI_TXOK
633 | ISI_CTS); 622 | ISI_CTS);
634 schedule_work(&port->bh_tqueue); 623 tty_wakeup(tty);
635 } 624 }
636 } else if (!(header & ISI_CTS)) { 625 } else if (!(header & ISI_CTS)) {
637 port->tty->hw_stopped = 1; 626 port->tty->hw_stopped = 1;
@@ -695,6 +684,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
695 tty_flip_buffer_push(tty); 684 tty_flip_buffer_push(tty);
696 } 685 }
697 outw(0x0000, base+0x04); /* enable interrupts */ 686 outw(0x0000, base+0x04); /* enable interrupts */
687 spin_unlock(&card->card_lock);
698 688
699 return IRQ_HANDLED; 689 return IRQ_HANDLED;
700} 690}
@@ -720,7 +710,8 @@ static void isicom_config_port(struct isi_port *port)
720 * respectively. 710 * respectively.
721 */ 711 */
722 712
723 if (baud < 1 || baud > 2) 713 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
714 if (baud < 1 || baud > 4)
724 port->tty->termios->c_cflag &= ~CBAUDEX; 715 port->tty->termios->c_cflag &= ~CBAUDEX;
725 else 716 else
726 baud += 15; 717 baud += 15;
@@ -736,6 +727,10 @@ static void isicom_config_port(struct isi_port *port)
736 baud++; /* 57.6 Kbps */ 727 baud++; /* 57.6 Kbps */
737 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 728 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
738 baud +=2; /* 115 Kbps */ 729 baud +=2; /* 115 Kbps */
730 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
731 baud += 3; /* 230 kbps*/
732 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
733 baud += 4; /* 460 kbps*/
739 } 734 }
740 if (linuxb_to_isib[baud] == -1) { 735 if (linuxb_to_isib[baud] == -1) {
741 /* hang up */ 736 /* hang up */
@@ -1460,17 +1455,6 @@ static void isicom_start(struct tty_struct *tty)
1460 port->status |= ISI_TXOK; 1455 port->status |= ISI_TXOK;
1461} 1456}
1462 1457
1463/* hangup et all */
1464static void do_isicom_hangup(struct work_struct *work)
1465{
1466 struct isi_port *port = container_of(work, struct isi_port, hangup_tq);
1467 struct tty_struct *tty;
1468
1469 tty = port->tty;
1470 if (tty)
1471 tty_hangup(tty);
1472}
1473
1474static void isicom_hangup(struct tty_struct *tty) 1458static void isicom_hangup(struct tty_struct *tty)
1475{ 1459{
1476 struct isi_port *port = tty->driver_data; 1460 struct isi_port *port = tty->driver_data;
@@ -1503,7 +1487,6 @@ static void isicom_flush_buffer(struct tty_struct *tty)
1503 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 1487 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1504 spin_unlock_irqrestore(&card->card_lock, flags); 1488 spin_unlock_irqrestore(&card->card_lock, flags);
1505 1489
1506 wake_up_interruptible(&tty->write_wait);
1507 tty_wakeup(tty); 1490 tty_wakeup(tty);
1508} 1491}
1509 1492
@@ -1536,7 +1519,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
1536{ 1519{
1537 struct isi_board *board = pci_get_drvdata(pdev); 1520 struct isi_board *board = pci_get_drvdata(pdev);
1538 unsigned long base = board->base; 1521 unsigned long base = board->base;
1539 unsigned int portcount = 0; 1522 unsigned int sig, portcount = 0;
1540 int retval = 0; 1523 int retval = 0;
1541 1524
1542 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1, 1525 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
@@ -1544,27 +1527,35 @@ static int __devinit reset_card(struct pci_dev *pdev,
1544 1527
1545 inw(base + 0x8); 1528 inw(base + 0x8);
1546 1529
1547 mdelay(10); 1530 msleep(10);
1548 1531
1549 outw(0, base + 0x8); /* Reset */ 1532 outw(0, base + 0x8); /* Reset */
1550 1533
1551 msleep(3000); 1534 msleep(1000);
1552 1535
1553 *signature = inw(base + 0x4) & 0xff; 1536 sig = inw(base + 0x4) & 0xff;
1537
1538 if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1539 sig != 0xee) {
1540 dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1541 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1542 dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1543 retval = -EIO;
1544 goto end;
1545 }
1546
1547 msleep(10);
1554 1548
1555 portcount = inw(base + 0x2); 1549 portcount = inw(base + 0x2);
1556 if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) && 1550 if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
1557 (portcount != 4) && (portcount != 8))) { 1551 portcount != 8 && portcount != 16)) {
1558 dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", 1552 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
1559 inw(base + 0x2), inw(base + 0xe)); 1553 card + 1);
1560 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
1561 "(Possible bad I/O Port Address 0x%lx).\n",
1562 card + 1, base);
1563 retval = -EIO; 1554 retval = -EIO;
1564 goto end; 1555 goto end;
1565 } 1556 }
1566 1557
1567 switch (*signature) { 1558 switch (sig) {
1568 case 0xa5: 1559 case 0xa5:
1569 case 0xbb: 1560 case 0xbb:
1570 case 0xdd: 1561 case 0xdd:
@@ -1572,16 +1563,13 @@ static int __devinit reset_card(struct pci_dev *pdev,
1572 board->shift_count = 12; 1563 board->shift_count = 12;
1573 break; 1564 break;
1574 case 0xcc: 1565 case 0xcc:
1566 case 0xee:
1575 board->port_count = 16; 1567 board->port_count = 16;
1576 board->shift_count = 11; 1568 board->shift_count = 11;
1577 break; 1569 break;
1578 default:
1579 dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
1580 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1581 dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
1582 retval = -EIO;
1583 } 1570 }
1584 dev_info(&pdev->dev, "-Done\n"); 1571 dev_info(&pdev->dev, "-Done\n");
1572 *signature = sig;
1585 1573
1586end: 1574end:
1587 return retval; 1575 return retval;
@@ -1757,7 +1745,7 @@ end:
1757/* 1745/*
1758 * Insmod can set static symbols so keep these static 1746 * Insmod can set static symbols so keep these static
1759 */ 1747 */
1760static int card; 1748static unsigned int card_count;
1761 1749
1762static int __devinit isicom_probe(struct pci_dev *pdev, 1750static int __devinit isicom_probe(struct pci_dev *pdev,
1763 const struct pci_device_id *ent) 1751 const struct pci_device_id *ent)
@@ -1767,7 +1755,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
1767 u8 pciirq; 1755 u8 pciirq;
1768 struct isi_board *board = NULL; 1756 struct isi_board *board = NULL;
1769 1757
1770 if (card >= BOARD_COUNT) 1758 if (card_count >= BOARD_COUNT)
1771 goto err; 1759 goto err;
1772 1760
1773 ioaddr = pci_resource_start(pdev, 3); 1761 ioaddr = pci_resource_start(pdev, 3);
@@ -1785,7 +1773,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
1785 board->index = index; 1773 board->index = index;
1786 board->base = ioaddr; 1774 board->base = ioaddr;
1787 board->irq = pciirq; 1775 board->irq = pciirq;
1788 card++; 1776 card_count++;
1789 1777
1790 pci_set_drvdata(pdev, board); 1778 pci_set_drvdata(pdev, board);
1791 1779
@@ -1795,7 +1783,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
1795 "will be disabled.\n", board->base, board->base + 15, 1783 "will be disabled.\n", board->base, board->base + 15,
1796 index + 1); 1784 index + 1);
1797 retval = -EBUSY; 1785 retval = -EBUSY;
1798 goto err; 1786 goto errdec;
1799 } 1787 }
1800 1788
1801 retval = request_irq(board->irq, isicom_interrupt, 1789 retval = request_irq(board->irq, isicom_interrupt,
@@ -1824,8 +1812,10 @@ errunri:
1824 free_irq(board->irq, board); 1812 free_irq(board->irq, board);
1825errunrr: 1813errunrr:
1826 pci_release_region(pdev, 3); 1814 pci_release_region(pdev, 3);
1827err: 1815errdec:
1828 board->base = 0; 1816 board->base = 0;
1817 card_count--;
1818err:
1829 return retval; 1819 return retval;
1830} 1820}
1831 1821
@@ -1839,6 +1829,8 @@ static void __devexit isicom_remove(struct pci_dev *pdev)
1839 1829
1840 free_irq(board->irq, board); 1830 free_irq(board->irq, board);
1841 pci_release_region(pdev, 3); 1831 pci_release_region(pdev, 3);
1832 board->base = 0;
1833 card_count--;
1842} 1834}
1843 1835
1844static int __init isicom_init(void) 1836static int __init isicom_init(void)
@@ -1846,8 +1838,6 @@ static int __init isicom_init(void)
1846 int retval, idx, channel; 1838 int retval, idx, channel;
1847 struct isi_port *port; 1839 struct isi_port *port;
1848 1840
1849 card = 0;
1850
1851 for(idx = 0; idx < BOARD_COUNT; idx++) { 1841 for(idx = 0; idx < BOARD_COUNT; idx++) {
1852 port = &isi_ports[idx * 16]; 1842 port = &isi_ports[idx * 16];
1853 isi_card[idx].ports = port; 1843 isi_card[idx].ports = port;
@@ -1858,8 +1848,6 @@ static int __init isicom_init(void)
1858 port->channel = channel; 1848 port->channel = channel;
1859 port->close_delay = 50 * HZ/100; 1849 port->close_delay = 50 * HZ/100;
1860 port->closing_wait = 3000 * HZ/100; 1850 port->closing_wait = 3000 * HZ/100;
1861 INIT_WORK(&port->hangup_tq, do_isicom_hangup);
1862 INIT_WORK(&port->bh_tqueue, isicom_bottomhalf);
1863 port->status = 0; 1851 port->status = 0;
1864 init_waitqueue_head(&port->open_wait); 1852 init_waitqueue_head(&port->open_wait);
1865 init_waitqueue_head(&port->close_wait); 1853 init_waitqueue_head(&port->close_wait);