Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Recognize and maintain s390 storage class memory.
0004  *
0005  * Copyright IBM Corp. 2012
0006  * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
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  * scm_driver_register() - register a scm driver
0054  * @scmdrv: driver to be registered
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  * scm_driver_unregister() - deregister a scm driver
0068  * @scmdrv: driver to be deregistered
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  * Check for state-changes, notify the driver and userspace.
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             /* Release reference from scm_find(). */
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             /* Release reference from device_initialize(). */
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);