@@ -1086,22 +1086,35 @@ static int mod_sysfs_setup(struct module *mod,
1086
1086
goto out ;
1087
1087
kobj_set_kset_s (& mod -> mkobj , module_subsys );
1088
1088
mod -> mkobj .mod = mod ;
1089
- err = kobject_register (& mod -> mkobj .kobj );
1089
+
1090
+ /* delay uevent until full sysfs population */
1091
+ kobject_init (& mod -> mkobj .kobj );
1092
+ err = kobject_add (& mod -> mkobj .kobj );
1090
1093
if (err )
1091
1094
goto out ;
1092
1095
1096
+ mod -> drivers_dir = kobject_add_dir (& mod -> mkobj .kobj , "drivers" );
1097
+ if (!mod -> drivers_dir )
1098
+ goto out_unreg ;
1099
+
1093
1100
err = module_param_sysfs_setup (mod , kparam , num_params );
1094
1101
if (err )
1095
- goto out_unreg ;
1102
+ goto out_unreg_drivers ;
1096
1103
1097
1104
err = module_add_modinfo_attrs (mod );
1098
1105
if (err )
1099
- goto out_unreg ;
1106
+ goto out_unreg_param ;
1100
1107
1108
+ kobject_uevent (& mod -> mkobj .kobj , KOBJ_ADD );
1101
1109
return 0 ;
1102
1110
1111
+ out_unreg_drivers :
1112
+ kobject_unregister (mod -> drivers_dir );
1113
+ out_unreg_param :
1114
+ module_param_sysfs_remove (mod );
1103
1115
out_unreg :
1104
- kobject_unregister (& mod -> mkobj .kobj );
1116
+ kobject_del (& mod -> mkobj .kobj );
1117
+ kobject_put (& mod -> mkobj .kobj );
1105
1118
out :
1106
1119
return err ;
1107
1120
}
@@ -1110,6 +1123,7 @@ static void mod_kobject_remove(struct module *mod)
1110
1123
{
1111
1124
module_remove_modinfo_attrs (mod );
1112
1125
module_param_sysfs_remove (mod );
1126
+ kobject_unregister (mod -> drivers_dir );
1113
1127
1114
1128
kobject_unregister (& mod -> mkobj .kobj );
1115
1129
}
@@ -2275,11 +2289,14 @@ void print_modules(void)
2275
2289
2276
2290
void module_add_driver (struct module * mod , struct device_driver * drv )
2277
2291
{
2292
+ int no_warn ;
2293
+
2278
2294
if (!mod || !drv )
2279
2295
return ;
2280
2296
2281
- /* Don't check return code; this call is idempotent */
2282
- sysfs_create_link (& drv -> kobj , & mod -> mkobj .kobj , "module" );
2297
+ /* Don't check return codes; these calls are idempotent */
2298
+ no_warn = sysfs_create_link (& drv -> kobj , & mod -> mkobj .kobj , "module" );
2299
+ no_warn = sysfs_create_link (mod -> drivers_dir , & drv -> kobj , drv -> name );
2283
2300
}
2284
2301
EXPORT_SYMBOL (module_add_driver );
2285
2302
@@ -2288,6 +2305,8 @@ void module_remove_driver(struct device_driver *drv)
2288
2305
if (!drv )
2289
2306
return ;
2290
2307
sysfs_remove_link (& drv -> kobj , "module" );
2308
+ if (drv -> owner && drv -> owner -> drivers_dir )
2309
+ sysfs_remove_link (drv -> owner -> drivers_dir , drv -> name );
2291
2310
}
2292
2311
EXPORT_SYMBOL (module_remove_driver );
2293
2312
0 commit comments