0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/slab.h>
0013 #include <linux/init.h>
0014 #include <linux/err.h>
0015 #include <asm/eadm.h>
0016 #include "chsc.h"
0017
0018 static struct device *scm_root;
0019
0020 #define to_scm_dev(n) container_of(n, struct scm_device, dev)
0021 #define to_scm_drv(d) container_of(d, struct scm_driver, drv)
0022
0023 static int scmdev_probe(struct device *dev)
0024 {
0025 struct scm_device *scmdev = to_scm_dev(dev);
0026 struct scm_driver *scmdrv = to_scm_drv(dev->driver);
0027
0028 return scmdrv->probe ? scmdrv->probe(scmdev) : -ENODEV;
0029 }
0030
0031 static void scmdev_remove(struct device *dev)
0032 {
0033 struct scm_device *scmdev = to_scm_dev(dev);
0034 struct scm_driver *scmdrv = to_scm_drv(dev->driver);
0035
0036 if (scmdrv->remove)
0037 scmdrv->remove(scmdev);
0038 }
0039
0040 static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env)
0041 {
0042 return add_uevent_var(env, "MODALIAS=scm:scmdev");
0043 }
0044
0045 static struct bus_type scm_bus_type = {
0046 .name = "scm",
0047 .probe = scmdev_probe,
0048 .remove = scmdev_remove,
0049 .uevent = scmdev_uevent,
0050 };
0051
0052
0053
0054
0055
0056 int scm_driver_register(struct scm_driver *scmdrv)
0057 {
0058 struct device_driver *drv = &scmdrv->drv;
0059
0060 drv->bus = &scm_bus_type;
0061
0062 return driver_register(drv);
0063 }
0064 EXPORT_SYMBOL_GPL(scm_driver_register);
0065
0066
0067
0068
0069
0070 void scm_driver_unregister(struct scm_driver *scmdrv)
0071 {
0072 driver_unregister(&scmdrv->drv);
0073 }
0074 EXPORT_SYMBOL_GPL(scm_driver_unregister);
0075
0076 void scm_irq_handler(struct aob *aob, blk_status_t error)
0077 {
0078 struct aob_rq_header *aobrq = (void *) aob->request.data;
0079 struct scm_device *scmdev = aobrq->scmdev;
0080 struct scm_driver *scmdrv = to_scm_drv(scmdev->dev.driver);
0081
0082 scmdrv->handler(scmdev, aobrq->data, error);
0083 }
0084 EXPORT_SYMBOL_GPL(scm_irq_handler);
0085
0086 #define scm_attr(name) \
0087 static ssize_t show_##name(struct device *dev, \
0088 struct device_attribute *attr, char *buf) \
0089 { \
0090 struct scm_device *scmdev = to_scm_dev(dev); \
0091 int ret; \
0092 \
0093 device_lock(dev); \
0094 ret = sprintf(buf, "%u\n", scmdev->attrs.name); \
0095 device_unlock(dev); \
0096 \
0097 return ret; \
0098 } \
0099 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
0100
0101 scm_attr(persistence);
0102 scm_attr(oper_state);
0103 scm_attr(data_state);
0104 scm_attr(rank);
0105 scm_attr(release);
0106 scm_attr(res_id);
0107
0108 static struct attribute *scmdev_attrs[] = {
0109 &dev_attr_persistence.attr,
0110 &dev_attr_oper_state.attr,
0111 &dev_attr_data_state.attr,
0112 &dev_attr_rank.attr,
0113 &dev_attr_release.attr,
0114 &dev_attr_res_id.attr,
0115 NULL,
0116 };
0117
0118 static struct attribute_group scmdev_attr_group = {
0119 .attrs = scmdev_attrs,
0120 };
0121
0122 static const struct attribute_group *scmdev_attr_groups[] = {
0123 &scmdev_attr_group,
0124 NULL,
0125 };
0126
0127 static void scmdev_release(struct device *dev)
0128 {
0129 struct scm_device *scmdev = to_scm_dev(dev);
0130
0131 kfree(scmdev);
0132 }
0133
0134 static void scmdev_setup(struct scm_device *scmdev, struct sale *sale,
0135 unsigned int size, unsigned int max_blk_count)
0136 {
0137 dev_set_name(&scmdev->dev, "%016llx", (unsigned long long) sale->sa);
0138 scmdev->nr_max_block = max_blk_count;
0139 scmdev->address = sale->sa;
0140 scmdev->size = 1UL << size;
0141 scmdev->attrs.rank = sale->rank;
0142 scmdev->attrs.persistence = sale->p;
0143 scmdev->attrs.oper_state = sale->op_state;
0144 scmdev->attrs.data_state = sale->data_state;
0145 scmdev->attrs.rank = sale->rank;
0146 scmdev->attrs.release = sale->r;
0147 scmdev->attrs.res_id = sale->rid;
0148 scmdev->dev.parent = scm_root;
0149 scmdev->dev.bus = &scm_bus_type;
0150 scmdev->dev.release = scmdev_release;
0151 scmdev->dev.groups = scmdev_attr_groups;
0152 }
0153
0154
0155
0156
0157 static void scmdev_update(struct scm_device *scmdev, struct sale *sale)
0158 {
0159 struct scm_driver *scmdrv;
0160 bool changed;
0161
0162 device_lock(&scmdev->dev);
0163 changed = scmdev->attrs.rank != sale->rank ||
0164 scmdev->attrs.oper_state != sale->op_state;
0165 scmdev->attrs.rank = sale->rank;
0166 scmdev->attrs.oper_state = sale->op_state;
0167 if (!scmdev->dev.driver)
0168 goto out;
0169 scmdrv = to_scm_drv(scmdev->dev.driver);
0170 if (changed && scmdrv->notify)
0171 scmdrv->notify(scmdev, SCM_CHANGE);
0172 out:
0173 device_unlock(&scmdev->dev);
0174 if (changed)
0175 kobject_uevent(&scmdev->dev.kobj, KOBJ_CHANGE);
0176 }
0177
0178 static int check_address(struct device *dev, const void *data)
0179 {
0180 struct scm_device *scmdev = to_scm_dev(dev);
0181 const struct sale *sale = data;
0182
0183 return scmdev->address == sale->sa;
0184 }
0185
0186 static struct scm_device *scmdev_find(struct sale *sale)
0187 {
0188 struct device *dev;
0189
0190 dev = bus_find_device(&scm_bus_type, NULL, sale, check_address);
0191
0192 return dev ? to_scm_dev(dev) : NULL;
0193 }
0194
0195 static int scm_add(struct chsc_scm_info *scm_info, size_t num)
0196 {
0197 struct sale *sale, *scmal = scm_info->scmal;
0198 struct scm_device *scmdev;
0199 int ret;
0200
0201 for (sale = scmal; sale < scmal + num; sale++) {
0202 scmdev = scmdev_find(sale);
0203 if (scmdev) {
0204 scmdev_update(scmdev, sale);
0205
0206 put_device(&scmdev->dev);
0207 continue;
0208 }
0209 scmdev = kzalloc(sizeof(*scmdev), GFP_KERNEL);
0210 if (!scmdev)
0211 return -ENODEV;
0212 scmdev_setup(scmdev, sale, scm_info->is, scm_info->mbc);
0213 ret = device_register(&scmdev->dev);
0214 if (ret) {
0215
0216 put_device(&scmdev->dev);
0217 return ret;
0218 }
0219 }
0220
0221 return 0;
0222 }
0223
0224 int scm_update_information(void)
0225 {
0226 struct chsc_scm_info *scm_info;
0227 u64 token = 0;
0228 size_t num;
0229 int ret;
0230
0231 scm_info = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
0232 if (!scm_info)
0233 return -ENOMEM;
0234
0235 do {
0236 ret = chsc_scm_info(scm_info, token);
0237 if (ret)
0238 break;
0239
0240 num = (scm_info->response.length -
0241 (offsetof(struct chsc_scm_info, scmal) -
0242 offsetof(struct chsc_scm_info, response))
0243 ) / sizeof(struct sale);
0244
0245 ret = scm_add(scm_info, num);
0246 if (ret)
0247 break;
0248
0249 token = scm_info->restok;
0250 } while (token);
0251
0252 free_page((unsigned long)scm_info);
0253
0254 return ret;
0255 }
0256
0257 static int scm_dev_avail(struct device *dev, void *unused)
0258 {
0259 struct scm_driver *scmdrv = to_scm_drv(dev->driver);
0260 struct scm_device *scmdev = to_scm_dev(dev);
0261
0262 if (dev->driver && scmdrv->notify)
0263 scmdrv->notify(scmdev, SCM_AVAIL);
0264
0265 return 0;
0266 }
0267
0268 int scm_process_availability_information(void)
0269 {
0270 return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail);
0271 }
0272
0273 static int __init scm_init(void)
0274 {
0275 int ret;
0276
0277 ret = bus_register(&scm_bus_type);
0278 if (ret)
0279 return ret;
0280
0281 scm_root = root_device_register("scm");
0282 if (IS_ERR(scm_root)) {
0283 bus_unregister(&scm_bus_type);
0284 return PTR_ERR(scm_root);
0285 }
0286
0287 scm_update_information();
0288 return 0;
0289 }
0290 subsys_initcall_sync(scm_init);