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.c447
1 files changed, 239 insertions, 208 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 49f88c9006cb..9ef8ab301768 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -107,7 +107,6 @@
107 * Omit those entries for boards you don't have installed. 107 * Omit those entries for boards you don't have installed.
108 * 108 *
109 * TODO 109 * TODO
110 * Hotplug
111 * Merge testing 110 * Merge testing
112 * 64-bit verification 111 * 64-bit verification
113 */ 112 */
@@ -146,20 +145,30 @@
146#define isicom_paranoia_check(a, b, c) 0 145#define isicom_paranoia_check(a, b, c) 0
147#endif 146#endif
148 147
148static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
149static void __devexit isicom_remove(struct pci_dev *);
150
149static struct pci_device_id isicom_pci_tbl[] = { 151static struct pci_device_id isicom_pci_tbl[] = {
150 { VENDOR_ID, 0x2028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 152 { PCI_DEVICE(VENDOR_ID, 0x2028) },
151 { VENDOR_ID, 0x2051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 153 { PCI_DEVICE(VENDOR_ID, 0x2051) },
152 { VENDOR_ID, 0x2052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 154 { PCI_DEVICE(VENDOR_ID, 0x2052) },
153 { VENDOR_ID, 0x2053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 155 { PCI_DEVICE(VENDOR_ID, 0x2053) },
154 { VENDOR_ID, 0x2054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 156 { PCI_DEVICE(VENDOR_ID, 0x2054) },
155 { VENDOR_ID, 0x2055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 157 { PCI_DEVICE(VENDOR_ID, 0x2055) },
156 { VENDOR_ID, 0x2056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 158 { PCI_DEVICE(VENDOR_ID, 0x2056) },
157 { VENDOR_ID, 0x2057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 159 { PCI_DEVICE(VENDOR_ID, 0x2057) },
158 { VENDOR_ID, 0x2058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 160 { PCI_DEVICE(VENDOR_ID, 0x2058) },
159 { 0 } 161 { 0 }
160}; 162};
161MODULE_DEVICE_TABLE(pci, isicom_pci_tbl); 163MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
162 164
165static struct pci_driver isicom_driver = {
166 .name = "isicom",
167 .id_table = isicom_pci_tbl,
168 .probe = isicom_probe,
169 .remove = __devexit_p(isicom_remove)
170};
171
163static int prev_card = 3; /* start servicing isi_card[0] */ 172static int prev_card = 3; /* start servicing isi_card[0] */
164static struct tty_driver *isicom_normal; 173static struct tty_driver *isicom_normal;
165 174
@@ -171,8 +180,6 @@ static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int c
171static void isicom_tx(unsigned long _data); 180static void isicom_tx(unsigned long _data);
172static void isicom_start(struct tty_struct *tty); 181static void isicom_start(struct tty_struct *tty);
173 182
174static unsigned char *tmp_buf;
175
176/* baud index mappings from linux defns to isi */ 183/* baud index mappings from linux defns to isi */
177 184
178static signed char linuxb_to_isib[] = { 185static signed char linuxb_to_isib[] = {
@@ -1365,7 +1372,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1365 if (isicom_paranoia_check(port, tty->name, "isicom_write")) 1372 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1366 return 0; 1373 return 0;
1367 1374
1368 if (!tty || !port->xmit_buf || !tmp_buf) 1375 if (!tty || !port->xmit_buf)
1369 return 0; 1376 return 0;
1370 1377
1371 spin_lock_irqsave(&card->card_lock, flags); 1378 spin_lock_irqsave(&card->card_lock, flags);
@@ -1731,32 +1738,39 @@ static void isicom_flush_buffer(struct tty_struct *tty)
1731 tty_wakeup(tty); 1738 tty_wakeup(tty);
1732} 1739}
1733 1740
1741/*
1742 * Driver init and deinit functions
1743 */
1734 1744
1735static int __devinit register_ioregion(void) 1745static int __devinit isicom_register_ioregion(struct pci_dev *pdev,
1746 const unsigned int index)
1736{ 1747{
1737 int count, done=0; 1748 struct isi_board *board = pci_get_drvdata(pdev);
1738 for (count=0; count < BOARD_COUNT; count++ ) { 1749
1739 if (isi_card[count].base) 1750 if (!board->base)
1740 if (!request_region(isi_card[count].base,16,ISICOM_NAME)) { 1751 return -EINVAL;
1741 printk(KERN_DEBUG "ISICOM: I/O Region 0x%lx-0x%lx is busy. Card%d will be disabled.\n", 1752
1742 isi_card[count].base,isi_card[count].base+15,count+1); 1753 if (!request_region(board->base, 16, ISICOM_NAME)) {
1743 isi_card[count].base=0; 1754 dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1744 done++; 1755 "will be disabled.\n", board->base, board->base + 15,
1745 } 1756 index + 1);
1746 } 1757 return -EBUSY;
1747 return done; 1758 }
1759
1760 return 0;
1748} 1761}
1749 1762
1750static void unregister_ioregion(void) 1763static void isicom_unregister_ioregion(struct pci_dev *pdev)
1751{ 1764{
1752 int count; 1765 struct isi_board *board = pci_get_drvdata(pdev);
1753 for (count=0; count < BOARD_COUNT; count++ ) 1766
1754 if (isi_card[count].base) { 1767 if (!board->base)
1755 release_region(isi_card[count].base,16); 1768 return;
1756#ifdef ISICOM_DEBUG 1769
1757 printk(KERN_DEBUG "ISICOM: I/O Region 0x%lx-0x%lx released for Card%d.\n",isi_card[count].base,isi_card[count].base+15,count+1); 1770 release_region(board->base, 16);
1758#endif 1771 dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n",
1759 } 1772 board->base, board->base + 15);
1773 board->base = 0;
1760} 1774}
1761 1775
1762static struct tty_operations isicom_ops = { 1776static struct tty_operations isicom_ops = {
@@ -1820,207 +1834,223 @@ static void isicom_unregister_tty_driver(void)
1820 put_tty_driver(isicom_normal); 1834 put_tty_driver(isicom_normal);
1821} 1835}
1822 1836
1823static int __devinit register_isr(void) 1837static int __devinit isicom_register_isr(struct pci_dev *pdev,
1838 const unsigned int index)
1824{ 1839{
1825 int count, done=0; 1840 struct isi_board *board = pci_get_drvdata(pdev);
1826 unsigned long irqflags; 1841 unsigned long irqflags = SA_INTERRUPT;
1827 1842 int retval = -EINVAL;
1828 for (count=0; count < BOARD_COUNT; count++ ) {
1829 if (isi_card[count].base) {
1830 irqflags = (isi_card[count].isa == YES) ?
1831 SA_INTERRUPT :
1832 (SA_INTERRUPT | SA_SHIRQ);
1833
1834 if (request_irq(isi_card[count].irq,
1835 isicom_interrupt,
1836 irqflags,
1837 ISICOM_NAME, &isi_card[count])) {
1838
1839 printk(KERN_WARNING "ISICOM: Could not"
1840 " install handler at Irq %d."
1841 " Card%d will be disabled.\n",
1842 isi_card[count].irq, count+1);
1843
1844 release_region(isi_card[count].base,16);
1845 isi_card[count].base=0;
1846 }
1847 else
1848 done++;
1849 }
1850 }
1851 return done;
1852}
1853 1843
1854static void __exit unregister_isr(void) 1844 if (!board->base)
1855{ 1845 goto end;
1856 int count;
1857 1846
1858 for (count=0; count < BOARD_COUNT; count++ ) { 1847 if (board->isa == NO)
1859 if (isi_card[count].base) 1848 irqflags |= SA_SHIRQ;
1860 free_irq(isi_card[count].irq, &isi_card[count]); 1849
1861 } 1850 retval = request_irq(board->irq, isicom_interrupt, irqflags,
1851 ISICOM_NAME, board);
1852 if (retval < 0)
1853 dev_warn(&pdev->dev, "Could not install handler at Irq %d. "
1854 "Card%d will be disabled.\n", board->irq, index + 1);
1855 else
1856 retval = 0;
1857end:
1858 return retval;
1862} 1859}
1863 1860
1864static int __devinit isicom_init(void) 1861static int __devinit reset_card(struct pci_dev *pdev,
1862 const unsigned int card, unsigned int *signature)
1865{ 1863{
1866 int card, channel, base; 1864 struct isi_board *board = pci_get_drvdata(pdev);
1867 struct isi_port *port; 1865 unsigned long base = board->base;
1868 unsigned long page; 1866 unsigned int portcount = 0;
1867 int retval = 0;
1869 1868
1870 if (!tmp_buf) { 1869 dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1871 page = get_zeroed_page(GFP_KERNEL); 1870 base);
1872 if (!page) {
1873#ifdef ISICOM_DEBUG
1874 printk(KERN_DEBUG "ISICOM: Couldn't allocate page for tmp_buf.\n");
1875#else
1876 printk(KERN_ERR "ISICOM: Not enough memory...\n");
1877#endif
1878 return 0;
1879 }
1880 tmp_buf = (unsigned char *) page;
1881 }
1882 1871
1883 if (!register_ioregion()) 1872 inw(base + 0x8);
1884 {
1885 printk(KERN_ERR "ISICOM: All required I/O space found busy.\n");
1886 free_page((unsigned long)tmp_buf);
1887 return 0;
1888 }
1889 if (isicom_register_tty_driver())
1890 {
1891 unregister_ioregion();
1892 free_page((unsigned long)tmp_buf);
1893 return 0;
1894 }
1895 if (!register_isr())
1896 {
1897 isicom_unregister_tty_driver();
1898 /* ioports already uregistered in register_isr */
1899 free_page((unsigned long)tmp_buf);
1900 return 0;
1901 }
1902 1873
1903 memset(isi_ports, 0, sizeof(isi_ports)); 1874 mdelay(10);
1904 for (card = 0; card < BOARD_COUNT; card++) { 1875
1905 port = &isi_ports[card * 16]; 1876 outw(0, base + 0x8); /* Reset */
1906 isi_card[card].ports = port; 1877
1907 spin_lock_init(&isi_card[card].card_lock); 1878 msleep(3000);
1908 base = isi_card[card].base; 1879
1909 for (channel = 0; channel < 16; channel++, port++) { 1880 *signature = inw(base + 0x4) & 0xff;
1910 port->magic = ISICOM_MAGIC; 1881
1911 port->card = &isi_card[card]; 1882 if (board->isa == YES) {
1912 port->channel = channel; 1883 if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) {
1913 port->close_delay = 50 * HZ/100; 1884 dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
1914 port->closing_wait = 3000 * HZ/100; 1885 inw(base + 0x2), inw(base + 0xe));
1915 INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); 1886 dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure "
1916 INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); 1887 "(Possible bad I/O Port Address 0x%lx).\n",
1917 port->status = 0; 1888 card + 1, base);
1918 init_waitqueue_head(&port->open_wait); 1889 retval = -EIO;
1919 init_waitqueue_head(&port->close_wait); 1890 goto end;
1920 /* . . . */
1921 } 1891 }
1892 } else {
1893 portcount = inw(base + 0x2);
1894 if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
1895 (portcount != 4) && (portcount != 8))) {
1896 dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
1897 inw(base + 0x2), inw(base + 0xe));
1898 dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
1899 "(Possible bad I/O Port Address 0x%lx).\n",
1900 card + 1, base);
1901 retval = -EIO;
1902 goto end;
1903 }
1904 }
1905
1906 switch (*signature) {
1907 case 0xa5:
1908 case 0xbb:
1909 case 0xdd:
1910 board->port_count = (board->isa == NO && portcount == 4) ? 4 :
1911 8;
1912 board->shift_count = 12;
1913 break;
1914 case 0xcc:
1915 board->port_count = 16;
1916 board->shift_count = 11;
1917 break;
1918 default:
1919 dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
1920 "bad I/O Port Address 0x%lx).\n", card + 1, base);
1921 dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
1922 retval = -EIO;
1922 } 1923 }
1924 dev_info(&pdev->dev, "-Done\n");
1923 1925
1924 return 1; 1926end:
1927 return retval;
1925} 1928}
1926 1929
1927/* 1930/*
1928 * Insmod can set static symbols so keep these static 1931 * Insmod can set static symbols so keep these static
1929 */ 1932 */
1930
1931static int io[4]; 1933static int io[4];
1932static int irq[4]; 1934static int irq[4];
1935static int card;
1936
1937static int __devinit isicom_probe(struct pci_dev *pdev,
1938 const struct pci_device_id *ent)
1939{
1940 unsigned int ioaddr, signature, index;
1941 int retval = -EPERM;
1942 u8 pciirq;
1943 struct isi_board *board = NULL;
1944
1945 if (card >= BOARD_COUNT)
1946 goto err;
1947
1948 ioaddr = pci_resource_start(pdev, 3);
1949 /* i.e at offset 0x1c in the PCI configuration register space. */
1950 pciirq = pdev->irq;
1951 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1952
1953 /* allot the first empty slot in the array */
1954 for (index = 0; index < BOARD_COUNT; index++)
1955 if (isi_card[index].base == 0) {
1956 board = &isi_card[index];
1957 break;
1958 }
1959
1960 board->base = ioaddr;
1961 board->irq = pciirq;
1962 board->isa = NO;
1963 card++;
1964
1965 pci_set_drvdata(pdev, board);
1966
1967 retval = isicom_register_ioregion(pdev, index);
1968 if (retval < 0)
1969 goto err;
1970
1971 retval = isicom_register_isr(pdev, index);
1972 if (retval < 0)
1973 goto errunrr;
1974
1975 retval = reset_card(pdev, index, &signature);
1976 if (retval < 0)
1977 goto errunri;
1978
1979 return 0;
1980
1981errunri:
1982 free_irq(board->irq, board);
1983errunrr:
1984 isicom_unregister_ioregion(pdev);
1985err:
1986 board->base = 0;
1987 return retval;
1988}
1989
1990static void __devexit isicom_remove(struct pci_dev *pdev)
1991{
1992 struct isi_board *board = pci_get_drvdata(pdev);
1993
1994 free_irq(board->irq, board);
1995 isicom_unregister_ioregion(pdev);
1996}
1933 1997
1934static int __devinit isicom_setup(void) 1998static int __devinit isicom_setup(void)
1935{ 1999{
1936 struct pci_dev *dev = NULL; 2000 int retval, idx, channel;
1937 int retval, card, idx, count; 2001 struct isi_port *port;
1938 unsigned char pciirq;
1939 unsigned int ioaddr;
1940 2002
1941 card = 0; 2003 card = 0;
1942 for (idx=0; idx < BOARD_COUNT; idx++) { 2004 memset(isi_ports, 0, sizeof(isi_ports));
1943 if (io[idx]) {
1944 isi_card[idx].base=io[idx];
1945 isi_card[idx].irq=irq[idx];
1946 isi_card[idx].isa=YES;
1947 card++;
1948 }
1949 else {
1950 isi_card[idx].base = 0;
1951 isi_card[idx].irq = 0;
1952 }
1953 }
1954
1955 for (idx=0 ;idx < card; idx++) {
1956 if (!((isi_card[idx].irq==2)||(isi_card[idx].irq==3)||
1957 (isi_card[idx].irq==4)||(isi_card[idx].irq==5)||
1958 (isi_card[idx].irq==7)||(isi_card[idx].irq==10)||
1959 (isi_card[idx].irq==11)||(isi_card[idx].irq==12)||
1960 (isi_card[idx].irq==15))) {
1961
1962 if (isi_card[idx].base) {
1963 printk(KERN_ERR "ISICOM: Irq %d unsupported. Disabling Card%d...\n",
1964 isi_card[idx].irq, idx+1);
1965 isi_card[idx].base=0;
1966 card--;
1967 }
1968 }
1969 }
1970 2005
1971 if (card < BOARD_COUNT) { 2006 for(idx = 0; idx < BOARD_COUNT; idx++) {
1972 for (idx=0; idx < DEVID_COUNT; idx++) { 2007 port = &isi_ports[idx * 16];
1973 dev = NULL; 2008 isi_card[idx].ports = port;
1974 for (;;){ 2009 spin_lock_init(&isi_card[idx].card_lock);
1975 if (!(dev = pci_find_device(VENDOR_ID, isicom_pci_tbl[idx].device, dev))) 2010 for (channel = 0; channel < 16; channel++, port++) {
1976 break; 2011 port->magic = ISICOM_MAGIC;
1977 if (card >= BOARD_COUNT) 2012 port->card = &isi_card[idx];
1978 break; 2013 port->channel = channel;
2014 port->close_delay = 50 * HZ/100;
2015 port->closing_wait = 3000 * HZ/100;
2016 INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
2017 INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
2018 port->status = 0;
2019 init_waitqueue_head(&port->open_wait);
2020 init_waitqueue_head(&port->close_wait);
2021 /* . . . */
2022 }
2023 isi_card[idx].base = 0;
2024 isi_card[idx].irq = 0;
1979 2025
1980 if (pci_enable_device(dev)) 2026 if (!io[idx])
1981 break; 2027 continue;
1982 2028
1983 /* found a PCI ISI card! */ 2029 if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4 ||
1984 ioaddr = pci_resource_start (dev, 3); 2030 irq[idx] == 5 || irq[idx] == 7 ||
1985 /* i.e at offset 0x1c in the 2031 irq[idx] == 10 || irq[idx] == 11 ||
1986 * PCI configuration register 2032 irq[idx] == 12 || irq[idx] == 15) {
1987 * space. 2033 printk(KERN_ERR "ISICOM: ISA not supported yet.\n");
1988 */ 2034 retval = -EINVAL;
1989 pciirq = dev->irq; 2035 goto error;
1990 printk(KERN_INFO "ISI PCI Card(Device ID 0x%x)\n", isicom_pci_tbl[idx].device); 2036 } else
1991 /* 2037 printk(KERN_ERR "ISICOM: Irq %d unsupported. "
1992 * allot the first empty slot in the array 2038 "Disabling Card%d...\n", irq[idx], idx + 1);
1993 */
1994 for (count=0; count < BOARD_COUNT; count++) {
1995 if (isi_card[count].base == 0) {
1996 isi_card[count].base = ioaddr;
1997 isi_card[count].irq = pciirq;
1998 isi_card[count].isa = NO;
1999 card++;
2000 break;
2001 }
2002 }
2003 }
2004 if (card >= BOARD_COUNT) break;
2005 }
2006 } 2039 }
2007 2040
2008 if (!(isi_card[0].base || isi_card[1].base || isi_card[2].base || isi_card[3].base)) { 2041 retval = isicom_register_tty_driver();
2009 printk(KERN_ERR "ISICOM: No valid card configuration. Driver cannot be initialized...\n"); 2042 if (retval < 0)
2010 return -EIO; 2043 goto error;
2011 }
2012 2044
2013 retval = misc_register(&isiloader_device); 2045 retval = pci_register_driver(&isicom_driver);
2014 if (retval < 0) { 2046 if (retval < 0) {
2015 printk(KERN_ERR "ISICOM: Unable to register firmware loader driver.\n"); 2047 printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
2016 return retval; 2048 goto errtty;
2017 } 2049 }
2018 2050
2019 if (!isicom_init()) { 2051 retval = misc_register(&isiloader_device);
2020 if (misc_deregister(&isiloader_device)) 2052 if (retval < 0)
2021 printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n"); 2053 goto errpci;
2022 return -EIO;
2023 }
2024 2054
2025 init_timer(&tx); 2055 init_timer(&tx);
2026 tx.expires = jiffies + 1; 2056 tx.expires = jiffies + 1;
@@ -2030,6 +2060,12 @@ static int __devinit isicom_setup(void)
2030 add_timer(&tx); 2060 add_timer(&tx);
2031 2061
2032 return 0; 2062 return 0;
2063errpci:
2064 pci_unregister_driver(&isicom_driver);
2065errtty:
2066 isicom_unregister_tty_driver();
2067error:
2068 return retval;
2033} 2069}
2034 2070
2035static void __exit isicom_exit(void) 2071static void __exit isicom_exit(void)
@@ -2041,13 +2077,8 @@ static void __exit isicom_exit(void)
2041 while (re_schedule != 2 && index++ < 100) 2077 while (re_schedule != 2 && index++ < 100)
2042 msleep(10); 2078 msleep(10);
2043 2079
2044 unregister_isr(); 2080 pci_unregister_driver(&isicom_driver);
2045 isicom_unregister_tty_driver(); 2081 isicom_unregister_tty_driver();
2046 unregister_ioregion();
2047 if (tmp_buf)
2048 free_page((unsigned long)tmp_buf);
2049 if (misc_deregister(&isiloader_device))
2050 printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
2051} 2082}
2052 2083
2053module_init(isicom_setup); 2084module_init(isicom_setup);