diff options
author | Joachim Fenkes <fenkes@de.ibm.com> | 2007-08-29 12:15:17 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-09-10 14:30:37 -0400 |
commit | d8612417b2f78767b96ca434b50d23e5cdfcde07 (patch) | |
tree | dc6231b7d51c350dfba09dc0d34251313ec286f7 /arch/powerpc | |
parent | d51dd3de87026cb0ea1ea5f873f08e930053bfc5 (diff) |
[POWERPC] ibmebus: Prevent bus_id collisions
Previously, ibmebus derived a device's bus_id from its location code.
The location code is not guaranteed to be unique, so we might get bus_id
collisions if two devices share the same location code. The OFDT
full_name, however, is unique, so we use that instead (truncating it
on the left if it is too long).
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/ibmebus.c | 30 |
1 files changed, 9 insertions, 21 deletions
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 9a8c9af43b22..d6a38cd5018e 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -188,33 +188,21 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( | |||
188 | struct device_node *dn) | 188 | struct device_node *dn) |
189 | { | 189 | { |
190 | struct ibmebus_dev *dev; | 190 | struct ibmebus_dev *dev; |
191 | const char *loc_code; | 191 | int i, len, bus_len; |
192 | int length; | ||
193 | |||
194 | loc_code = of_get_property(dn, "ibm,loc-code", NULL); | ||
195 | if (!loc_code) { | ||
196 | printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", | ||
197 | __FUNCTION__, dn->name ? dn->name : "<unknown>"); | ||
198 | return ERR_PTR(-EINVAL); | ||
199 | } | ||
200 | |||
201 | if (strlen(loc_code) == 0) { | ||
202 | printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n", | ||
203 | __FUNCTION__); | ||
204 | return ERR_PTR(-EINVAL); | ||
205 | } | ||
206 | 192 | ||
207 | dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); | 193 | dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); |
208 | if (!dev) { | 194 | if (!dev) |
209 | return ERR_PTR(-ENOMEM); | 195 | return ERR_PTR(-ENOMEM); |
210 | } | ||
211 | 196 | ||
212 | dev->ofdev.node = of_node_get(dn); | 197 | dev->ofdev.node = of_node_get(dn); |
213 | 198 | ||
214 | length = strlen(loc_code); | 199 | len = strlen(dn->full_name + 1); |
215 | memcpy(dev->ofdev.dev.bus_id, loc_code | 200 | bus_len = min(len, BUS_ID_SIZE - 1); |
216 | + (length - min(length, BUS_ID_SIZE - 1)), | 201 | memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1 |
217 | min(length, BUS_ID_SIZE - 1)); | 202 | + (len - bus_len), bus_len); |
203 | for (i = 0; i < bus_len; i++) | ||
204 | if (dev->ofdev.dev.bus_id[i] == '/') | ||
205 | dev->ofdev.dev.bus_id[i] = '_'; | ||
218 | 206 | ||
219 | /* Register with generic device framework. */ | 207 | /* Register with generic device framework. */ |
220 | if (ibmebus_register_device_common(dev, dn->name) != 0) { | 208 | if (ibmebus_register_device_common(dev, dn->name) != 0) { |