2 * Recognize and maintain s390 storage class memory.
4 * Copyright IBM Corp. 2012
5 * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/mutex.h>
11 #include <linux/slab.h>
12 #include <linux/init.h>
13 #include <linux/err.h>
17 static struct device
*scm_root
;
19 #define to_scm_dev(n) container_of(n, struct scm_device, dev)
20 #define to_scm_drv(d) container_of(d, struct scm_driver, drv)
22 static int scmdev_probe(struct device
*dev
)
24 struct scm_device
*scmdev
= to_scm_dev(dev
);
25 struct scm_driver
*scmdrv
= to_scm_drv(dev
->driver
);
27 return scmdrv
->probe
? scmdrv
->probe(scmdev
) : -ENODEV
;
30 static int scmdev_remove(struct device
*dev
)
32 struct scm_device
*scmdev
= to_scm_dev(dev
);
33 struct scm_driver
*scmdrv
= to_scm_drv(dev
->driver
);
35 return scmdrv
->remove
? scmdrv
->remove(scmdev
) : -ENODEV
;
38 static int scmdev_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
40 return add_uevent_var(env
, "MODALIAS=scm:scmdev");
43 static struct bus_type scm_bus_type
= {
45 .probe
= scmdev_probe
,
46 .remove
= scmdev_remove
,
47 .uevent
= scmdev_uevent
,
51 * scm_driver_register() - register a scm driver
52 * @scmdrv: driver to be registered
54 int scm_driver_register(struct scm_driver
*scmdrv
)
56 struct device_driver
*drv
= &scmdrv
->drv
;
58 drv
->bus
= &scm_bus_type
;
60 return driver_register(drv
);
62 EXPORT_SYMBOL_GPL(scm_driver_register
);
65 * scm_driver_unregister() - deregister a scm driver
66 * @scmdrv: driver to be deregistered
68 void scm_driver_unregister(struct scm_driver
*scmdrv
)
70 driver_unregister(&scmdrv
->drv
);
72 EXPORT_SYMBOL_GPL(scm_driver_unregister
);
74 void scm_irq_handler(struct aob
*aob
, int error
)
76 struct aob_rq_header
*aobrq
= (void *) aob
->request
.data
;
77 struct scm_device
*scmdev
= aobrq
->scmdev
;
78 struct scm_driver
*scmdrv
= to_scm_drv(scmdev
->dev
.driver
);
80 scmdrv
->handler(scmdev
, aobrq
->data
, error
);
82 EXPORT_SYMBOL_GPL(scm_irq_handler
);
84 #define scm_attr(name) \
85 static ssize_t show_##name(struct device *dev, \
86 struct device_attribute *attr, char *buf) \
88 struct scm_device *scmdev = to_scm_dev(dev); \
92 ret = sprintf(buf, "%u\n", scmdev->attrs.name); \
97 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
99 scm_attr(persistence
);
100 scm_attr(oper_state
);
101 scm_attr(data_state
);
106 static struct attribute
*scmdev_attrs
[] = {
107 &dev_attr_persistence
.attr
,
108 &dev_attr_oper_state
.attr
,
109 &dev_attr_data_state
.attr
,
111 &dev_attr_release
.attr
,
112 &dev_attr_res_id
.attr
,
116 static struct attribute_group scmdev_attr_group
= {
117 .attrs
= scmdev_attrs
,
120 static const struct attribute_group
*scmdev_attr_groups
[] = {
125 static void scmdev_release(struct device
*dev
)
127 struct scm_device
*scmdev
= to_scm_dev(dev
);
132 static void scmdev_setup(struct scm_device
*scmdev
, struct sale
*sale
,
133 unsigned int size
, unsigned int max_blk_count
)
135 dev_set_name(&scmdev
->dev
, "%016llx", (unsigned long long) sale
->sa
);
136 scmdev
->nr_max_block
= max_blk_count
;
137 scmdev
->address
= sale
->sa
;
138 scmdev
->size
= 1UL << size
;
139 scmdev
->attrs
.rank
= sale
->rank
;
140 scmdev
->attrs
.persistence
= sale
->p
;
141 scmdev
->attrs
.oper_state
= sale
->op_state
;
142 scmdev
->attrs
.data_state
= sale
->data_state
;
143 scmdev
->attrs
.rank
= sale
->rank
;
144 scmdev
->attrs
.release
= sale
->r
;
145 scmdev
->attrs
.res_id
= sale
->rid
;
146 scmdev
->dev
.parent
= scm_root
;
147 scmdev
->dev
.bus
= &scm_bus_type
;
148 scmdev
->dev
.release
= scmdev_release
;
149 scmdev
->dev
.groups
= scmdev_attr_groups
;
153 * Check for state-changes, notify the driver and userspace.
155 static void scmdev_update(struct scm_device
*scmdev
, struct sale
*sale
)
157 struct scm_driver
*scmdrv
;
160 device_lock(&scmdev
->dev
);
161 changed
= scmdev
->attrs
.rank
!= sale
->rank
||
162 scmdev
->attrs
.oper_state
!= sale
->op_state
;
163 scmdev
->attrs
.rank
= sale
->rank
;
164 scmdev
->attrs
.oper_state
= sale
->op_state
;
165 if (!scmdev
->dev
.driver
)
167 scmdrv
= to_scm_drv(scmdev
->dev
.driver
);
168 if (changed
&& scmdrv
->notify
)
169 scmdrv
->notify(scmdev
, SCM_CHANGE
);
171 device_unlock(&scmdev
->dev
);
173 kobject_uevent(&scmdev
->dev
.kobj
, KOBJ_CHANGE
);
176 static int check_address(struct device
*dev
, void *data
)
178 struct scm_device
*scmdev
= to_scm_dev(dev
);
179 struct sale
*sale
= data
;
181 return scmdev
->address
== sale
->sa
;
184 static struct scm_device
*scmdev_find(struct sale
*sale
)
188 dev
= bus_find_device(&scm_bus_type
, NULL
, sale
, check_address
);
190 return dev
? to_scm_dev(dev
) : NULL
;
193 static int scm_add(struct chsc_scm_info
*scm_info
, size_t num
)
195 struct sale
*sale
, *scmal
= scm_info
->scmal
;
196 struct scm_device
*scmdev
;
199 for (sale
= scmal
; sale
< scmal
+ num
; sale
++) {
200 scmdev
= scmdev_find(sale
);
202 scmdev_update(scmdev
, sale
);
203 /* Release reference from scm_find(). */
204 put_device(&scmdev
->dev
);
207 scmdev
= kzalloc(sizeof(*scmdev
), GFP_KERNEL
);
210 scmdev_setup(scmdev
, sale
, scm_info
->is
, scm_info
->mbc
);
211 ret
= device_register(&scmdev
->dev
);
213 /* Release reference from device_initialize(). */
214 put_device(&scmdev
->dev
);
222 int scm_update_information(void)
224 struct chsc_scm_info
*scm_info
;
229 scm_info
= (void *)__get_free_page(GFP_KERNEL
| GFP_DMA
);
234 ret
= chsc_scm_info(scm_info
, token
);
238 num
= (scm_info
->response
.length
-
239 (offsetof(struct chsc_scm_info
, scmal
) -
240 offsetof(struct chsc_scm_info
, response
))
241 ) / sizeof(struct sale
);
243 ret
= scm_add(scm_info
, num
);
247 token
= scm_info
->restok
;
250 free_page((unsigned long)scm_info
);
255 static int scm_dev_avail(struct device
*dev
, void *unused
)
257 struct scm_driver
*scmdrv
= to_scm_drv(dev
->driver
);
258 struct scm_device
*scmdev
= to_scm_dev(dev
);
260 if (dev
->driver
&& scmdrv
->notify
)
261 scmdrv
->notify(scmdev
, SCM_AVAIL
);
266 int scm_process_availability_information(void)
268 return bus_for_each_dev(&scm_bus_type
, NULL
, NULL
, scm_dev_avail
);
271 static int __init
scm_init(void)
275 ret
= bus_register(&scm_bus_type
);
279 scm_root
= root_device_register("scm");
280 if (IS_ERR(scm_root
)) {
281 bus_unregister(&scm_bus_type
);
282 return PTR_ERR(scm_root
);
285 scm_update_information();
288 subsys_initcall_sync(scm_init
);