31
31
int nvdimm_major ;
32
32
static int nvdimm_bus_major ;
33
33
static struct class * nd_class ;
34
+ static DEFINE_IDA (nd_ida );
34
35
35
36
static int to_nd_device_type (struct device * dev )
36
37
{
@@ -60,13 +61,6 @@ static int nvdimm_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
60
61
to_nd_device_type (dev ));
61
62
}
62
63
63
- static int nvdimm_bus_match (struct device * dev , struct device_driver * drv )
64
- {
65
- struct nd_device_driver * nd_drv = to_nd_device_driver (drv );
66
-
67
- return !!test_bit (to_nd_device_type (dev ), & nd_drv -> type );
68
- }
69
-
70
64
static struct module * to_bus_provider (struct device * dev )
71
65
{
72
66
/* pin bus providers while regions are enabled */
@@ -223,6 +217,8 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
223
217
}
224
218
EXPORT_SYMBOL_GPL (nvdimm_clear_poison );
225
219
220
+ static int nvdimm_bus_match (struct device * dev , struct device_driver * drv );
221
+
226
222
static struct bus_type nvdimm_bus_type = {
227
223
.name = "nd" ,
228
224
.uevent = nvdimm_bus_uevent ,
@@ -232,6 +228,176 @@ static struct bus_type nvdimm_bus_type = {
232
228
.shutdown = nvdimm_bus_shutdown ,
233
229
};
234
230
231
+ static void nvdimm_bus_release (struct device * dev )
232
+ {
233
+ struct nvdimm_bus * nvdimm_bus ;
234
+
235
+ nvdimm_bus = container_of (dev , struct nvdimm_bus , dev );
236
+ ida_simple_remove (& nd_ida , nvdimm_bus -> id );
237
+ kfree (nvdimm_bus );
238
+ }
239
+
240
+ static bool is_nvdimm_bus (struct device * dev )
241
+ {
242
+ return dev -> release == nvdimm_bus_release ;
243
+ }
244
+
245
+ struct nvdimm_bus * walk_to_nvdimm_bus (struct device * nd_dev )
246
+ {
247
+ struct device * dev ;
248
+
249
+ for (dev = nd_dev ; dev ; dev = dev -> parent )
250
+ if (is_nvdimm_bus (dev ))
251
+ break ;
252
+ dev_WARN_ONCE (nd_dev , !dev , "invalid dev, not on nd bus\n" );
253
+ if (dev )
254
+ return to_nvdimm_bus (dev );
255
+ return NULL ;
256
+ }
257
+
258
+ struct nvdimm_bus * to_nvdimm_bus (struct device * dev )
259
+ {
260
+ struct nvdimm_bus * nvdimm_bus ;
261
+
262
+ nvdimm_bus = container_of (dev , struct nvdimm_bus , dev );
263
+ WARN_ON (!is_nvdimm_bus (dev ));
264
+ return nvdimm_bus ;
265
+ }
266
+ EXPORT_SYMBOL_GPL (to_nvdimm_bus );
267
+
268
+ struct nvdimm_bus * nvdimm_bus_register (struct device * parent ,
269
+ struct nvdimm_bus_descriptor * nd_desc )
270
+ {
271
+ struct nvdimm_bus * nvdimm_bus ;
272
+ int rc ;
273
+
274
+ nvdimm_bus = kzalloc (sizeof (* nvdimm_bus ), GFP_KERNEL );
275
+ if (!nvdimm_bus )
276
+ return NULL ;
277
+ INIT_LIST_HEAD (& nvdimm_bus -> list );
278
+ INIT_LIST_HEAD (& nvdimm_bus -> mapping_list );
279
+ INIT_LIST_HEAD (& nvdimm_bus -> poison_list );
280
+ init_waitqueue_head (& nvdimm_bus -> probe_wait );
281
+ nvdimm_bus -> id = ida_simple_get (& nd_ida , 0 , 0 , GFP_KERNEL );
282
+ mutex_init (& nvdimm_bus -> reconfig_mutex );
283
+ if (nvdimm_bus -> id < 0 ) {
284
+ kfree (nvdimm_bus );
285
+ return NULL ;
286
+ }
287
+ nvdimm_bus -> nd_desc = nd_desc ;
288
+ nvdimm_bus -> dev .parent = parent ;
289
+ nvdimm_bus -> dev .release = nvdimm_bus_release ;
290
+ nvdimm_bus -> dev .groups = nd_desc -> attr_groups ;
291
+ nvdimm_bus -> dev .bus = & nvdimm_bus_type ;
292
+ dev_set_name (& nvdimm_bus -> dev , "ndbus%d" , nvdimm_bus -> id );
293
+ rc = device_register (& nvdimm_bus -> dev );
294
+ if (rc ) {
295
+ dev_dbg (& nvdimm_bus -> dev , "registration failed: %d\n" , rc );
296
+ goto err ;
297
+ }
298
+
299
+ return nvdimm_bus ;
300
+ err :
301
+ put_device (& nvdimm_bus -> dev );
302
+ return NULL ;
303
+ }
304
+ EXPORT_SYMBOL_GPL (nvdimm_bus_register );
305
+
306
+ void nvdimm_bus_unregister (struct nvdimm_bus * nvdimm_bus )
307
+ {
308
+ if (!nvdimm_bus )
309
+ return ;
310
+ device_unregister (& nvdimm_bus -> dev );
311
+ }
312
+ EXPORT_SYMBOL_GPL (nvdimm_bus_unregister );
313
+
314
+ static int child_unregister (struct device * dev , void * data )
315
+ {
316
+ /*
317
+ * the singular ndctl class device per bus needs to be
318
+ * "device_destroy"ed, so skip it here
319
+ *
320
+ * i.e. remove classless children
321
+ */
322
+ if (dev -> class )
323
+ /* pass */ ;
324
+ else
325
+ nd_device_unregister (dev , ND_SYNC );
326
+ return 0 ;
327
+ }
328
+
329
+ static void free_poison_list (struct list_head * poison_list )
330
+ {
331
+ struct nd_poison * pl , * next ;
332
+
333
+ list_for_each_entry_safe (pl , next , poison_list , list ) {
334
+ list_del (& pl -> list );
335
+ kfree (pl );
336
+ }
337
+ list_del_init (poison_list );
338
+ }
339
+
340
+ static int nd_bus_remove (struct device * dev )
341
+ {
342
+ struct nvdimm_bus * nvdimm_bus = to_nvdimm_bus (dev );
343
+
344
+ mutex_lock (& nvdimm_bus_list_mutex );
345
+ list_del_init (& nvdimm_bus -> list );
346
+ mutex_unlock (& nvdimm_bus_list_mutex );
347
+
348
+ nd_synchronize ();
349
+ device_for_each_child (& nvdimm_bus -> dev , NULL , child_unregister );
350
+
351
+ nvdimm_bus_lock (& nvdimm_bus -> dev );
352
+ free_poison_list (& nvdimm_bus -> poison_list );
353
+ nvdimm_bus_unlock (& nvdimm_bus -> dev );
354
+
355
+ nvdimm_bus_destroy_ndctl (nvdimm_bus );
356
+
357
+ return 0 ;
358
+ }
359
+
360
+ static int nd_bus_probe (struct device * dev )
361
+ {
362
+ struct nvdimm_bus * nvdimm_bus = to_nvdimm_bus (dev );
363
+ int rc ;
364
+
365
+ rc = nvdimm_bus_create_ndctl (nvdimm_bus );
366
+ if (rc )
367
+ return rc ;
368
+
369
+ mutex_lock (& nvdimm_bus_list_mutex );
370
+ list_add_tail (& nvdimm_bus -> list , & nvdimm_bus_list );
371
+ mutex_unlock (& nvdimm_bus_list_mutex );
372
+
373
+ /* enable bus provider attributes to look up their local context */
374
+ dev_set_drvdata (dev , nvdimm_bus -> nd_desc );
375
+
376
+ return 0 ;
377
+ }
378
+
379
+ static struct nd_device_driver nd_bus_driver = {
380
+ .probe = nd_bus_probe ,
381
+ .remove = nd_bus_remove ,
382
+ .drv = {
383
+ .name = "nd_bus" ,
384
+ .suppress_bind_attrs = true,
385
+ .bus = & nvdimm_bus_type ,
386
+ .owner = THIS_MODULE ,
387
+ .mod_name = KBUILD_MODNAME ,
388
+ },
389
+ };
390
+
391
+ static int nvdimm_bus_match (struct device * dev , struct device_driver * drv )
392
+ {
393
+ struct nd_device_driver * nd_drv = to_nd_device_driver (drv );
394
+
395
+ if (is_nvdimm_bus (dev ) && nd_drv == & nd_bus_driver )
396
+ return true;
397
+
398
+ return !!test_bit (to_nd_device_type (dev ), & nd_drv -> type );
399
+ }
400
+
235
401
static ASYNC_DOMAIN_EXCLUSIVE (nd_async_domain );
236
402
237
403
void nd_synchronize (void )
@@ -864,8 +1030,14 @@ int __init nvdimm_bus_init(void)
864
1030
goto err_class ;
865
1031
}
866
1032
1033
+ rc = driver_register (& nd_bus_driver .drv );
1034
+ if (rc )
1035
+ goto err_nd_bus ;
1036
+
867
1037
return 0 ;
868
1038
1039
+ err_nd_bus :
1040
+ class_destroy (nd_class );
869
1041
err_class :
870
1042
unregister_chrdev (nvdimm_major , "dimmctl" );
871
1043
err_dimm_chrdev :
@@ -878,8 +1050,10 @@ int __init nvdimm_bus_init(void)
878
1050
879
1051
void nvdimm_bus_exit (void )
880
1052
{
1053
+ driver_unregister (& nd_bus_driver .drv );
881
1054
class_destroy (nd_class );
882
1055
unregister_chrdev (nvdimm_bus_major , "ndctl" );
883
1056
unregister_chrdev (nvdimm_major , "dimmctl" );
884
1057
bus_unregister (& nvdimm_bus_type );
1058
+ ida_destroy (& nd_ida );
885
1059
}
0 commit comments