diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-29 14:28:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-29 14:28:30 -0500 |
commit | 76babde121d2ffef04ca692ce64ef9f8a9866086 (patch) | |
tree | 294923bbb4974258d86d223e35eee691abacdfb1 /fs | |
parent | e71ac6032edf77a1e4a81f3e3b260807e94b37a5 (diff) | |
parent | 15e812ad849e142e3dfc984d33c4d8042389f148 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (67 commits)
[PATCH] powerpc: Remove oprofile spinlock backtrace code
[PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus
[PATCH] powerpc: Add oprofile calltrace support
[PATCH] for_each_possible_cpu: ppc
[PATCH] for_each_possible_cpu: powerpc
[PATCH] lock PTE before updating it in 440/BookE page fault handler
[PATCH] powerpc: Kill _machine and hard-coded platform numbers
ppc: Fix compile error in arch/ppc/lib/strcase.c
[PATCH] git-powerpc: WARN was a dumb idea
[PATCH] powerpc: a couple of trivial compile warning fixes
powerpc: remove OCP references
powerpc: Make uImage default build output for MPC8540 ADS
powerpc: move math-emu over to arch/powerpc
powerpc: use memparse() for mem= command line parsing
ppc: fix strncasecmp prototype
[PATCH] powerpc: make ISA floppies work again
[PATCH] powerpc: Fix some initcall return values
[PATCH] powerpc: Workaround for pSeries RTAS bug
[PATCH] spufs: fix __init/__exit annotations
[PATCH] powerpc: add hvc backend for rtas
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/partitions/mac.c | 3 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 103 |
2 files changed, 82 insertions, 24 deletions
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index bb22cdd0cb14..813292f21210 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "mac.h" | 12 | #include "mac.h" |
13 | 13 | ||
14 | #ifdef CONFIG_PPC_PMAC | 14 | #ifdef CONFIG_PPC_PMAC |
15 | #include <asm/machdep.h> | ||
15 | extern void note_bootable_part(dev_t dev, int part, int goodness); | 16 | extern void note_bootable_part(dev_t dev, int part, int goodness); |
16 | #endif | 17 | #endif |
17 | 18 | ||
@@ -79,7 +80,7 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
79 | * If this is the first bootable partition, tell the | 80 | * If this is the first bootable partition, tell the |
80 | * setup code, in case it wants to make this the root. | 81 | * setup code, in case it wants to make this the root. |
81 | */ | 82 | */ |
82 | if (_machine == _MACH_Pmac) { | 83 | if (machine_is(powermac)) { |
83 | int goodness = 0; | 84 | int goodness = 0; |
84 | 85 | ||
85 | mac_fix_string(part->processor, 16); | 86 | mac_fix_string(part->processor, 16); |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 596b4b4f1cc8..abdf068bc27f 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -52,7 +52,8 @@ static int property_read_proc(char *page, char **start, off_t off, | |||
52 | * Add a property to a node | 52 | * Add a property to a node |
53 | */ | 53 | */ |
54 | static struct proc_dir_entry * | 54 | static struct proc_dir_entry * |
55 | __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp) | 55 | __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, |
56 | const char *name) | ||
56 | { | 57 | { |
57 | struct proc_dir_entry *ent; | 58 | struct proc_dir_entry *ent; |
58 | 59 | ||
@@ -60,14 +61,14 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp) | |||
60 | * Unfortunately proc_register puts each new entry | 61 | * Unfortunately proc_register puts each new entry |
61 | * at the beginning of the list. So we rearrange them. | 62 | * at the beginning of the list. So we rearrange them. |
62 | */ | 63 | */ |
63 | ent = create_proc_read_entry(pp->name, | 64 | ent = create_proc_read_entry(name, |
64 | strncmp(pp->name, "security-", 9) | 65 | strncmp(name, "security-", 9) |
65 | ? S_IRUGO : S_IRUSR, de, | 66 | ? S_IRUGO : S_IRUSR, de, |
66 | property_read_proc, pp); | 67 | property_read_proc, pp); |
67 | if (ent == NULL) | 68 | if (ent == NULL) |
68 | return NULL; | 69 | return NULL; |
69 | 70 | ||
70 | if (!strncmp(pp->name, "security-", 9)) | 71 | if (!strncmp(name, "security-", 9)) |
71 | ent->size = 0; /* don't leak number of password chars */ | 72 | ent->size = 0; /* don't leak number of password chars */ |
72 | else | 73 | else |
73 | ent->size = pp->length; | 74 | ent->size = pp->length; |
@@ -78,7 +79,7 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp) | |||
78 | 79 | ||
79 | void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) | 80 | void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) |
80 | { | 81 | { |
81 | __proc_device_tree_add_prop(pde, prop); | 82 | __proc_device_tree_add_prop(pde, prop, prop->name); |
82 | } | 83 | } |
83 | 84 | ||
84 | void proc_device_tree_remove_prop(struct proc_dir_entry *pde, | 85 | void proc_device_tree_remove_prop(struct proc_dir_entry *pde, |
@@ -106,6 +107,69 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde, | |||
106 | } | 107 | } |
107 | 108 | ||
108 | /* | 109 | /* |
110 | * Various dodgy firmware might give us nodes and/or properties with | ||
111 | * conflicting names. That's generally ok, except for exporting via /proc, | ||
112 | * so munge names here to ensure they're unique. | ||
113 | */ | ||
114 | |||
115 | static int duplicate_name(struct proc_dir_entry *de, const char *name) | ||
116 | { | ||
117 | struct proc_dir_entry *ent; | ||
118 | int found = 0; | ||
119 | |||
120 | spin_lock(&proc_subdir_lock); | ||
121 | |||
122 | for (ent = de->subdir; ent != NULL; ent = ent->next) { | ||
123 | if (strcmp(ent->name, name) == 0) { | ||
124 | found = 1; | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | spin_unlock(&proc_subdir_lock); | ||
130 | |||
131 | return found; | ||
132 | } | ||
133 | |||
134 | static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de, | ||
135 | const char *name) | ||
136 | { | ||
137 | char *fixed_name; | ||
138 | int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */ | ||
139 | int i = 1, size; | ||
140 | |||
141 | realloc: | ||
142 | fixed_name = kmalloc(fixup_len, GFP_KERNEL); | ||
143 | if (fixed_name == NULL) { | ||
144 | printk(KERN_ERR "device-tree: Out of memory trying to fixup " | ||
145 | "name \"%s\"\n", name); | ||
146 | return name; | ||
147 | } | ||
148 | |||
149 | retry: | ||
150 | size = snprintf(fixed_name, fixup_len, "%s#%d", name, i); | ||
151 | size++; /* account for NULL */ | ||
152 | |||
153 | if (size > fixup_len) { | ||
154 | /* We ran out of space, free and reallocate. */ | ||
155 | kfree(fixed_name); | ||
156 | fixup_len = size; | ||
157 | goto realloc; | ||
158 | } | ||
159 | |||
160 | if (duplicate_name(de, fixed_name)) { | ||
161 | /* Multiple duplicates. Retry with a different offset. */ | ||
162 | i++; | ||
163 | goto retry; | ||
164 | } | ||
165 | |||
166 | printk(KERN_WARNING "device-tree: Duplicate name in %s, " | ||
167 | "renamed to \"%s\"\n", np->full_name, fixed_name); | ||
168 | |||
169 | return fixed_name; | ||
170 | } | ||
171 | |||
172 | /* | ||
109 | * Process a node, adding entries for its children and its properties. | 173 | * Process a node, adding entries for its children and its properties. |
110 | */ | 174 | */ |
111 | void proc_device_tree_add_node(struct device_node *np, | 175 | void proc_device_tree_add_node(struct device_node *np, |
@@ -118,37 +182,30 @@ void proc_device_tree_add_node(struct device_node *np, | |||
118 | 182 | ||
119 | set_node_proc_entry(np, de); | 183 | set_node_proc_entry(np, de); |
120 | for (child = NULL; (child = of_get_next_child(np, child));) { | 184 | for (child = NULL; (child = of_get_next_child(np, child));) { |
185 | /* Use everything after the last slash, or the full name */ | ||
121 | p = strrchr(child->full_name, '/'); | 186 | p = strrchr(child->full_name, '/'); |
122 | if (!p) | 187 | if (!p) |
123 | p = child->full_name; | 188 | p = child->full_name; |
124 | else | 189 | else |
125 | ++p; | 190 | ++p; |
191 | |||
192 | if (duplicate_name(de, p)) | ||
193 | p = fixup_name(np, de, p); | ||
194 | |||
126 | ent = proc_mkdir(p, de); | 195 | ent = proc_mkdir(p, de); |
127 | if (ent == 0) | 196 | if (ent == 0) |
128 | break; | 197 | break; |
129 | proc_device_tree_add_node(child, ent); | 198 | proc_device_tree_add_node(child, ent); |
130 | } | 199 | } |
131 | of_node_put(child); | 200 | of_node_put(child); |
201 | |||
132 | for (pp = np->properties; pp != 0; pp = pp->next) { | 202 | for (pp = np->properties; pp != 0; pp = pp->next) { |
133 | /* | 203 | p = pp->name; |
134 | * Yet another Apple device-tree bogosity: on some machines, | 204 | |
135 | * they have properties & nodes with the same name. Those | 205 | if (duplicate_name(de, p)) |
136 | * properties are quite unimportant for us though, thus we | 206 | p = fixup_name(np, de, p); |
137 | * simply "skip" them here, but we do have to check. | ||
138 | */ | ||
139 | spin_lock(&proc_subdir_lock); | ||
140 | for (ent = de->subdir; ent != NULL; ent = ent->next) | ||
141 | if (!strcmp(ent->name, pp->name)) | ||
142 | break; | ||
143 | spin_unlock(&proc_subdir_lock); | ||
144 | if (ent != NULL) { | ||
145 | printk(KERN_WARNING "device-tree: property \"%s\" name" | ||
146 | " conflicts with node in %s\n", pp->name, | ||
147 | np->full_name); | ||
148 | continue; | ||
149 | } | ||
150 | 207 | ||
151 | ent = __proc_device_tree_add_prop(de, pp); | 208 | ent = __proc_device_tree_add_prop(de, pp, p); |
152 | if (ent == 0) | 209 | if (ent == 0) |
153 | break; | 210 | break; |
154 | } | 211 | } |