[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>
This commit is contained in:
Joachim Fenkes 2007-08-29 18:15:17 +02:00 коммит произвёл Paul Mackerras
Родитель d51dd3de87
Коммит d8612417b2
1 изменённых файлов: 9 добавлений и 21 удалений

Просмотреть файл

@ -188,33 +188,21 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
struct device_node *dn) struct device_node *dn)
{ {
struct ibmebus_dev *dev; struct ibmebus_dev *dev;
const char *loc_code; int i, len, bus_len;
int length;
loc_code = of_get_property(dn, "ibm,loc-code", NULL);
if (!loc_code) {
printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
__FUNCTION__, dn->name ? dn->name : "<unknown>");
return ERR_PTR(-EINVAL);
}
if (strlen(loc_code) == 0) {
printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n",
__FUNCTION__);
return ERR_PTR(-EINVAL);
}
dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
if (!dev) { if (!dev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
dev->ofdev.node = of_node_get(dn); dev->ofdev.node = of_node_get(dn);
length = strlen(loc_code); len = strlen(dn->full_name + 1);
memcpy(dev->ofdev.dev.bus_id, loc_code bus_len = min(len, BUS_ID_SIZE - 1);
+ (length - min(length, BUS_ID_SIZE - 1)), memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1
min(length, BUS_ID_SIZE - 1)); + (len - bus_len), bus_len);
for (i = 0; i < bus_len; i++)
if (dev->ofdev.dev.bus_id[i] == '/')
dev->ofdev.dev.bus_id[i] = '_';
/* Register with generic device framework. */ /* Register with generic device framework. */
if (ibmebus_register_device_common(dev, dn->name) != 0) { if (ibmebus_register_device_common(dev, dn->name) != 0) {