Modules may have drivers with the same name on different buses. This patch fixes this problem.
Unified · Split
| @@ -1148,10 +1148,10 @@ static int mod_sysfs_setup(struct module *mod, · 1147 unmodified lines | ||
| 1148 | 1148 | kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); |
| 1149 | 1149 | return 0; |
| 1150 | 1150 | |
| 1151 | −out_unreg_drivers: | |
| 1152 | − kobject_unregister(mod->drivers_dir); | |
| 1153 | 1151 | out_unreg_param: |
| 1154 | 1152 | module_param_sysfs_remove(mod); |
| 1153 | +out_unreg_drivers: | |
| 1154 | + kobject_unregister(mod->drivers_dir); | |
| 1155 | 1155 | out_unreg: |
| 1156 | 1156 | kobject_del(&mod->mkobj.kobj); |
| 1157 | 1157 | kobject_put(&mod->mkobj.kobj); |
| @@ -2327,8 +2327,22 @@ void print_modules(void) · 1169 unmodified lines | ||
| 2327 | 2327 | printk("\n"); |
| 2328 | 2328 | } |
| 2329 | 2329 | |
| 2330 | +static char *make_driver_name(struct device_driver *drv) | |
| 2331 | +{ | |
| 2332 | + char *driver_name; | |
| 2333 | + | |
| 2334 | + driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | |
| 2335 | + GFP_KERNEL); | |
| 2336 | + if (!driver_name) | |
| 2337 | + return NULL; | |
| 2338 | + | |
| 2339 | + sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | |
| 2340 | + return driver_name; | |
| 2341 | +} | |
| 2342 | + | |
| 2330 | 2343 | void module_add_driver(struct module *mod, struct device_driver *drv) |
| 2331 | 2344 | { |
| 2345 | + char *driver_name; | |
| 2332 | 2346 | int no_warn; |
| 2333 | 2347 | |
| 2334 | 2348 | if (!mod || !drv) |
| @@ -2336,17 +2350,31 @@ void module_add_driver(struct module *mod, struct device_driver *drv) · 1 unmodified line | ||
| 2336 | 2350 | |
| 2337 | 2351 | /* Don't check return codes; these calls are idempotent */ |
| 2338 | 2352 | no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); |
| 2339 | − no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, drv->name); | |
| 2353 | + driver_name = make_driver_name(drv); | |
| 2354 | + if (driver_name) { | |
| 2355 | + no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, | |
| 2356 | + driver_name); | |
| 2357 | + kfree(driver_name); | |
| 2358 | + } | |
| 2340 | 2359 | } |
| 2341 | 2360 | EXPORT_SYMBOL(module_add_driver); |
| 2342 | 2361 | |
| 2343 | 2362 | void module_remove_driver(struct device_driver *drv) |
| 2344 | 2363 | { |
| 2364 | + char *driver_name; | |
| 2365 | + | |
| 2345 | 2366 | if (!drv) |
| 2346 | 2367 | return; |
| 2368 | + | |
| 2347 | 2369 | sysfs_remove_link(&drv->kobj, "module"); |
| 2348 | − if (drv->owner && drv->owner->drivers_dir) | |
| 2349 | − sysfs_remove_link(drv->owner->drivers_dir, drv->name); | |
| 2370 | + if (drv->owner && drv->owner->drivers_dir) { | |
| 2371 | + driver_name = make_driver_name(drv); | |
| 2372 | + if (driver_name) { | |
| 2373 | + sysfs_remove_link(drv->owner->drivers_dir, | |
| 2374 | + driver_name); | |
| 2375 | + kfree(driver_name); | |
| 2376 | + } | |
| 2377 | + } | |
| 2350 | 2378 | } |
| 2351 | 2379 | EXPORT_SYMBOL(module_remove_driver); |
| 2352 | 2380 | |