diff options
Diffstat (limited to 'arch/ia64/kernel/palinfo.c')
| -rw-r--r-- | arch/ia64/kernel/palinfo.c | 77 |
1 files changed, 13 insertions, 64 deletions
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 77597e5ea60a..79521d5499f9 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
| @@ -849,17 +849,6 @@ static palinfo_entry_t palinfo_entries[]={ | |||
| 849 | 849 | ||
| 850 | #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) | 850 | #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) |
| 851 | 851 | ||
| 852 | /* | ||
| 853 | * this array is used to keep track of the proc entries we create. This is | ||
| 854 | * required in the module mode when we need to remove all entries. The procfs code | ||
| 855 | * does not do recursion of deletion | ||
| 856 | * | ||
| 857 | * Notes: | ||
| 858 | * - +1 accounts for the cpuN directory entry in /proc/pal | ||
| 859 | */ | ||
| 860 | #define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1)) | ||
| 861 | |||
| 862 | static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES]; | ||
| 863 | static struct proc_dir_entry *palinfo_dir; | 852 | static struct proc_dir_entry *palinfo_dir; |
| 864 | 853 | ||
| 865 | /* | 854 | /* |
| @@ -971,60 +960,32 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi | |||
| 971 | static void __cpuinit | 960 | static void __cpuinit |
| 972 | create_palinfo_proc_entries(unsigned int cpu) | 961 | create_palinfo_proc_entries(unsigned int cpu) |
| 973 | { | 962 | { |
| 974 | # define CPUSTR "cpu%d" | ||
| 975 | |||
| 976 | pal_func_cpu_u_t f; | 963 | pal_func_cpu_u_t f; |
| 977 | struct proc_dir_entry **pdir; | ||
| 978 | struct proc_dir_entry *cpu_dir; | 964 | struct proc_dir_entry *cpu_dir; |
| 979 | int j; | 965 | int j; |
| 980 | char cpustr[sizeof(CPUSTR)]; | 966 | char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ |
| 981 | 967 | sprintf(cpustr, "cpu%d", cpu); | |
| 982 | |||
| 983 | /* | ||
| 984 | * we keep track of created entries in a depth-first order for | ||
| 985 | * cleanup purposes. Each entry is stored into palinfo_proc_entries | ||
| 986 | */ | ||
| 987 | sprintf(cpustr,CPUSTR, cpu); | ||
| 988 | 968 | ||
| 989 | cpu_dir = proc_mkdir(cpustr, palinfo_dir); | 969 | cpu_dir = proc_mkdir(cpustr, palinfo_dir); |
| 970 | if (!cpu_dir) | ||
| 971 | return; | ||
| 990 | 972 | ||
| 991 | f.req_cpu = cpu; | 973 | f.req_cpu = cpu; |
| 992 | 974 | ||
| 993 | /* | ||
| 994 | * Compute the location to store per cpu entries | ||
| 995 | * We dont store the top level entry in this list, but | ||
| 996 | * remove it finally after removing all cpu entries. | ||
| 997 | */ | ||
| 998 | pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)]; | ||
| 999 | *pdir++ = cpu_dir; | ||
| 1000 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { | 975 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { |
| 1001 | f.func_id = j; | 976 | f.func_id = j; |
| 1002 | *pdir = create_proc_read_entry( | 977 | create_proc_read_entry( |
| 1003 | palinfo_entries[j].name, 0, cpu_dir, | 978 | palinfo_entries[j].name, 0, cpu_dir, |
| 1004 | palinfo_read_entry, (void *)f.value); | 979 | palinfo_read_entry, (void *)f.value); |
| 1005 | pdir++; | ||
| 1006 | } | 980 | } |
| 1007 | } | 981 | } |
| 1008 | 982 | ||
| 1009 | static void | 983 | static void |
| 1010 | remove_palinfo_proc_entries(unsigned int hcpu) | 984 | remove_palinfo_proc_entries(unsigned int hcpu) |
| 1011 | { | 985 | { |
| 1012 | int j; | 986 | char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ |
| 1013 | struct proc_dir_entry *cpu_dir, **pdir; | 987 | sprintf(cpustr, "cpu%d", hcpu); |
| 1014 | 988 | remove_proc_subtree(cpustr, palinfo_dir); | |
| 1015 | pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)]; | ||
| 1016 | cpu_dir = *pdir; | ||
| 1017 | *pdir++=NULL; | ||
| 1018 | for (j=0; j < (NR_PALINFO_ENTRIES); j++) { | ||
| 1019 | if ((*pdir)) { | ||
| 1020 | remove_proc_entry ((*pdir)->name, cpu_dir); | ||
| 1021 | *pdir ++= NULL; | ||
| 1022 | } | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | if (cpu_dir) { | ||
| 1026 | remove_proc_entry(cpu_dir->name, palinfo_dir); | ||
| 1027 | } | ||
| 1028 | } | 989 | } |
| 1029 | 990 | ||
| 1030 | static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, | 991 | static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, |
| @@ -1058,6 +1019,8 @@ palinfo_init(void) | |||
| 1058 | 1019 | ||
| 1059 | printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); | 1020 | printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); |
| 1060 | palinfo_dir = proc_mkdir("pal", NULL); | 1021 | palinfo_dir = proc_mkdir("pal", NULL); |
| 1022 | if (!palinfo_dir) | ||
| 1023 | return -ENOMEM; | ||
| 1061 | 1024 | ||
| 1062 | /* Create palinfo dirs in /proc for all online cpus */ | 1025 | /* Create palinfo dirs in /proc for all online cpus */ |
| 1063 | for_each_online_cpu(i) { | 1026 | for_each_online_cpu(i) { |
| @@ -1073,22 +1036,8 @@ palinfo_init(void) | |||
| 1073 | static void __exit | 1036 | static void __exit |
| 1074 | palinfo_exit(void) | 1037 | palinfo_exit(void) |
| 1075 | { | 1038 | { |
| 1076 | int i = 0; | ||
| 1077 | |||
| 1078 | /* remove all nodes: depth first pass. Could optimize this */ | ||
| 1079 | for_each_online_cpu(i) { | ||
| 1080 | remove_palinfo_proc_entries(i); | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | /* | ||
| 1084 | * Remove the top level entry finally | ||
| 1085 | */ | ||
| 1086 | remove_proc_entry(palinfo_dir->name, NULL); | ||
| 1087 | |||
| 1088 | /* | ||
| 1089 | * Unregister from cpu notifier callbacks | ||
| 1090 | */ | ||
| 1091 | unregister_hotcpu_notifier(&palinfo_cpu_notifier); | 1039 | unregister_hotcpu_notifier(&palinfo_cpu_notifier); |
| 1040 | remove_proc_subtree("pal", NULL); | ||
| 1092 | } | 1041 | } |
| 1093 | 1042 | ||
| 1094 | module_init(palinfo_init); | 1043 | module_init(palinfo_init); |
