[PATCH] char/isicom: Pci probing added

Pci probing functions added, most of functions rewrited because of it (some
for loops were redundant). Used PCI_DEVICE macro. dev_* used for printing
wherever possible. Renamed some functions to have isicom_ in the name.

Signed-off-by: Jiri Slaby <xslaby@fi.muni.cz>
Signed-off-by: Laurent Riffard <laurent.riffard@free.fr>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Jiri Slaby and committed by
Linus Torvalds
9ac0948b aaa246ea

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