2
2
/* Copyright(c) 2017-2018 Intel Corporation. All rights reserved. */
3
3
#include <linux/memremap.h>
4
4
#include <linux/device.h>
5
+ #include <linux/mutex.h>
6
+ #include <linux/list.h>
5
7
#include <linux/slab.h>
6
8
#include <linux/dax.h>
7
9
#include "dax-private.h"
8
10
#include "bus.h"
9
11
12
+ static DEFINE_MUTEX (dax_bus_lock );
13
+
14
+ #define DAX_NAME_LEN 30
15
+ struct dax_id {
16
+ struct list_head list ;
17
+ char dev_name [DAX_NAME_LEN ];
18
+ };
19
+
10
20
static int dax_bus_uevent (struct device * dev , struct kobj_uevent_env * env )
11
21
{
12
22
/*
@@ -16,22 +26,115 @@ static int dax_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
16
26
return add_uevent_var (env , "MODALIAS=" DAX_DEVICE_MODALIAS_FMT , 0 );
17
27
}
18
28
29
+ static struct dax_device_driver * to_dax_drv (struct device_driver * drv )
30
+ {
31
+ return container_of (drv , struct dax_device_driver , drv );
32
+ }
33
+
34
+ static struct dax_id * __dax_match_id (struct dax_device_driver * dax_drv ,
35
+ const char * dev_name )
36
+ {
37
+ struct dax_id * dax_id ;
38
+
39
+ lockdep_assert_held (& dax_bus_lock );
40
+
41
+ list_for_each_entry (dax_id , & dax_drv -> ids , list )
42
+ if (sysfs_streq (dax_id -> dev_name , dev_name ))
43
+ return dax_id ;
44
+ return NULL ;
45
+ }
46
+
47
+ static int dax_match_id (struct dax_device_driver * dax_drv , struct device * dev )
48
+ {
49
+ int match ;
50
+
51
+ mutex_lock (& dax_bus_lock );
52
+ match = !!__dax_match_id (dax_drv , dev_name (dev ));
53
+ mutex_unlock (& dax_bus_lock );
54
+
55
+ return match ;
56
+ }
57
+
58
+ static ssize_t do_id_store (struct device_driver * drv , const char * buf ,
59
+ size_t count , bool add )
60
+ {
61
+ struct dax_device_driver * dax_drv = to_dax_drv (drv );
62
+ unsigned int region_id , id ;
63
+ char devname [DAX_NAME_LEN ];
64
+ struct dax_id * dax_id ;
65
+ ssize_t rc = count ;
66
+ int fields ;
67
+
68
+ fields = sscanf (buf , "dax%d.%d" , & region_id , & id );
69
+ if (fields != 2 )
70
+ return - EINVAL ;
71
+ sprintf (devname , "dax%d.%d" , region_id , id );
72
+ if (!sysfs_streq (buf , devname ))
73
+ return - EINVAL ;
74
+
75
+ mutex_lock (& dax_bus_lock );
76
+ dax_id = __dax_match_id (dax_drv , buf );
77
+ if (!dax_id ) {
78
+ if (add ) {
79
+ dax_id = kzalloc (sizeof (* dax_id ), GFP_KERNEL );
80
+ if (dax_id ) {
81
+ strncpy (dax_id -> dev_name , buf , DAX_NAME_LEN );
82
+ list_add (& dax_id -> list , & dax_drv -> ids );
83
+ } else
84
+ rc = - ENOMEM ;
85
+ } else
86
+ /* nothing to remove */ ;
87
+ } else if (!add ) {
88
+ list_del (& dax_id -> list );
89
+ kfree (dax_id );
90
+ } else
91
+ /* dax_id already added */ ;
92
+ mutex_unlock (& dax_bus_lock );
93
+ return rc ;
94
+ }
95
+
96
+ static ssize_t new_id_store (struct device_driver * drv , const char * buf ,
97
+ size_t count )
98
+ {
99
+ return do_id_store (drv , buf , count , true);
100
+ }
101
+ static DRIVER_ATTR_WO (new_id );
102
+
103
+ static ssize_t remove_id_store (struct device_driver * drv , const char * buf ,
104
+ size_t count )
105
+ {
106
+ return do_id_store (drv , buf , count , false);
107
+ }
108
+ static DRIVER_ATTR_WO (remove_id );
109
+
110
+ static struct attribute * dax_drv_attrs [] = {
111
+ & driver_attr_new_id .attr ,
112
+ & driver_attr_remove_id .attr ,
113
+ NULL ,
114
+ };
115
+ ATTRIBUTE_GROUPS (dax_drv );
116
+
19
117
static int dax_bus_match (struct device * dev , struct device_driver * drv );
20
118
21
119
static struct bus_type dax_bus_type = {
22
120
.name = "dax" ,
23
121
.uevent = dax_bus_uevent ,
24
122
.match = dax_bus_match ,
123
+ .drv_groups = dax_drv_groups ,
25
124
};
26
125
27
126
static int dax_bus_match (struct device * dev , struct device_driver * drv )
28
127
{
128
+ struct dax_device_driver * dax_drv = to_dax_drv (drv );
129
+
29
130
/*
30
- * The drivers that can register on the 'dax' bus are private to
31
- * drivers/dax/ so any device and driver on the bus always
32
- * match.
131
+ * All but the 'device-dax' driver, which has 'match_always'
132
+ * set, requires an exact id match.
33
133
*/
34
- return 1 ;
134
+ if (dax_drv -> match_always )
135
+ return 1 ;
136
+
137
+ return dax_match_id (dax_drv , dev );
35
138
}
36
139
37
140
/*
@@ -273,17 +376,49 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id,
273
376
}
274
377
EXPORT_SYMBOL_GPL (devm_create_dev_dax );
275
378
276
- int __dax_driver_register (struct device_driver * drv ,
379
+ static int match_always_count ;
380
+
381
+ int __dax_driver_register (struct dax_device_driver * dax_drv ,
277
382
struct module * module , const char * mod_name )
278
383
{
384
+ struct device_driver * drv = & dax_drv -> drv ;
385
+ int rc = 0 ;
386
+
387
+ INIT_LIST_HEAD (& dax_drv -> ids );
279
388
drv -> owner = module ;
280
389
drv -> name = mod_name ;
281
390
drv -> mod_name = mod_name ;
282
391
drv -> bus = & dax_bus_type ;
392
+
393
+ /* there can only be one default driver */
394
+ mutex_lock (& dax_bus_lock );
395
+ match_always_count += dax_drv -> match_always ;
396
+ if (match_always_count > 1 ) {
397
+ match_always_count -- ;
398
+ WARN_ON (1 );
399
+ rc = - EINVAL ;
400
+ }
401
+ mutex_unlock (& dax_bus_lock );
402
+ if (rc )
403
+ return rc ;
283
404
return driver_register (drv );
284
405
}
285
406
EXPORT_SYMBOL_GPL (__dax_driver_register );
286
407
408
+ void dax_driver_unregister (struct dax_device_driver * dax_drv )
409
+ {
410
+ struct dax_id * dax_id , * _id ;
411
+
412
+ mutex_lock (& dax_bus_lock );
413
+ match_always_count -= dax_drv -> match_always ;
414
+ list_for_each_entry_safe (dax_id , _id , & dax_drv -> ids , list ) {
415
+ list_del (& dax_id -> list );
416
+ kfree (dax_id );
417
+ }
418
+ mutex_unlock (& dax_bus_lock );
419
+ }
420
+ EXPORT_SYMBOL_GPL (dax_driver_unregister );
421
+
287
422
int __init dax_bus_init (void )
288
423
{
289
424
return bus_register (& dax_bus_type );
0 commit comments