diff options
Diffstat (limited to 'drivers/parisc/sba_iommu.c')
-rw-r--r-- | drivers/parisc/sba_iommu.c | 128 |
1 files changed, 79 insertions, 49 deletions
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index c85653f315aa..5d47c5965c51 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ | 37 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ |
38 | 38 | ||
39 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
40 | #include <linux/seq_file.h> | ||
41 | |||
40 | #include <asm/runway.h> /* for proc_runway_root */ | 42 | #include <asm/runway.h> /* for proc_runway_root */ |
41 | #include <asm/pdc.h> /* for PDC_MODEL_* */ | 43 | #include <asm/pdc.h> /* for PDC_MODEL_* */ |
42 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ | 44 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ |
@@ -1892,46 +1894,43 @@ sba_common_init(struct sba_device *sba_dev) | |||
1892 | } | 1894 | } |
1893 | 1895 | ||
1894 | #ifdef CONFIG_PROC_FS | 1896 | #ifdef CONFIG_PROC_FS |
1895 | static int sba_proc_info(char *buf, char **start, off_t offset, int len) | 1897 | static int sba_proc_info(struct seq_file *m, void *p) |
1896 | { | 1898 | { |
1897 | struct sba_device *sba_dev = sba_list; | 1899 | struct sba_device *sba_dev = sba_list; |
1898 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ | 1900 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ |
1899 | int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ | 1901 | int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ |
1900 | unsigned long i; | ||
1901 | #ifdef SBA_COLLECT_STATS | 1902 | #ifdef SBA_COLLECT_STATS |
1902 | unsigned long avg = 0, min, max; | 1903 | unsigned long avg = 0, min, max; |
1903 | #endif | 1904 | #endif |
1905 | int i, len = 0; | ||
1904 | 1906 | ||
1905 | sprintf(buf, "%s rev %d.%d\n", | 1907 | len += seq_printf(m, "%s rev %d.%d\n", |
1906 | sba_dev->name, | 1908 | sba_dev->name, |
1907 | (sba_dev->hw_rev & 0x7) + 1, | 1909 | (sba_dev->hw_rev & 0x7) + 1, |
1908 | (sba_dev->hw_rev & 0x18) >> 3 | 1910 | (sba_dev->hw_rev & 0x18) >> 3 |
1909 | ); | 1911 | ); |
1910 | sprintf(buf, "%sIO PDIR size : %d bytes (%d entries)\n", | 1912 | len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", |
1911 | buf, | ||
1912 | (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ | 1913 | (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ |
1913 | total_pages); | 1914 | total_pages); |
1914 | 1915 | ||
1915 | sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", | 1916 | len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", |
1916 | buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ | 1917 | ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ |
1917 | 1918 | ||
1918 | sprintf(buf, "%sLMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", | 1919 | len += seq_printf(m, "LMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", |
1919 | buf, | ||
1920 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_BASE), | 1920 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_BASE), |
1921 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_MASK), | 1921 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_MASK), |
1922 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_ROUTE) | 1922 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_ROUTE) |
1923 | ); | 1923 | ); |
1924 | 1924 | ||
1925 | for (i=0; i<4; i++) | 1925 | for (i=0; i<4; i++) |
1926 | sprintf(buf, "%sDIR%ld_BASE/MASK/ROUTE %08x %08x %08x\n", | 1926 | len += seq_printf(m, "DIR%d_BASE/MASK/ROUTE %08x %08x %08x\n", i, |
1927 | buf, i, | ||
1928 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_BASE + i*0x18), | 1927 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_BASE + i*0x18), |
1929 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_MASK + i*0x18), | 1928 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_MASK + i*0x18), |
1930 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_ROUTE + i*0x18) | 1929 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_ROUTE + i*0x18) |
1931 | ); | 1930 | ); |
1932 | 1931 | ||
1933 | #ifdef SBA_COLLECT_STATS | 1932 | #ifdef SBA_COLLECT_STATS |
1934 | sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf, | 1933 | len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", |
1935 | total_pages - ioc->used_pages, ioc->used_pages, | 1934 | total_pages - ioc->used_pages, ioc->used_pages, |
1936 | (int) (ioc->used_pages * 100 / total_pages)); | 1935 | (int) (ioc->used_pages * 100 / total_pages)); |
1937 | 1936 | ||
@@ -1942,53 +1941,76 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len) | |||
1942 | if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; | 1941 | if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; |
1943 | } | 1942 | } |
1944 | avg /= SBA_SEARCH_SAMPLE; | 1943 | avg /= SBA_SEARCH_SAMPLE; |
1945 | sprintf(buf, "%s Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", | 1944 | len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", |
1946 | buf, min, avg, max); | 1945 | min, avg, max); |
1947 | 1946 | ||
1948 | sprintf(buf, "%spci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", | 1947 | len += seq_printf(m, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", |
1949 | buf, ioc->msingle_calls, ioc->msingle_pages, | 1948 | ioc->msingle_calls, ioc->msingle_pages, |
1950 | (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); | 1949 | (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); |
1951 | 1950 | ||
1952 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ | 1951 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ |
1953 | min = ioc->usingle_calls; | 1952 | min = ioc->usingle_calls; |
1954 | max = ioc->usingle_pages - ioc->usg_pages; | 1953 | max = ioc->usingle_pages - ioc->usg_pages; |
1955 | sprintf(buf, "%spci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", | 1954 | len += seq_printf(m, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", |
1956 | buf, min, max, | 1955 | min, max, (int) ((max * 1000)/min)); |
1957 | (int) ((max * 1000)/min)); | ||
1958 | 1956 | ||
1959 | sprintf(buf, "%spci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", | 1957 | len += seq_printf(m, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", |
1960 | buf, ioc->msg_calls, ioc->msg_pages, | 1958 | ioc->msg_calls, ioc->msg_pages, |
1961 | (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); | 1959 | (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); |
1962 | 1960 | ||
1963 | sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", | 1961 | len += seq_printf(m, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", |
1964 | buf, ioc->usg_calls, ioc->usg_pages, | 1962 | ioc->usg_calls, ioc->usg_pages, |
1965 | (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); | 1963 | (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); |
1966 | #endif | 1964 | #endif |
1967 | 1965 | ||
1968 | return strlen(buf); | 1966 | return 0; |
1969 | } | 1967 | } |
1970 | 1968 | ||
1971 | #if 0 | ||
1972 | /* XXX too much output - exceeds 4k limit and needs to be re-written */ | ||
1973 | static int | 1969 | static int |
1974 | sba_resource_map(char *buf, char **start, off_t offset, int len) | 1970 | sba_proc_open(struct inode *i, struct file *f) |
1971 | { | ||
1972 | return single_open(f, &sba_proc_info, NULL); | ||
1973 | } | ||
1974 | |||
1975 | static struct file_operations sba_proc_fops = { | ||
1976 | .owner = THIS_MODULE, | ||
1977 | .open = sba_proc_open, | ||
1978 | .read = seq_read, | ||
1979 | .llseek = seq_lseek, | ||
1980 | .release = single_release, | ||
1981 | }; | ||
1982 | |||
1983 | static int | ||
1984 | sba_proc_bitmap_info(struct seq_file *m, void *p) | ||
1975 | { | 1985 | { |
1976 | struct sba_device *sba_dev = sba_list; | 1986 | struct sba_device *sba_dev = sba_list; |
1977 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Mutli-IOC suppoer! */ | 1987 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ |
1978 | unsigned int *res_ptr = (unsigned int *)ioc->res_map; | 1988 | unsigned int *res_ptr = (unsigned int *)ioc->res_map; |
1979 | int i; | 1989 | int i, len = 0; |
1980 | 1990 | ||
1981 | buf[0] = '\0'; | 1991 | for (i = 0; i < (ioc->res_size/sizeof(unsigned int)); ++i, ++res_ptr) { |
1982 | for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) { | ||
1983 | if ((i & 7) == 0) | 1992 | if ((i & 7) == 0) |
1984 | strcat(buf,"\n "); | 1993 | len += seq_printf(m, "\n "); |
1985 | sprintf(buf, "%s %08x", buf, *res_ptr); | 1994 | len += seq_printf(m, " %08x", *res_ptr); |
1986 | } | 1995 | } |
1987 | strcat(buf, "\n"); | 1996 | len += seq_printf(m, "\n"); |
1988 | 1997 | ||
1989 | return strlen(buf); | 1998 | return 0; |
1990 | } | 1999 | } |
1991 | #endif /* 0 */ | 2000 | |
2001 | static int | ||
2002 | sba_proc_bitmap_open(struct inode *i, struct file *f) | ||
2003 | { | ||
2004 | return single_open(f, &sba_proc_bitmap_info, NULL); | ||
2005 | } | ||
2006 | |||
2007 | static struct file_operations sba_proc_bitmap_fops = { | ||
2008 | .owner = THIS_MODULE, | ||
2009 | .open = sba_proc_bitmap_open, | ||
2010 | .read = seq_read, | ||
2011 | .llseek = seq_lseek, | ||
2012 | .release = single_release, | ||
2013 | }; | ||
1992 | #endif /* CONFIG_PROC_FS */ | 2014 | #endif /* CONFIG_PROC_FS */ |
1993 | 2015 | ||
1994 | static struct parisc_device_id sba_tbl[] = { | 2016 | static struct parisc_device_id sba_tbl[] = { |
@@ -2021,6 +2043,7 @@ sba_driver_callback(struct parisc_device *dev) | |||
2021 | int i; | 2043 | int i; |
2022 | char *version; | 2044 | char *version; |
2023 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); | 2045 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); |
2046 | struct proc_dir_entry *info_entry, *bitmap_entry, *root; | ||
2024 | 2047 | ||
2025 | sba_dump_ranges(sba_addr); | 2048 | sba_dump_ranges(sba_addr); |
2026 | 2049 | ||
@@ -2064,14 +2087,13 @@ sba_driver_callback(struct parisc_device *dev) | |||
2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", | 2087 | printk(KERN_INFO "%s found %s at 0x%lx\n", |
2065 | MODULE_NAME, version, dev->hpa.start); | 2088 | MODULE_NAME, version, dev->hpa.start); |
2066 | 2089 | ||
2067 | sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); | 2090 | sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); |
2068 | if (!sba_dev) { | 2091 | if (!sba_dev) { |
2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); | 2092 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); |
2070 | return -ENOMEM; | 2093 | return -ENOMEM; |
2071 | } | 2094 | } |
2072 | 2095 | ||
2073 | parisc_set_drvdata(dev, sba_dev); | 2096 | parisc_set_drvdata(dev, sba_dev); |
2074 | memset(sba_dev, 0, sizeof(struct sba_device)); | ||
2075 | 2097 | ||
2076 | for(i=0; i<MAX_IOC; i++) | 2098 | for(i=0; i<MAX_IOC; i++) |
2077 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); | 2099 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); |
@@ -2089,19 +2111,27 @@ sba_driver_callback(struct parisc_device *dev) | |||
2089 | hppa_dma_ops = &sba_ops; | 2111 | hppa_dma_ops = &sba_ops; |
2090 | 2112 | ||
2091 | #ifdef CONFIG_PROC_FS | 2113 | #ifdef CONFIG_PROC_FS |
2092 | if (IS_ASTRO(&dev->id)) { | 2114 | switch (dev->id.hversion) { |
2093 | create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info); | 2115 | case PLUTO_MCKINLEY_PORT: |
2094 | } else if (IS_IKE(&dev->id)) { | 2116 | root = proc_mckinley_root; |
2095 | create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info); | 2117 | break; |
2096 | } else if (IS_PLUTO(&dev->id)) { | 2118 | case ASTRO_RUNWAY_PORT: |
2097 | create_proc_info_entry("Pluto", 0, proc_mckinley_root, sba_proc_info); | 2119 | case IKE_MERCED_PORT: |
2098 | } else { | 2120 | default: |
2099 | create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info); | 2121 | root = proc_runway_root; |
2122 | break; | ||
2100 | } | 2123 | } |
2101 | #if 0 | 2124 | |
2102 | create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map); | 2125 | info_entry = create_proc_entry("sba_iommu", 0, root); |
2103 | #endif | 2126 | bitmap_entry = create_proc_entry("sba_iommu-bitmap", 0, root); |
2127 | |||
2128 | if (info_entry) | ||
2129 | info_entry->proc_fops = &sba_proc_fops; | ||
2130 | |||
2131 | if (bitmap_entry) | ||
2132 | bitmap_entry->proc_fops = &sba_proc_bitmap_fops; | ||
2104 | #endif | 2133 | #endif |
2134 | |||
2105 | parisc_vmerge_boundary = IOVP_SIZE; | 2135 | parisc_vmerge_boundary = IOVP_SIZE; |
2106 | parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; | 2136 | parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; |
2107 | parisc_has_iommu(); | 2137 | parisc_has_iommu(); |