diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 169 |
1 files changed, 110 insertions, 59 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4f3f8c9ec262..58c0e6387cf7 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/seq_file.h> | ||
39 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
40 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
@@ -970,6 +971,33 @@ out_kfree: | |||
970 | } | 971 | } |
971 | EXPORT_SYMBOL(ipmi_create_user); | 972 | EXPORT_SYMBOL(ipmi_create_user); |
972 | 973 | ||
974 | int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data) | ||
975 | { | ||
976 | int rv = 0; | ||
977 | ipmi_smi_t intf; | ||
978 | struct ipmi_smi_handlers *handlers; | ||
979 | |||
980 | mutex_lock(&ipmi_interfaces_mutex); | ||
981 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { | ||
982 | if (intf->intf_num == if_num) | ||
983 | goto found; | ||
984 | } | ||
985 | /* Not found, return an error */ | ||
986 | rv = -EINVAL; | ||
987 | mutex_unlock(&ipmi_interfaces_mutex); | ||
988 | return rv; | ||
989 | |||
990 | found: | ||
991 | handlers = intf->handlers; | ||
992 | rv = -ENOSYS; | ||
993 | if (handlers->get_smi_info) | ||
994 | rv = handlers->get_smi_info(intf->send_info, data); | ||
995 | mutex_unlock(&ipmi_interfaces_mutex); | ||
996 | |||
997 | return rv; | ||
998 | } | ||
999 | EXPORT_SYMBOL(ipmi_get_smi_info); | ||
1000 | |||
973 | static void free_user(struct kref *ref) | 1001 | static void free_user(struct kref *ref) |
974 | { | 1002 | { |
975 | ipmi_user_t user = container_of(ref, struct ipmi_user, refcount); | 1003 | ipmi_user_t user = container_of(ref, struct ipmi_user, refcount); |
@@ -1869,102 +1897,128 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1869 | EXPORT_SYMBOL(ipmi_request_supply_msgs); | 1897 | EXPORT_SYMBOL(ipmi_request_supply_msgs); |
1870 | 1898 | ||
1871 | #ifdef CONFIG_PROC_FS | 1899 | #ifdef CONFIG_PROC_FS |
1872 | static int ipmb_file_read_proc(char *page, char **start, off_t off, | 1900 | static int smi_ipmb_proc_show(struct seq_file *m, void *v) |
1873 | int count, int *eof, void *data) | ||
1874 | { | 1901 | { |
1875 | char *out = (char *) page; | 1902 | ipmi_smi_t intf = m->private; |
1876 | ipmi_smi_t intf = data; | ||
1877 | int i; | 1903 | int i; |
1878 | int rv = 0; | ||
1879 | 1904 | ||
1880 | for (i = 0; i < IPMI_MAX_CHANNELS; i++) | 1905 | seq_printf(m, "%x", intf->channels[0].address); |
1881 | rv += sprintf(out+rv, "%x ", intf->channels[i].address); | 1906 | for (i = 1; i < IPMI_MAX_CHANNELS; i++) |
1882 | out[rv-1] = '\n'; /* Replace the final space with a newline */ | 1907 | seq_printf(m, " %x", intf->channels[i].address); |
1883 | out[rv] = '\0'; | 1908 | return seq_putc(m, '\n'); |
1884 | rv++; | 1909 | } |
1885 | return rv; | 1910 | |
1911 | static int smi_ipmb_proc_open(struct inode *inode, struct file *file) | ||
1912 | { | ||
1913 | return single_open(file, smi_ipmb_proc_show, PDE(inode)->data); | ||
1886 | } | 1914 | } |
1887 | 1915 | ||
1888 | static int version_file_read_proc(char *page, char **start, off_t off, | 1916 | static const struct file_operations smi_ipmb_proc_ops = { |
1889 | int count, int *eof, void *data) | 1917 | .open = smi_ipmb_proc_open, |
1918 | .read = seq_read, | ||
1919 | .llseek = seq_lseek, | ||
1920 | .release = single_release, | ||
1921 | }; | ||
1922 | |||
1923 | static int smi_version_proc_show(struct seq_file *m, void *v) | ||
1890 | { | 1924 | { |
1891 | char *out = (char *) page; | 1925 | ipmi_smi_t intf = m->private; |
1892 | ipmi_smi_t intf = data; | ||
1893 | 1926 | ||
1894 | return sprintf(out, "%u.%u\n", | 1927 | return seq_printf(m, "%u.%u\n", |
1895 | ipmi_version_major(&intf->bmc->id), | 1928 | ipmi_version_major(&intf->bmc->id), |
1896 | ipmi_version_minor(&intf->bmc->id)); | 1929 | ipmi_version_minor(&intf->bmc->id)); |
1897 | } | 1930 | } |
1898 | 1931 | ||
1899 | static int stat_file_read_proc(char *page, char **start, off_t off, | 1932 | static int smi_version_proc_open(struct inode *inode, struct file *file) |
1900 | int count, int *eof, void *data) | ||
1901 | { | 1933 | { |
1902 | char *out = (char *) page; | 1934 | return single_open(file, smi_version_proc_show, PDE(inode)->data); |
1903 | ipmi_smi_t intf = data; | 1935 | } |
1904 | 1936 | ||
1905 | out += sprintf(out, "sent_invalid_commands: %u\n", | 1937 | static const struct file_operations smi_version_proc_ops = { |
1938 | .open = smi_version_proc_open, | ||
1939 | .read = seq_read, | ||
1940 | .llseek = seq_lseek, | ||
1941 | .release = single_release, | ||
1942 | }; | ||
1943 | |||
1944 | static int smi_stats_proc_show(struct seq_file *m, void *v) | ||
1945 | { | ||
1946 | ipmi_smi_t intf = m->private; | ||
1947 | |||
1948 | seq_printf(m, "sent_invalid_commands: %u\n", | ||
1906 | ipmi_get_stat(intf, sent_invalid_commands)); | 1949 | ipmi_get_stat(intf, sent_invalid_commands)); |
1907 | out += sprintf(out, "sent_local_commands: %u\n", | 1950 | seq_printf(m, "sent_local_commands: %u\n", |
1908 | ipmi_get_stat(intf, sent_local_commands)); | 1951 | ipmi_get_stat(intf, sent_local_commands)); |
1909 | out += sprintf(out, "handled_local_responses: %u\n", | 1952 | seq_printf(m, "handled_local_responses: %u\n", |
1910 | ipmi_get_stat(intf, handled_local_responses)); | 1953 | ipmi_get_stat(intf, handled_local_responses)); |
1911 | out += sprintf(out, "unhandled_local_responses: %u\n", | 1954 | seq_printf(m, "unhandled_local_responses: %u\n", |
1912 | ipmi_get_stat(intf, unhandled_local_responses)); | 1955 | ipmi_get_stat(intf, unhandled_local_responses)); |
1913 | out += sprintf(out, "sent_ipmb_commands: %u\n", | 1956 | seq_printf(m, "sent_ipmb_commands: %u\n", |
1914 | ipmi_get_stat(intf, sent_ipmb_commands)); | 1957 | ipmi_get_stat(intf, sent_ipmb_commands)); |
1915 | out += sprintf(out, "sent_ipmb_command_errs: %u\n", | 1958 | seq_printf(m, "sent_ipmb_command_errs: %u\n", |
1916 | ipmi_get_stat(intf, sent_ipmb_command_errs)); | 1959 | ipmi_get_stat(intf, sent_ipmb_command_errs)); |
1917 | out += sprintf(out, "retransmitted_ipmb_commands: %u\n", | 1960 | seq_printf(m, "retransmitted_ipmb_commands: %u\n", |
1918 | ipmi_get_stat(intf, retransmitted_ipmb_commands)); | 1961 | ipmi_get_stat(intf, retransmitted_ipmb_commands)); |
1919 | out += sprintf(out, "timed_out_ipmb_commands: %u\n", | 1962 | seq_printf(m, "timed_out_ipmb_commands: %u\n", |
1920 | ipmi_get_stat(intf, timed_out_ipmb_commands)); | 1963 | ipmi_get_stat(intf, timed_out_ipmb_commands)); |
1921 | out += sprintf(out, "timed_out_ipmb_broadcasts: %u\n", | 1964 | seq_printf(m, "timed_out_ipmb_broadcasts: %u\n", |
1922 | ipmi_get_stat(intf, timed_out_ipmb_broadcasts)); | 1965 | ipmi_get_stat(intf, timed_out_ipmb_broadcasts)); |
1923 | out += sprintf(out, "sent_ipmb_responses: %u\n", | 1966 | seq_printf(m, "sent_ipmb_responses: %u\n", |
1924 | ipmi_get_stat(intf, sent_ipmb_responses)); | 1967 | ipmi_get_stat(intf, sent_ipmb_responses)); |
1925 | out += sprintf(out, "handled_ipmb_responses: %u\n", | 1968 | seq_printf(m, "handled_ipmb_responses: %u\n", |
1926 | ipmi_get_stat(intf, handled_ipmb_responses)); | 1969 | ipmi_get_stat(intf, handled_ipmb_responses)); |
1927 | out += sprintf(out, "invalid_ipmb_responses: %u\n", | 1970 | seq_printf(m, "invalid_ipmb_responses: %u\n", |
1928 | ipmi_get_stat(intf, invalid_ipmb_responses)); | 1971 | ipmi_get_stat(intf, invalid_ipmb_responses)); |
1929 | out += sprintf(out, "unhandled_ipmb_responses: %u\n", | 1972 | seq_printf(m, "unhandled_ipmb_responses: %u\n", |
1930 | ipmi_get_stat(intf, unhandled_ipmb_responses)); | 1973 | ipmi_get_stat(intf, unhandled_ipmb_responses)); |
1931 | out += sprintf(out, "sent_lan_commands: %u\n", | 1974 | seq_printf(m, "sent_lan_commands: %u\n", |
1932 | ipmi_get_stat(intf, sent_lan_commands)); | 1975 | ipmi_get_stat(intf, sent_lan_commands)); |
1933 | out += sprintf(out, "sent_lan_command_errs: %u\n", | 1976 | seq_printf(m, "sent_lan_command_errs: %u\n", |
1934 | ipmi_get_stat(intf, sent_lan_command_errs)); | 1977 | ipmi_get_stat(intf, sent_lan_command_errs)); |
1935 | out += sprintf(out, "retransmitted_lan_commands: %u\n", | 1978 | seq_printf(m, "retransmitted_lan_commands: %u\n", |
1936 | ipmi_get_stat(intf, retransmitted_lan_commands)); | 1979 | ipmi_get_stat(intf, retransmitted_lan_commands)); |
1937 | out += sprintf(out, "timed_out_lan_commands: %u\n", | 1980 | seq_printf(m, "timed_out_lan_commands: %u\n", |
1938 | ipmi_get_stat(intf, timed_out_lan_commands)); | 1981 | ipmi_get_stat(intf, timed_out_lan_commands)); |
1939 | out += sprintf(out, "sent_lan_responses: %u\n", | 1982 | seq_printf(m, "sent_lan_responses: %u\n", |
1940 | ipmi_get_stat(intf, sent_lan_responses)); | 1983 | ipmi_get_stat(intf, sent_lan_responses)); |
1941 | out += sprintf(out, "handled_lan_responses: %u\n", | 1984 | seq_printf(m, "handled_lan_responses: %u\n", |
1942 | ipmi_get_stat(intf, handled_lan_responses)); | 1985 | ipmi_get_stat(intf, handled_lan_responses)); |
1943 | out += sprintf(out, "invalid_lan_responses: %u\n", | 1986 | seq_printf(m, "invalid_lan_responses: %u\n", |
1944 | ipmi_get_stat(intf, invalid_lan_responses)); | 1987 | ipmi_get_stat(intf, invalid_lan_responses)); |
1945 | out += sprintf(out, "unhandled_lan_responses: %u\n", | 1988 | seq_printf(m, "unhandled_lan_responses: %u\n", |
1946 | ipmi_get_stat(intf, unhandled_lan_responses)); | 1989 | ipmi_get_stat(intf, unhandled_lan_responses)); |
1947 | out += sprintf(out, "handled_commands: %u\n", | 1990 | seq_printf(m, "handled_commands: %u\n", |
1948 | ipmi_get_stat(intf, handled_commands)); | 1991 | ipmi_get_stat(intf, handled_commands)); |
1949 | out += sprintf(out, "invalid_commands: %u\n", | 1992 | seq_printf(m, "invalid_commands: %u\n", |
1950 | ipmi_get_stat(intf, invalid_commands)); | 1993 | ipmi_get_stat(intf, invalid_commands)); |
1951 | out += sprintf(out, "unhandled_commands: %u\n", | 1994 | seq_printf(m, "unhandled_commands: %u\n", |
1952 | ipmi_get_stat(intf, unhandled_commands)); | 1995 | ipmi_get_stat(intf, unhandled_commands)); |
1953 | out += sprintf(out, "invalid_events: %u\n", | 1996 | seq_printf(m, "invalid_events: %u\n", |
1954 | ipmi_get_stat(intf, invalid_events)); | 1997 | ipmi_get_stat(intf, invalid_events)); |
1955 | out += sprintf(out, "events: %u\n", | 1998 | seq_printf(m, "events: %u\n", |
1956 | ipmi_get_stat(intf, events)); | 1999 | ipmi_get_stat(intf, events)); |
1957 | out += sprintf(out, "failed rexmit LAN msgs: %u\n", | 2000 | seq_printf(m, "failed rexmit LAN msgs: %u\n", |
1958 | ipmi_get_stat(intf, dropped_rexmit_lan_commands)); | 2001 | ipmi_get_stat(intf, dropped_rexmit_lan_commands)); |
1959 | out += sprintf(out, "failed rexmit IPMB msgs: %u\n", | 2002 | seq_printf(m, "failed rexmit IPMB msgs: %u\n", |
1960 | ipmi_get_stat(intf, dropped_rexmit_ipmb_commands)); | 2003 | ipmi_get_stat(intf, dropped_rexmit_ipmb_commands)); |
2004 | return 0; | ||
2005 | } | ||
1961 | 2006 | ||
1962 | return (out - ((char *) page)); | 2007 | static int smi_stats_proc_open(struct inode *inode, struct file *file) |
2008 | { | ||
2009 | return single_open(file, smi_stats_proc_show, PDE(inode)->data); | ||
1963 | } | 2010 | } |
2011 | |||
2012 | static const struct file_operations smi_stats_proc_ops = { | ||
2013 | .open = smi_stats_proc_open, | ||
2014 | .read = seq_read, | ||
2015 | .llseek = seq_lseek, | ||
2016 | .release = single_release, | ||
2017 | }; | ||
1964 | #endif /* CONFIG_PROC_FS */ | 2018 | #endif /* CONFIG_PROC_FS */ |
1965 | 2019 | ||
1966 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | 2020 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, |
1967 | read_proc_t *read_proc, | 2021 | const struct file_operations *proc_ops, |
1968 | void *data) | 2022 | void *data) |
1969 | { | 2023 | { |
1970 | int rv = 0; | 2024 | int rv = 0; |
@@ -1983,15 +2037,12 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | |||
1983 | } | 2037 | } |
1984 | strcpy(entry->name, name); | 2038 | strcpy(entry->name, name); |
1985 | 2039 | ||
1986 | file = create_proc_entry(name, 0, smi->proc_dir); | 2040 | file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data); |
1987 | if (!file) { | 2041 | if (!file) { |
1988 | kfree(entry->name); | 2042 | kfree(entry->name); |
1989 | kfree(entry); | 2043 | kfree(entry); |
1990 | rv = -ENOMEM; | 2044 | rv = -ENOMEM; |
1991 | } else { | 2045 | } else { |
1992 | file->data = data; | ||
1993 | file->read_proc = read_proc; | ||
1994 | |||
1995 | mutex_lock(&smi->proc_entry_lock); | 2046 | mutex_lock(&smi->proc_entry_lock); |
1996 | /* Stick it on the list. */ | 2047 | /* Stick it on the list. */ |
1997 | entry->next = smi->proc_entries; | 2048 | entry->next = smi->proc_entries; |
@@ -2016,17 +2067,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num) | |||
2016 | 2067 | ||
2017 | if (rv == 0) | 2068 | if (rv == 0) |
2018 | rv = ipmi_smi_add_proc_entry(smi, "stats", | 2069 | rv = ipmi_smi_add_proc_entry(smi, "stats", |
2019 | stat_file_read_proc, | 2070 | &smi_stats_proc_ops, |
2020 | smi); | 2071 | smi); |
2021 | 2072 | ||
2022 | if (rv == 0) | 2073 | if (rv == 0) |
2023 | rv = ipmi_smi_add_proc_entry(smi, "ipmb", | 2074 | rv = ipmi_smi_add_proc_entry(smi, "ipmb", |
2024 | ipmb_file_read_proc, | 2075 | &smi_ipmb_proc_ops, |
2025 | smi); | 2076 | smi); |
2026 | 2077 | ||
2027 | if (rv == 0) | 2078 | if (rv == 0) |
2028 | rv = ipmi_smi_add_proc_entry(smi, "version", | 2079 | rv = ipmi_smi_add_proc_entry(smi, "version", |
2029 | version_file_read_proc, | 2080 | &smi_version_proc_ops, |
2030 | smi); | 2081 | smi); |
2031 | #endif /* CONFIG_PROC_FS */ | 2082 | #endif /* CONFIG_PROC_FS */ |
2032 | 2083 | ||
@@ -4442,13 +4493,13 @@ static int ipmi_init_msghandler(void) | |||
4442 | return 0; | 4493 | return 0; |
4443 | } | 4494 | } |
4444 | 4495 | ||
4445 | static __init int ipmi_init_msghandler_mod(void) | 4496 | static int __init ipmi_init_msghandler_mod(void) |
4446 | { | 4497 | { |
4447 | ipmi_init_msghandler(); | 4498 | ipmi_init_msghandler(); |
4448 | return 0; | 4499 | return 0; |
4449 | } | 4500 | } |
4450 | 4501 | ||
4451 | static __exit void cleanup_ipmi(void) | 4502 | static void __exit cleanup_ipmi(void) |
4452 | { | 4503 | { |
4453 | int count; | 4504 | int count; |
4454 | 4505 | ||