core.c (c95baf12f5077419db01313ab61c2aac007d40cd) core.c (48001ea50d17f3eb06a552e9ecf21f7fc01b25da)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
4 */
5#include <linux/libnvdimm.h>
6#include <linux/badblocks.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
4 */
5#include <linux/libnvdimm.h>
6#include <linux/badblocks.h>
7#include <linux/suspend.h>
7#include <linux/export.h>
8#include <linux/module.h>
9#include <linux/blkdev.h>
10#include <linux/device.h>
11#include <linux/ctype.h>
12#include <linux/ndctl.h>
13#include <linux/mutex.h>
14#include <linux/slab.h>

--- 369 unchanged lines hidden (view full) ---

384 &dev_attr_provider.attr,
385 NULL,
386};
387
388static const struct attribute_group nvdimm_bus_attribute_group = {
389 .attrs = nvdimm_bus_attributes,
390};
391
8#include <linux/export.h>
9#include <linux/module.h>
10#include <linux/blkdev.h>
11#include <linux/device.h>
12#include <linux/ctype.h>
13#include <linux/ndctl.h>
14#include <linux/mutex.h>
15#include <linux/slab.h>

--- 369 unchanged lines hidden (view full) ---

385 &dev_attr_provider.attr,
386 NULL,
387};
388
389static const struct attribute_group nvdimm_bus_attribute_group = {
390 .attrs = nvdimm_bus_attributes,
391};
392
393static ssize_t capability_show(struct device *dev,
394 struct device_attribute *attr, char *buf)
395{
396 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
397 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
398 enum nvdimm_fwa_capability cap;
399
400 if (!nd_desc->fw_ops)
401 return -EOPNOTSUPP;
402
403 nvdimm_bus_lock(dev);
404 cap = nd_desc->fw_ops->capability(nd_desc);
405 nvdimm_bus_unlock(dev);
406
407 switch (cap) {
408 case NVDIMM_FWA_CAP_QUIESCE:
409 return sprintf(buf, "quiesce\n");
410 case NVDIMM_FWA_CAP_LIVE:
411 return sprintf(buf, "live\n");
412 default:
413 return -EOPNOTSUPP;
414 }
415}
416
417static DEVICE_ATTR_RO(capability);
418
419static ssize_t activate_show(struct device *dev,
420 struct device_attribute *attr, char *buf)
421{
422 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
423 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
424 enum nvdimm_fwa_capability cap;
425 enum nvdimm_fwa_state state;
426
427 if (!nd_desc->fw_ops)
428 return -EOPNOTSUPP;
429
430 nvdimm_bus_lock(dev);
431 cap = nd_desc->fw_ops->capability(nd_desc);
432 state = nd_desc->fw_ops->activate_state(nd_desc);
433 nvdimm_bus_unlock(dev);
434
435 if (cap < NVDIMM_FWA_CAP_QUIESCE)
436 return -EOPNOTSUPP;
437
438 switch (state) {
439 case NVDIMM_FWA_IDLE:
440 return sprintf(buf, "idle\n");
441 case NVDIMM_FWA_BUSY:
442 return sprintf(buf, "busy\n");
443 case NVDIMM_FWA_ARMED:
444 return sprintf(buf, "armed\n");
445 case NVDIMM_FWA_ARM_OVERFLOW:
446 return sprintf(buf, "overflow\n");
447 default:
448 return -ENXIO;
449 }
450}
451
452static int exec_firmware_activate(void *data)
453{
454 struct nvdimm_bus_descriptor *nd_desc = data;
455
456 return nd_desc->fw_ops->activate(nd_desc);
457}
458
459static ssize_t activate_store(struct device *dev,
460 struct device_attribute *attr, const char *buf, size_t len)
461{
462 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
463 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
464 enum nvdimm_fwa_state state;
465 bool quiesce;
466 ssize_t rc;
467
468 if (!nd_desc->fw_ops)
469 return -EOPNOTSUPP;
470
471 if (sysfs_streq(buf, "live"))
472 quiesce = false;
473 else if (sysfs_streq(buf, "quiesce"))
474 quiesce = true;
475 else
476 return -EINVAL;
477
478 nvdimm_bus_lock(dev);
479 state = nd_desc->fw_ops->activate_state(nd_desc);
480
481 switch (state) {
482 case NVDIMM_FWA_BUSY:
483 rc = -EBUSY;
484 break;
485 case NVDIMM_FWA_ARMED:
486 case NVDIMM_FWA_ARM_OVERFLOW:
487 if (quiesce)
488 rc = hibernate_quiet_exec(exec_firmware_activate, nd_desc);
489 else
490 rc = nd_desc->fw_ops->activate(nd_desc);
491 break;
492 case NVDIMM_FWA_IDLE:
493 default:
494 rc = -ENXIO;
495 }
496 nvdimm_bus_unlock(dev);
497
498 if (rc == 0)
499 rc = len;
500 return rc;
501}
502
503static DEVICE_ATTR_ADMIN_RW(activate);
504
505static umode_t nvdimm_bus_firmware_visible(struct kobject *kobj, struct attribute *a, int n)
506{
507 struct device *dev = container_of(kobj, typeof(*dev), kobj);
508 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
509 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
510 enum nvdimm_fwa_capability cap;
511
512 /*
513 * Both 'activate' and 'capability' disappear when no ops
514 * detected, or a negative capability is indicated.
515 */
516 if (!nd_desc->fw_ops)
517 return 0;
518
519 nvdimm_bus_lock(dev);
520 cap = nd_desc->fw_ops->capability(nd_desc);
521 nvdimm_bus_unlock(dev);
522
523 if (cap < NVDIMM_FWA_CAP_QUIESCE)
524 return 0;
525
526 return a->mode;
527}
528static struct attribute *nvdimm_bus_firmware_attributes[] = {
529 &dev_attr_activate.attr,
530 &dev_attr_capability.attr,
531 NULL,
532};
533
534static const struct attribute_group nvdimm_bus_firmware_attribute_group = {
535 .name = "firmware",
536 .attrs = nvdimm_bus_firmware_attributes,
537 .is_visible = nvdimm_bus_firmware_visible,
538};
539
392const struct attribute_group *nvdimm_bus_attribute_groups[] = {
393 &nvdimm_bus_attribute_group,
540const struct attribute_group *nvdimm_bus_attribute_groups[] = {
541 &nvdimm_bus_attribute_group,
542 &nvdimm_bus_firmware_attribute_group,
394 NULL,
395};
396
397int nvdimm_bus_add_badrange(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
398{
399 return badrange_add(&nvdimm_bus->badrange, addr, length);
400}
401EXPORT_SYMBOL_GPL(nvdimm_bus_add_badrange);

--- 67 unchanged lines hidden ---
543 NULL,
544};
545
546int nvdimm_bus_add_badrange(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
547{
548 return badrange_add(&nvdimm_bus->badrange, addr, length);
549}
550EXPORT_SYMBOL_GPL(nvdimm_bus_add_badrange);

--- 67 unchanged lines hidden ---