diff options
-rw-r--r-- | drivers/char/isicom.c | 151 |
1 files changed, 44 insertions, 107 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 29e28b756336..adaf833c5431 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1520,37 +1520,6 @@ static void isicom_flush_buffer(struct tty_struct *tty) | |||
1520 | * Driver init and deinit functions | 1520 | * Driver init and deinit functions |
1521 | */ | 1521 | */ |
1522 | 1522 | ||
1523 | static int __devinit isicom_register_ioregion(struct pci_dev *pdev, | ||
1524 | const unsigned int index) | ||
1525 | { | ||
1526 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1527 | |||
1528 | if (!board->base) | ||
1529 | return -EINVAL; | ||
1530 | |||
1531 | if (!request_region(board->base, 16, ISICOM_NAME)) { | ||
1532 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " | ||
1533 | "will be disabled.\n", board->base, board->base + 15, | ||
1534 | index + 1); | ||
1535 | return -EBUSY; | ||
1536 | } | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | static void isicom_unregister_ioregion(struct pci_dev *pdev) | ||
1542 | { | ||
1543 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1544 | |||
1545 | if (!board->base) | ||
1546 | return; | ||
1547 | |||
1548 | release_region(board->base, 16); | ||
1549 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n", | ||
1550 | board->base, board->base + 15); | ||
1551 | board->base = 0; | ||
1552 | } | ||
1553 | |||
1554 | static const struct tty_operations isicom_ops = { | 1523 | static const struct tty_operations isicom_ops = { |
1555 | .open = isicom_open, | 1524 | .open = isicom_open, |
1556 | .close = isicom_close, | 1525 | .close = isicom_close, |
@@ -1571,70 +1540,6 @@ static const struct tty_operations isicom_ops = { | |||
1571 | .tiocmset = isicom_tiocmset, | 1540 | .tiocmset = isicom_tiocmset, |
1572 | }; | 1541 | }; |
1573 | 1542 | ||
1574 | static int __devinit isicom_register_tty_driver(void) | ||
1575 | { | ||
1576 | int error = -ENOMEM; | ||
1577 | |||
1578 | /* tty driver structure initialization */ | ||
1579 | isicom_normal = alloc_tty_driver(PORT_COUNT); | ||
1580 | if (!isicom_normal) | ||
1581 | goto end; | ||
1582 | |||
1583 | isicom_normal->owner = THIS_MODULE; | ||
1584 | isicom_normal->name = "ttyM"; | ||
1585 | isicom_normal->major = ISICOM_NMAJOR; | ||
1586 | isicom_normal->minor_start = 0; | ||
1587 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | ||
1588 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; | ||
1589 | isicom_normal->init_termios = tty_std_termios; | ||
1590 | isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | | ||
1591 | CLOCAL; | ||
1592 | isicom_normal->flags = TTY_DRIVER_REAL_RAW; | ||
1593 | tty_set_operations(isicom_normal, &isicom_ops); | ||
1594 | |||
1595 | if ((error = tty_register_driver(isicom_normal))) { | ||
1596 | pr_dbg("Couldn't register the dialin driver, error=%d\n", | ||
1597 | error); | ||
1598 | put_tty_driver(isicom_normal); | ||
1599 | } | ||
1600 | end: | ||
1601 | return error; | ||
1602 | } | ||
1603 | |||
1604 | static void isicom_unregister_tty_driver(void) | ||
1605 | { | ||
1606 | int error; | ||
1607 | |||
1608 | if ((error = tty_unregister_driver(isicom_normal))) | ||
1609 | pr_dbg("couldn't unregister normal driver, error=%d.\n", error); | ||
1610 | |||
1611 | put_tty_driver(isicom_normal); | ||
1612 | } | ||
1613 | |||
1614 | static int __devinit isicom_register_isr(struct pci_dev *pdev, | ||
1615 | const unsigned int index) | ||
1616 | { | ||
1617 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1618 | unsigned long irqflags = IRQF_DISABLED; | ||
1619 | int retval = -EINVAL; | ||
1620 | |||
1621 | if (!board->base) | ||
1622 | goto end; | ||
1623 | |||
1624 | if (board->isa == NO) | ||
1625 | irqflags |= IRQF_SHARED; | ||
1626 | |||
1627 | retval = request_irq(board->irq, isicom_interrupt, irqflags, | ||
1628 | ISICOM_NAME, board); | ||
1629 | if (retval < 0) | ||
1630 | dev_warn(&pdev->dev, "Could not install handler at Irq %d. " | ||
1631 | "Card%d will be disabled.\n", board->irq, index + 1); | ||
1632 | else | ||
1633 | retval = 0; | ||
1634 | end: | ||
1635 | return retval; | ||
1636 | } | ||
1637 | |||
1638 | static int __devinit reset_card(struct pci_dev *pdev, | 1543 | static int __devinit reset_card(struct pci_dev *pdev, |
1639 | const unsigned int card, unsigned int *signature) | 1544 | const unsigned int card, unsigned int *signature) |
1640 | { | 1545 | { |
@@ -1913,13 +1818,21 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1913 | 1818 | ||
1914 | pci_set_drvdata(pdev, board); | 1819 | pci_set_drvdata(pdev, board); |
1915 | 1820 | ||
1916 | retval = isicom_register_ioregion(pdev, index); | 1821 | if (!request_region(board->base, 16, ISICOM_NAME)) { |
1917 | if (retval < 0) | 1822 | dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " |
1823 | "will be disabled.\n", board->base, board->base + 15, | ||
1824 | index + 1); | ||
1825 | retval = -EBUSY; | ||
1918 | goto err; | 1826 | goto err; |
1827 | } | ||
1919 | 1828 | ||
1920 | retval = isicom_register_isr(pdev, index); | 1829 | retval = request_irq(board->irq, isicom_interrupt, |
1921 | if (retval < 0) | 1830 | IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); |
1831 | if (retval < 0) { | ||
1832 | dev_err(&pdev->dev, "Could not install handler at Irq %d. " | ||
1833 | "Card%d will be disabled.\n", board->irq, index + 1); | ||
1922 | goto errunrr; | 1834 | goto errunrr; |
1835 | } | ||
1923 | 1836 | ||
1924 | retval = reset_card(pdev, index, &signature); | 1837 | retval = reset_card(pdev, index, &signature); |
1925 | if (retval < 0) | 1838 | if (retval < 0) |
@@ -1934,7 +1847,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1934 | errunri: | 1847 | errunri: |
1935 | free_irq(board->irq, board); | 1848 | free_irq(board->irq, board); |
1936 | errunrr: | 1849 | errunrr: |
1937 | isicom_unregister_ioregion(pdev); | 1850 | release_region(board->base, 16); |
1938 | err: | 1851 | err: |
1939 | board->base = 0; | 1852 | board->base = 0; |
1940 | return retval; | 1853 | return retval; |
@@ -1945,7 +1858,7 @@ static void __devexit isicom_remove(struct pci_dev *pdev) | |||
1945 | struct isi_board *board = pci_get_drvdata(pdev); | 1858 | struct isi_board *board = pci_get_drvdata(pdev); |
1946 | 1859 | ||
1947 | free_irq(board->irq, board); | 1860 | free_irq(board->irq, board); |
1948 | isicom_unregister_ioregion(pdev); | 1861 | release_region(board->base, 16); |
1949 | } | 1862 | } |
1950 | 1863 | ||
1951 | static int __devinit isicom_setup(void) | 1864 | static int __devinit isicom_setup(void) |
@@ -1991,14 +1904,35 @@ static int __devinit isicom_setup(void) | |||
1991 | "Disabling Card%d...\n", irq[idx], idx + 1); | 1904 | "Disabling Card%d...\n", irq[idx], idx + 1); |
1992 | } | 1905 | } |
1993 | 1906 | ||
1994 | retval = isicom_register_tty_driver(); | 1907 | /* tty driver structure initialization */ |
1995 | if (retval < 0) | 1908 | isicom_normal = alloc_tty_driver(PORT_COUNT); |
1909 | if (!isicom_normal) { | ||
1910 | retval = -ENOMEM; | ||
1996 | goto error; | 1911 | goto error; |
1912 | } | ||
1913 | |||
1914 | isicom_normal->owner = THIS_MODULE; | ||
1915 | isicom_normal->name = "ttyM"; | ||
1916 | isicom_normal->major = ISICOM_NMAJOR; | ||
1917 | isicom_normal->minor_start = 0; | ||
1918 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | ||
1919 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; | ||
1920 | isicom_normal->init_termios = tty_std_termios; | ||
1921 | isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | | ||
1922 | CLOCAL; | ||
1923 | isicom_normal->flags = TTY_DRIVER_REAL_RAW; | ||
1924 | tty_set_operations(isicom_normal, &isicom_ops); | ||
1925 | |||
1926 | retval = tty_register_driver(isicom_normal); | ||
1927 | if (retval) { | ||
1928 | pr_dbg("Couldn't register the dialin driver\n"); | ||
1929 | goto err_puttty; | ||
1930 | } | ||
1997 | 1931 | ||
1998 | retval = pci_register_driver(&isicom_driver); | 1932 | retval = pci_register_driver(&isicom_driver); |
1999 | if (retval < 0) { | 1933 | if (retval < 0) { |
2000 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); | 1934 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); |
2001 | goto errtty; | 1935 | goto err_unrtty; |
2002 | } | 1936 | } |
2003 | 1937 | ||
2004 | init_timer(&tx); | 1938 | init_timer(&tx); |
@@ -2009,8 +1943,10 @@ static int __devinit isicom_setup(void) | |||
2009 | add_timer(&tx); | 1943 | add_timer(&tx); |
2010 | 1944 | ||
2011 | return 0; | 1945 | return 0; |
2012 | errtty: | 1946 | err_unrtty: |
2013 | isicom_unregister_tty_driver(); | 1947 | tty_unregister_driver(isicom_normal); |
1948 | err_puttty: | ||
1949 | put_tty_driver(isicom_normal); | ||
2014 | error: | 1950 | error: |
2015 | return retval; | 1951 | return retval; |
2016 | } | 1952 | } |
@@ -2025,7 +1961,8 @@ static void __exit isicom_exit(void) | |||
2025 | msleep(10); | 1961 | msleep(10); |
2026 | 1962 | ||
2027 | pci_unregister_driver(&isicom_driver); | 1963 | pci_unregister_driver(&isicom_driver); |
2028 | isicom_unregister_tty_driver(); | 1964 | tty_unregister_driver(isicom_normal); |
1965 | put_tty_driver(isicom_normal); | ||
2029 | } | 1966 | } |
2030 | 1967 | ||
2031 | module_init(isicom_setup); | 1968 | module_init(isicom_setup); |