0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011
0012 #include <linux/types.h>
0013 #include <linux/module.h>
0014 #include <linux/device.h>
0015 #include <linux/configfs.h>
0016 #include <linux/slab.h>
0017 #include <linux/stm.h>
0018 #include "stm.h"
0019
0020
0021
0022
0023
0024 struct stp_policy {
0025 struct config_group group;
0026 struct stm_device *stm;
0027 };
0028
0029 struct stp_policy_node {
0030 struct config_group group;
0031 struct stp_policy *policy;
0032 unsigned int first_master;
0033 unsigned int last_master;
0034 unsigned int first_channel;
0035 unsigned int last_channel;
0036
0037 unsigned char priv[];
0038 };
0039
0040 void *stp_policy_node_priv(struct stp_policy_node *pn)
0041 {
0042 if (!pn)
0043 return NULL;
0044
0045 return pn->priv;
0046 }
0047
0048 static struct configfs_subsystem stp_policy_subsys;
0049
0050 void stp_policy_node_get_ranges(struct stp_policy_node *policy_node,
0051 unsigned int *mstart, unsigned int *mend,
0052 unsigned int *cstart, unsigned int *cend)
0053 {
0054 *mstart = policy_node->first_master;
0055 *mend = policy_node->last_master;
0056 *cstart = policy_node->first_channel;
0057 *cend = policy_node->last_channel;
0058 }
0059
0060 static inline struct stp_policy *to_stp_policy(struct config_item *item)
0061 {
0062 return item ?
0063 container_of(to_config_group(item), struct stp_policy, group) :
0064 NULL;
0065 }
0066
0067 static inline struct stp_policy_node *
0068 to_stp_policy_node(struct config_item *item)
0069 {
0070 return item ?
0071 container_of(to_config_group(item), struct stp_policy_node,
0072 group) :
0073 NULL;
0074 }
0075
0076 void *to_pdrv_policy_node(struct config_item *item)
0077 {
0078 struct stp_policy_node *node = to_stp_policy_node(item);
0079
0080 return stp_policy_node_priv(node);
0081 }
0082 EXPORT_SYMBOL_GPL(to_pdrv_policy_node);
0083
0084 static ssize_t
0085 stp_policy_node_masters_show(struct config_item *item, char *page)
0086 {
0087 struct stp_policy_node *policy_node = to_stp_policy_node(item);
0088 ssize_t count;
0089
0090 count = sprintf(page, "%u %u\n", policy_node->first_master,
0091 policy_node->last_master);
0092
0093 return count;
0094 }
0095
0096 static ssize_t
0097 stp_policy_node_masters_store(struct config_item *item, const char *page,
0098 size_t count)
0099 {
0100 struct stp_policy_node *policy_node = to_stp_policy_node(item);
0101 unsigned int first, last;
0102 struct stm_device *stm;
0103 char *p = (char *)page;
0104 ssize_t ret = -ENODEV;
0105
0106 if (sscanf(p, "%u %u", &first, &last) != 2)
0107 return -EINVAL;
0108
0109 mutex_lock(&stp_policy_subsys.su_mutex);
0110 stm = policy_node->policy->stm;
0111 if (!stm)
0112 goto unlock;
0113
0114
0115 if (first > last || first < stm->data->sw_start ||
0116 last > stm->data->sw_end) {
0117 ret = -ERANGE;
0118 goto unlock;
0119 }
0120
0121 ret = count;
0122 policy_node->first_master = first;
0123 policy_node->last_master = last;
0124
0125 unlock:
0126 mutex_unlock(&stp_policy_subsys.su_mutex);
0127
0128 return ret;
0129 }
0130
0131 static ssize_t
0132 stp_policy_node_channels_show(struct config_item *item, char *page)
0133 {
0134 struct stp_policy_node *policy_node = to_stp_policy_node(item);
0135 ssize_t count;
0136
0137 count = sprintf(page, "%u %u\n", policy_node->first_channel,
0138 policy_node->last_channel);
0139
0140 return count;
0141 }
0142
0143 static ssize_t
0144 stp_policy_node_channels_store(struct config_item *item, const char *page,
0145 size_t count)
0146 {
0147 struct stp_policy_node *policy_node = to_stp_policy_node(item);
0148 unsigned int first, last;
0149 struct stm_device *stm;
0150 char *p = (char *)page;
0151 ssize_t ret = -ENODEV;
0152
0153 if (sscanf(p, "%u %u", &first, &last) != 2)
0154 return -EINVAL;
0155
0156 mutex_lock(&stp_policy_subsys.su_mutex);
0157 stm = policy_node->policy->stm;
0158 if (!stm)
0159 goto unlock;
0160
0161 if (first > INT_MAX || last > INT_MAX || first > last ||
0162 last >= stm->data->sw_nchannels) {
0163 ret = -ERANGE;
0164 goto unlock;
0165 }
0166
0167 ret = count;
0168 policy_node->first_channel = first;
0169 policy_node->last_channel = last;
0170
0171 unlock:
0172 mutex_unlock(&stp_policy_subsys.su_mutex);
0173
0174 return ret;
0175 }
0176
0177 static void stp_policy_node_release(struct config_item *item)
0178 {
0179 struct stp_policy_node *node = to_stp_policy_node(item);
0180
0181 kfree(node);
0182 }
0183
0184 static struct configfs_item_operations stp_policy_node_item_ops = {
0185 .release = stp_policy_node_release,
0186 };
0187
0188 CONFIGFS_ATTR(stp_policy_node_, masters);
0189 CONFIGFS_ATTR(stp_policy_node_, channels);
0190
0191 static struct configfs_attribute *stp_policy_node_attrs[] = {
0192 &stp_policy_node_attr_masters,
0193 &stp_policy_node_attr_channels,
0194 NULL,
0195 };
0196
0197 static const struct config_item_type stp_policy_type;
0198 static const struct config_item_type stp_policy_node_type;
0199
0200 const struct config_item_type *
0201 get_policy_node_type(struct configfs_attribute **attrs)
0202 {
0203 struct config_item_type *type;
0204 struct configfs_attribute **merged;
0205
0206 type = kmemdup(&stp_policy_node_type, sizeof(stp_policy_node_type),
0207 GFP_KERNEL);
0208 if (!type)
0209 return NULL;
0210
0211 merged = memcat_p(stp_policy_node_attrs, attrs);
0212 if (!merged) {
0213 kfree(type);
0214 return NULL;
0215 }
0216
0217 type->ct_attrs = merged;
0218
0219 return type;
0220 }
0221
0222 static struct config_group *
0223 stp_policy_node_make(struct config_group *group, const char *name)
0224 {
0225 const struct config_item_type *type = &stp_policy_node_type;
0226 struct stp_policy_node *policy_node, *parent_node;
0227 const struct stm_protocol_driver *pdrv;
0228 struct stp_policy *policy;
0229
0230 if (group->cg_item.ci_type == &stp_policy_type) {
0231 policy = container_of(group, struct stp_policy, group);
0232 } else {
0233 parent_node = container_of(group, struct stp_policy_node,
0234 group);
0235 policy = parent_node->policy;
0236 }
0237
0238 if (!policy->stm)
0239 return ERR_PTR(-ENODEV);
0240
0241 pdrv = policy->stm->pdrv;
0242 policy_node =
0243 kzalloc(offsetof(struct stp_policy_node, priv[pdrv->priv_sz]),
0244 GFP_KERNEL);
0245 if (!policy_node)
0246 return ERR_PTR(-ENOMEM);
0247
0248 if (pdrv->policy_node_init)
0249 pdrv->policy_node_init((void *)policy_node->priv);
0250
0251 if (policy->stm->pdrv_node_type)
0252 type = policy->stm->pdrv_node_type;
0253
0254 config_group_init_type_name(&policy_node->group, name, type);
0255
0256 policy_node->policy = policy;
0257
0258
0259 policy_node->first_master = policy->stm->data->sw_start;
0260 policy_node->last_master = policy->stm->data->sw_end;
0261 policy_node->first_channel = 0;
0262 policy_node->last_channel = policy->stm->data->sw_nchannels - 1;
0263
0264 return &policy_node->group;
0265 }
0266
0267 static void
0268 stp_policy_node_drop(struct config_group *group, struct config_item *item)
0269 {
0270 config_item_put(item);
0271 }
0272
0273 static struct configfs_group_operations stp_policy_node_group_ops = {
0274 .make_group = stp_policy_node_make,
0275 .drop_item = stp_policy_node_drop,
0276 };
0277
0278 static const struct config_item_type stp_policy_node_type = {
0279 .ct_item_ops = &stp_policy_node_item_ops,
0280 .ct_group_ops = &stp_policy_node_group_ops,
0281 .ct_attrs = stp_policy_node_attrs,
0282 .ct_owner = THIS_MODULE,
0283 };
0284
0285
0286
0287
0288 static ssize_t stp_policy_device_show(struct config_item *item,
0289 char *page)
0290 {
0291 struct stp_policy *policy = to_stp_policy(item);
0292 ssize_t count;
0293
0294 count = sprintf(page, "%s\n",
0295 (policy && policy->stm) ?
0296 policy->stm->data->name :
0297 "<none>");
0298
0299 return count;
0300 }
0301
0302 CONFIGFS_ATTR_RO(stp_policy_, device);
0303
0304 static ssize_t stp_policy_protocol_show(struct config_item *item,
0305 char *page)
0306 {
0307 struct stp_policy *policy = to_stp_policy(item);
0308 ssize_t count;
0309
0310 count = sprintf(page, "%s\n",
0311 (policy && policy->stm) ?
0312 policy->stm->pdrv->name :
0313 "<none>");
0314
0315 return count;
0316 }
0317
0318 CONFIGFS_ATTR_RO(stp_policy_, protocol);
0319
0320 static struct configfs_attribute *stp_policy_attrs[] = {
0321 &stp_policy_attr_device,
0322 &stp_policy_attr_protocol,
0323 NULL,
0324 };
0325
0326 void stp_policy_unbind(struct stp_policy *policy)
0327 {
0328 struct stm_device *stm = policy->stm;
0329
0330
0331
0332
0333
0334
0335 if (WARN_ON_ONCE(!policy->stm))
0336 return;
0337
0338 lockdep_assert_held(&stm->policy_mutex);
0339
0340 stm->policy = NULL;
0341 policy->stm = NULL;
0342
0343
0344
0345
0346 stm_put_protocol(stm->pdrv);
0347 stm->pdrv = NULL;
0348 stm_put_device(stm);
0349 }
0350
0351 static void stp_policy_release(struct config_item *item)
0352 {
0353 struct stp_policy *policy = to_stp_policy(item);
0354 struct stm_device *stm = policy->stm;
0355
0356
0357 if (!stm)
0358 return;
0359
0360 mutex_lock(&stm->policy_mutex);
0361 stp_policy_unbind(policy);
0362 mutex_unlock(&stm->policy_mutex);
0363
0364 kfree(policy);
0365 }
0366
0367 static struct configfs_item_operations stp_policy_item_ops = {
0368 .release = stp_policy_release,
0369 };
0370
0371 static struct configfs_group_operations stp_policy_group_ops = {
0372 .make_group = stp_policy_node_make,
0373 };
0374
0375 static const struct config_item_type stp_policy_type = {
0376 .ct_item_ops = &stp_policy_item_ops,
0377 .ct_group_ops = &stp_policy_group_ops,
0378 .ct_attrs = stp_policy_attrs,
0379 .ct_owner = THIS_MODULE,
0380 };
0381
0382 static struct config_group *
0383 stp_policy_make(struct config_group *group, const char *name)
0384 {
0385 const struct config_item_type *pdrv_node_type;
0386 const struct stm_protocol_driver *pdrv;
0387 char *devname, *proto, *p;
0388 struct config_group *ret;
0389 struct stm_device *stm;
0390 int err;
0391
0392 devname = kasprintf(GFP_KERNEL, "%s", name);
0393 if (!devname)
0394 return ERR_PTR(-ENOMEM);
0395
0396
0397
0398
0399
0400
0401
0402
0403 p = strrchr(devname, '.');
0404 if (!p) {
0405 kfree(devname);
0406 return ERR_PTR(-EINVAL);
0407 }
0408
0409 *p = '\0';
0410
0411
0412
0413
0414
0415
0416 proto = strrchr(devname, ':');
0417 if (proto)
0418 *proto++ = '\0';
0419
0420 stm = stm_find_device(devname);
0421 if (!stm) {
0422 kfree(devname);
0423 return ERR_PTR(-ENODEV);
0424 }
0425
0426 err = stm_lookup_protocol(proto, &pdrv, &pdrv_node_type);
0427 kfree(devname);
0428
0429 if (err) {
0430 stm_put_device(stm);
0431 return ERR_PTR(-ENODEV);
0432 }
0433
0434 mutex_lock(&stm->policy_mutex);
0435 if (stm->policy) {
0436 ret = ERR_PTR(-EBUSY);
0437 goto unlock_policy;
0438 }
0439
0440 stm->policy = kzalloc(sizeof(*stm->policy), GFP_KERNEL);
0441 if (!stm->policy) {
0442 ret = ERR_PTR(-ENOMEM);
0443 goto unlock_policy;
0444 }
0445
0446 config_group_init_type_name(&stm->policy->group, name,
0447 &stp_policy_type);
0448
0449 stm->pdrv = pdrv;
0450 stm->pdrv_node_type = pdrv_node_type;
0451 stm->policy->stm = stm;
0452 ret = &stm->policy->group;
0453
0454 unlock_policy:
0455 mutex_unlock(&stm->policy_mutex);
0456
0457 if (IS_ERR(ret)) {
0458
0459
0460
0461
0462 stm_put_protocol(pdrv);
0463 stm_put_device(stm);
0464 }
0465
0466 return ret;
0467 }
0468
0469 static struct configfs_group_operations stp_policy_root_group_ops = {
0470 .make_group = stp_policy_make,
0471 };
0472
0473 static const struct config_item_type stp_policy_root_type = {
0474 .ct_group_ops = &stp_policy_root_group_ops,
0475 .ct_owner = THIS_MODULE,
0476 };
0477
0478 static struct configfs_subsystem stp_policy_subsys = {
0479 .su_group = {
0480 .cg_item = {
0481 .ci_namebuf = "stp-policy",
0482 .ci_type = &stp_policy_root_type,
0483 },
0484 },
0485 };
0486
0487
0488
0489
0490 static struct stp_policy_node *
0491 __stp_policy_node_lookup(struct stp_policy *policy, char *s)
0492 {
0493 struct stp_policy_node *policy_node, *ret = NULL;
0494 struct list_head *head = &policy->group.cg_children;
0495 struct config_item *item;
0496 char *start, *end = s;
0497
0498 if (list_empty(head))
0499 return NULL;
0500
0501 next:
0502 for (;;) {
0503 start = strsep(&end, "/");
0504 if (!start)
0505 break;
0506
0507 if (!*start)
0508 continue;
0509
0510 list_for_each_entry(item, head, ci_entry) {
0511 policy_node = to_stp_policy_node(item);
0512
0513 if (!strcmp(start,
0514 policy_node->group.cg_item.ci_name)) {
0515 ret = policy_node;
0516
0517 if (!end)
0518 goto out;
0519
0520 head = &policy_node->group.cg_children;
0521 goto next;
0522 }
0523 }
0524 break;
0525 }
0526
0527 out:
0528 return ret;
0529 }
0530
0531
0532 struct stp_policy_node *
0533 stp_policy_node_lookup(struct stm_device *stm, char *s)
0534 {
0535 struct stp_policy_node *policy_node = NULL;
0536
0537 mutex_lock(&stp_policy_subsys.su_mutex);
0538
0539 mutex_lock(&stm->policy_mutex);
0540 if (stm->policy)
0541 policy_node = __stp_policy_node_lookup(stm->policy, s);
0542 mutex_unlock(&stm->policy_mutex);
0543
0544 if (policy_node)
0545 config_item_get(&policy_node->group.cg_item);
0546 else
0547 mutex_unlock(&stp_policy_subsys.su_mutex);
0548
0549 return policy_node;
0550 }
0551
0552 void stp_policy_node_put(struct stp_policy_node *policy_node)
0553 {
0554 lockdep_assert_held(&stp_policy_subsys.su_mutex);
0555
0556 mutex_unlock(&stp_policy_subsys.su_mutex);
0557 config_item_put(&policy_node->group.cg_item);
0558 }
0559
0560 int __init stp_configfs_init(void)
0561 {
0562 config_group_init(&stp_policy_subsys.su_group);
0563 mutex_init(&stp_policy_subsys.su_mutex);
0564 return configfs_register_subsystem(&stp_policy_subsys);
0565 }
0566
0567 void __exit stp_configfs_exit(void)
0568 {
0569 configfs_unregister_subsystem(&stp_policy_subsys);
0570 }