Foolishly I'd missed you out of the series Cc so you only got those two patches. You should find the rest @ Subject: [RFC PATCH 0/5] RPMB internal and user-space API + WIP virtio-rpmb frontend Date: Wed, 3 Mar 2021 13:54:55 +0000 Message-Id: <20210303135500.24673-1-alex.bennee@xxxxxxxxxx> assuming you are subscribed to one of the Cc'd lists. On Wed, 3 Mar 2021 at 15:29, Ulf Hansson <ulf.hansson@xxxxxxxxxx> wrote: > > On Wed, 3 Mar 2021 at 14:55, Alex Bennée <alex.bennee@xxxxxxxxxx> wrote: > > > > A number of storage technologies support a specialised hardware > > partition designed to be resistant to replay attacks. The underlying > > HW protocols differ but the operations are common. The RPMB partition > > cannot be accessed via standard block layer, but by a set of specific > > commands: WRITE, READ, GET_WRITE_COUNTER, and PROGRAM_KEY. Such a > > partition provides authenticated and replay protected access, hence > > suitable as a secure storage. > > > > The RPMB layer aims to provide in-kernel API for Trusted Execution > > Environment (TEE) devices that are capable to securely compute block > > frame signature. In case a TEE device wishes to store a replay > > protected data, requests the storage device via RPMB layer to store > > the data. > > > > A TEE device driver can claim the RPMB interface, for example, via > > class_interface_register(). The RPMB layer provides a series of > > operations for interacting with the device. > > > > * program_key - a one time operation for setting up a new device > > * get_capacity - introspect the device capacity > > * get_write_count - check the write counter > > * write_blocks - write a series of blocks to the RPMB device > > * read_blocks - read a series of blocks from the RPMB device > > > > The detailed operation of implementing the access is left to the TEE > > device driver itself. > > > > [This is based-on Thomas Winkler's proposed API from: > > > > https://lore.kernel.org/linux-mmc/1478548394-8184-2-git-send-email-tomas.winkler@xxxxxxxxx/ > > > > The principle difference is the framing details and HW specific > > bits (JDEC vs NVME frames) are left to the lower level TEE driver to > > worry about. The eventual userspace ioctl interface will aim to be > > similarly generic. This is an RFC to follow up on: > > > > Subject: RPMB user space ABI > > Date: Thu, 11 Feb 2021 14:07:00 +0000 > > Message-ID: <87mtwashi4.fsf@xxxxxxxxxx>] > > > > Signed-off-by: Alex Bennée <alex.bennee@xxxxxxxxxx> > > Cc: Tomas Winkler <tomas.winkler@xxxxxxxxx> > > Cc: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > > Cc: Linus Walleij <linus.walleij@xxxxxxxxxx> > > Cc: Arnd Bergmann <arnd.bergmann@xxxxxxxxxx> > > Cc: Ilias Apalodimas <ilias.apalodimas@xxxxxxxxxx> > > Alex, I promise to have a closer look at this and provide my opinions. > > However, it looks like you have posted patch 1 and patch2, but the > remainder 3, 4, 5 I can't find. Was this perhaps intentional? > > Moreover, I think these kinds of changes deserve a proper > cover-letter, describing the overall goal with the series. Can you > perhaps re-submit, so clarify things. > > Kind regards > Uffe > > > --- > > MAINTAINERS | 7 + > > drivers/char/Kconfig | 2 + > > drivers/char/Makefile | 1 + > > drivers/char/rpmb/Kconfig | 11 + > > drivers/char/rpmb/Makefile | 7 + > > drivers/char/rpmb/core.c | 429 +++++++++++++++++++++++++++++++++++++ > > include/linux/rpmb.h | 163 ++++++++++++++ > > 7 files changed, 620 insertions(+) > > create mode 100644 drivers/char/rpmb/Kconfig > > create mode 100644 drivers/char/rpmb/Makefile > > create mode 100644 drivers/char/rpmb/core.c > > create mode 100644 include/linux/rpmb.h > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index bfc1b86e3e73..076f3983526c 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -15369,6 +15369,13 @@ T: git git://linuxtv.org/media_tree.git > > F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml > > F: drivers/media/platform/sunxi/sun8i-rotate/ > > > > +RPMB SUBSYSTEM > > +M: ? > > +L: linux-kernel@xxxxxxxxxxxxxxx > > +S: Supported > > +F: drivers/char/rpmb/* > > +F: include/linux/rpmb.h > > + > > RTL2830 MEDIA DRIVER > > M: Antti Palosaari <crope@xxxxxx> > > L: linux-media@xxxxxxxxxxxxxxx > > diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig > > index d229a2d0c017..a7834cc3e0ea 100644 > > --- a/drivers/char/Kconfig > > +++ b/drivers/char/Kconfig > > @@ -471,6 +471,8 @@ config ADI > > and SSM (Silicon Secured Memory). Intended consumers of this > > driver include crash and makedumpfile. > > > > +source "drivers/char/rpmb/Kconfig" > > + > > endmenu > > > > config RANDOM_TRUST_CPU > > diff --git a/drivers/char/Makefile b/drivers/char/Makefile > > index ffce287ef415..0eed6e21a7a7 100644 > > --- a/drivers/char/Makefile > > +++ b/drivers/char/Makefile > > @@ -47,3 +47,4 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o > > obj-$(CONFIG_XILLYBUS) += xillybus/ > > obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o > > obj-$(CONFIG_ADI) += adi.o > > +obj-$(CONFIG_RPMB) += rpmb/ > > diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig > > new file mode 100644 > > index 000000000000..431c2823cf70 > > --- /dev/null > > +++ b/drivers/char/rpmb/Kconfig > > @@ -0,0 +1,11 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +# Copyright (c) 2015-2019, Intel Corporation. > > + > > +config RPMB > > + tristate "RPMB partition interface" > > + help > > + Unified RPMB partition interface for eMMC and UFS. > > + Provides interface for in kernel security controllers to > > + access RPMB partition. > > + > > + If unsure, select N. > > diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile > > new file mode 100644 > > index 000000000000..24d4752a9a53 > > --- /dev/null > > +++ b/drivers/char/rpmb/Makefile > > @@ -0,0 +1,7 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +# Copyright (c) 2015-2019, Intel Corporation. > > + > > +obj-$(CONFIG_RPMB) += rpmb.o > > +rpmb-objs += core.o > > + > > +ccflags-y += -D__CHECK_ENDIAN__ > > diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c > > new file mode 100644 > > index 000000000000..a2e21c14986a > > --- /dev/null > > +++ b/drivers/char/rpmb/core.c > > @@ -0,0 +1,429 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright(c) 2015 - 2019 Intel Corporation. All rights reserved. > > + * Copyright(c) 2021 - Linaro Ltd. > > + */ > > +#include <linux/module.h> > > +#include <linux/init.h> > > +#include <linux/kernel.h> > > +#include <linux/mutex.h> > > +#include <linux/list.h> > > +#include <linux/device.h> > > +#include <linux/slab.h> > > + > > +#include <linux/rpmb.h> > > + > > +static DEFINE_IDA(rpmb_ida); > > + > > +/** > > + * rpmb_dev_get() - increase rpmb device ref counter > > + * @rdev: rpmb device > > + */ > > +struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev) > > +{ > > + return get_device(&rdev->dev) ? rdev : NULL; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_get); > > + > > +/** > > + * rpmb_dev_put() - decrease rpmb device ref counter > > + * @rdev: rpmb device > > + */ > > +void rpmb_dev_put(struct rpmb_dev *rdev) > > +{ > > + put_device(&rdev->dev); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_put); > > + > > +/** > > + * rpmb_program_key() - program the RPMB access key > > + * @rdev: rpmb device > > + * @key: key data > > + * @keylen: length of key data > > + * > > + * A successful programming of the key implies it has been set by the > > + * driver and can be used. > > + * > > + * Return: > > + * * 0 on success > > + * * -EINVAL on wrong parameters > > + * * -EPERM key already programmed > > + * * -EOPNOTSUPP if device doesn't support the requested operation > > + * * < 0 if the operation fails > > + */ > > +int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid) > > +{ > > + int err; > > + > > + if (!rdev || !keyid) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + err = -EOPNOTSUPP; > > + if (rdev->ops && rdev->ops->program_key) { > > + err = rdev->ops->program_key(rdev->dev.parent, rdev->target, > > + keyid); > > + } > > + mutex_unlock(&rdev->lock); > > + > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_program_key); > > + > > +/** > > + * rpmb_get_capacity() - returns the capacity of the rpmb device > > + * @rdev: rpmb device > > + * > > + * Return: > > + * * capacity of the device in units of 128K, on success > > + * * -EINVAL on wrong parameters > > + * * -EOPNOTSUPP if device doesn't support the requested operation > > + * * < 0 if the operation fails > > + */ > > +int rpmb_get_capacity(struct rpmb_dev *rdev) > > +{ > > + int err; > > + > > + if (!rdev) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + err = -EOPNOTSUPP; > > + if (rdev->ops && rdev->ops->get_capacity) > > + err = rdev->ops->get_capacity(rdev->dev.parent, rdev->target); > > + mutex_unlock(&rdev->lock); > > + > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_get_capacity); > > + > > +/** > > + * rpmb_get_write_count() - returns the write counter of the rpmb device > > + * @rdev: rpmb device > > + * > > + * Return: > > + * * counter > > + * * -EINVAL on wrong parameters > > + * * -EOPNOTSUPP if device doesn't support the requested operation > > + * * < 0 if the operation fails > > + */ > > +int rpmb_get_write_count(struct rpmb_dev *rdev) > > +{ > > + int err; > > + > > + if (!rdev) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + err = -EOPNOTSUPP; > > + if (rdev->ops && rdev->ops->get_write_count) > > + err = rdev->ops->get_write_count(rdev->dev.parent, rdev->target); > > + mutex_unlock(&rdev->lock); > > + > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_get_write_count); > > + > > +/** > > + * rpmb_write_blocks() - write data to RPMB device > > + * @rdev: rpmb device > > + * @addr: block address (index of first block - 256B blocks) > > + * @count: number of 256B blosks > > + * @data: pointer to data to program > > + * > > + * Write a series of blocks to the RPMB device. > > + * > > + * Return: > > + * * 0 on success > > + * * -EINVAL on wrong parameters > > + * * -EACCESS no key set > > + * * -EOPNOTSUPP if device doesn't support the requested operation > > + * * < 0 if the operation fails > > + */ > > +int rpmb_write_blocks(struct rpmb_dev *rdev, key_serial_t keyid, int addr, > > + int count, u8 *data) > > +{ > > + int err; > > + > > + if (!rdev || !count || !data) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + err = -EOPNOTSUPP; > > + if (rdev->ops && rdev->ops->write_blocks) { > > + err = rdev->ops->write_blocks(rdev->dev.parent, rdev->target, keyid, > > + addr, count, data); > > + } > > + mutex_unlock(&rdev->lock); > > + > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_write_blocks); > > + > > +/** > > + * rpmb_read_blocks() - read data from RPMB device > > + * @rdev: rpmb device > > + * @addr: block address (index of first block - 256B blocks) > > + * @count: number of 256B blocks > > + * @data: pointer to data to read > > + * > > + * Read a series of one or more blocks from the RPMB device. > > + * > > + * Return: > > + * * 0 on success > > + * * -EINVAL on wrong parameters > > + * * -EACCESS no key set > > + * * -EOPNOTSUPP if device doesn't support the requested operation > > + * * < 0 if the operation fails > > + */ > > +int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count, u8 *data) > > +{ > > + int err; > > + > > + if (!rdev || !count || !data) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + err = -EOPNOTSUPP; > > + if (rdev->ops && rdev->ops->read_blocks) { > > + err = rdev->ops->read_blocks(rdev->dev.parent, rdev->target, > > + addr, count, data); > > + } > > + mutex_unlock(&rdev->lock); > > + > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_read_blocks); > > + > > + > > +static void rpmb_dev_release(struct device *dev) > > +{ > > + struct rpmb_dev *rdev = to_rpmb_dev(dev); > > + > > + ida_simple_remove(&rpmb_ida, rdev->id); > > + kfree(rdev); > > +} > > + > > +struct class rpmb_class = { > > + .name = "rpmb", > > + .owner = THIS_MODULE, > > + .dev_release = rpmb_dev_release, > > +}; > > +EXPORT_SYMBOL(rpmb_class); > > + > > +/** > > + * rpmb_dev_find_device() - return first matching rpmb device > > + * @data: data for the match function > > + * @match: the matching function > > + * > > + * Return: matching rpmb device or NULL on failure > > + */ > > +static > > +struct rpmb_dev *rpmb_dev_find_device(const void *data, > > + int (*match)(struct device *dev, > > + const void *data)) > > +{ > > + struct device *dev; > > + > > + dev = class_find_device(&rpmb_class, NULL, data, match); > > + > > + return dev ? to_rpmb_dev(dev) : NULL; > > +} > > + > > +struct device_with_target { > > + const struct device *dev; > > + u8 target; > > +}; > > + > > +static int match_by_parent(struct device *dev, const void *data) > > +{ > > + const struct device_with_target *d = data; > > + struct rpmb_dev *rdev = to_rpmb_dev(dev); > > + > > + return (d->dev && dev->parent == d->dev && rdev->target == d->target); > > +} > > + > > +/** > > + * rpmb_dev_find_by_device() - retrieve rpmb device from the parent device > > + * @parent: parent device of the rpmb device > > + * @target: RPMB target/region within the physical device > > + * > > + * Return: NULL if there is no rpmb device associated with the parent device > > + */ > > +struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent, u8 target) > > +{ > > + struct device_with_target t; > > + > > + if (!parent) > > + return NULL; > > + > > + t.dev = parent; > > + t.target = target; > > + > > + return rpmb_dev_find_device(&t, match_by_parent); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_find_by_device); > > + > > +/** > > + * rpmb_dev_unregister() - unregister RPMB partition from the RPMB subsystem > > + * @rdev: the rpmb device to unregister > > + * Return: > > + * * 0 on success > > + * * -EINVAL on wrong parameters > > + */ > > +int rpmb_dev_unregister(struct rpmb_dev *rdev) > > +{ > > + if (!rdev) > > + return -EINVAL; > > + > > + mutex_lock(&rdev->lock); > > + device_del(&rdev->dev); > > + mutex_unlock(&rdev->lock); > > + > > + rpmb_dev_put(rdev); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_unregister); > > + > > +/** > > + * rpmb_dev_unregister_by_device() - unregister RPMB partition > > + * from the RPMB subsystem > > + * @dev: the parent device of the rpmb device > > + * @target: RPMB target/region within the physical device > > + * Return: > > + * * 0 on success > > + * * -EINVAL on wrong parameters > > + * * -ENODEV if a device cannot be find. > > + */ > > +int rpmb_dev_unregister_by_device(struct device *dev, u8 target) > > +{ > > + struct rpmb_dev *rdev; > > + > > + if (!dev) > > + return -EINVAL; > > + > > + rdev = rpmb_dev_find_by_device(dev, target); > > + if (!rdev) { > > + dev_warn(dev, "no disk found %s\n", dev_name(dev->parent)); > > + return -ENODEV; > > + } > > + > > + rpmb_dev_put(rdev); > > + > > + return rpmb_dev_unregister(rdev); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_unregister_by_device); > > + > > +/** > > + * rpmb_dev_get_drvdata() - driver data getter > > + * @rdev: rpmb device > > + * > > + * Return: driver private data > > + */ > > +void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev) > > +{ > > + return dev_get_drvdata(&rdev->dev); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_get_drvdata); > > + > > +/** > > + * rpmb_dev_set_drvdata() - driver data setter > > + * @rdev: rpmb device > > + * @data: data to store > > + */ > > +void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data) > > +{ > > + dev_set_drvdata(&rdev->dev, data); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_set_drvdata); > > + > > +/** > > + * rpmb_dev_register - register RPMB partition with the RPMB subsystem > > + * @dev: storage device of the rpmb device > > + * @target: RPMB target/region within the physical device > > + * @ops: device specific operations > > + * > > + * Return: a pointer to rpmb device > > + */ > > +struct rpmb_dev *rpmb_dev_register(struct device *dev, u8 target, > > + const struct rpmb_ops *ops) > > +{ > > + struct rpmb_dev *rdev; > > + int id; > > + int ret; > > + > > + if (!dev || !ops) > > + return ERR_PTR(-EINVAL); > > + > > + if (!ops->program_key) > > + return ERR_PTR(-EINVAL); > > + > > + if (!ops->get_capacity) > > + return ERR_PTR(-EINVAL); > > + > > + if (!ops->get_write_count) > > + return ERR_PTR(-EINVAL); > > + > > + if (!ops->write_blocks) > > + return ERR_PTR(-EINVAL); > > + > > + if (!ops->read_blocks) > > + return ERR_PTR(-EINVAL); > > + > > + if (ops->type == RPMB_TYPE_ANY || ops->type > RPMB_TYPE_MAX) > > + return ERR_PTR(-EINVAL); > > + > > + rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); > > + if (!rdev) > > + return ERR_PTR(-ENOMEM); > > + > > + id = ida_simple_get(&rpmb_ida, 0, 0, GFP_KERNEL); > > + if (id < 0) { > > + ret = id; > > + goto exit; > > + } > > + > > + mutex_init(&rdev->lock); > > + rdev->ops = ops; > > + rdev->id = id; > > + rdev->target = target; > > + > > + dev_set_name(&rdev->dev, "rpmb%d", id); > > + rdev->dev.class = &rpmb_class; > > + rdev->dev.parent = dev; > > + ret = device_register(&rdev->dev); > > + if (ret) > > + goto exit; > > + > > + dev_dbg(&rdev->dev, "registered device\n"); > > + > > + return rdev; > > + > > +exit: > > + if (id >= 0) > > + ida_simple_remove(&rpmb_ida, id); > > + kfree(rdev); > > + return ERR_PTR(ret); > > +} > > +EXPORT_SYMBOL_GPL(rpmb_dev_register); > > + > > +static int __init rpmb_init(void) > > +{ > > + ida_init(&rpmb_ida); > > + class_register(&rpmb_class); > > + return 0; > > +} > > + > > +static void __exit rpmb_exit(void) > > +{ > > + class_unregister(&rpmb_class); > > + ida_destroy(&rpmb_ida); > > +} > > + > > +subsys_initcall(rpmb_init); > > +module_exit(rpmb_exit); > > + > > +MODULE_AUTHOR("Intel Corporation"); > > +MODULE_DESCRIPTION("RPMB class"); > > +MODULE_LICENSE("GPL v2"); > > diff --git a/include/linux/rpmb.h b/include/linux/rpmb.h > > new file mode 100644 > > index 000000000000..718ba7c91ecd > > --- /dev/null > > +++ b/include/linux/rpmb.h > > @@ -0,0 +1,163 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ > > +/* > > + * Copyright (C) 2015-2019 Intel Corp. All rights reserved > > + * Copyright (C) 2021 Linaro Ltd > > + */ > > +#ifndef __RPMB_H__ > > +#define __RPMB_H__ > > + > > +#include <linux/types.h> > > +#include <linux/device.h> > > +#include <linux/kref.h> > > +#include <linux/key.h> > > + > > +/** > > + * struct rpmb_ops - RPMB ops to be implemented by underlying block device > > + * > > + * @program_key : program device key (once only op). > > + * @get_capacity : rpmb size in 128K units in for region/target. > > + * @get_write_count: return the device write counter > > + * @write_blocks : write blocks to RPMB device > > + * @read_blocks : read blocks from RPMB device > > + * @block_size : block size in half sectors (1 == 256B) > > + * @wr_cnt_max : maximal number of blocks that can be > > + * written in one access. > > + * @rd_cnt_max : maximal number of blocks that can be > > + * read in one access. > > + * @auth_method : rpmb_auth_method > > + * @dev_id : unique device identifier > > + * @dev_id_len : unique device identifier length > > + */ > > +struct rpmb_ops { > > + int (*program_key)(struct device *dev, u8 target, key_serial_t keyid); > > + int (*get_capacity)(struct device *dev, u8 target); > > + int (*get_write_count)(struct device *dev, u8 target); > > + int (*write_blocks)(struct device *dev, u8 target, key_serial_t keyid, > > + int addr, int count, u8 *data); > > + int (*read_blocks)(struct device *dev, u8 target, > > + int addr, int count, u8 *data); > > + u16 block_size; > > + u16 wr_cnt_max; > > + u16 rd_cnt_max; > > + u16 auth_method; > > + const u8 *dev_id; > > + size_t dev_id_len; > > +}; > > + > > +/** > > + * struct rpmb_dev - device which can support RPMB partition > > + * > > + * @lock : the device lock > > + * @dev : device > > + * @id : device id > > + * @target : RPMB target/region within the physical device > > + * @ops : operation exported by block layer > > + */ > > +struct rpmb_dev { > > + struct mutex lock; /* device serialization lock */ > > + struct device dev; > > + int id; > > + u8 target; > > + const struct rpmb_ops *ops; > > +}; > > + > > +#define to_rpmb_dev(x) container_of((x), struct rpmb_dev, dev) > > + > > +#if IS_ENABLED(CONFIG_RPMB) > > +struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev); > > +void rpmb_dev_put(struct rpmb_dev *rdev); > > +struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent, u8 target); > > +struct rpmb_dev *rpmb_dev_get_by_type(u32 type); > > +struct rpmb_dev *rpmb_dev_register(struct device *dev, u8 target, > > + const struct rpmb_ops *ops); > > +void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev); > > +void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data); > > +int rpmb_dev_unregister(struct rpmb_dev *rdev); > > +int rpmb_dev_unregister_by_device(struct device *dev, u8 target); > > +int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid); > > +int rpmb_get_capacity(struct rpmb_dev *rdev); > > +int rpmb_get_write_count(struct rpmb_dev *rdev); > > +int rpmb_write_blocks(struct rpmb_dev *rdev, key_serial_t keyid, > > + int addr, int count, u8 *data); > > +int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count, u8 *data); > > + > > +#else > > +static inline struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev) > > +{ > > + return NULL; > > +} > > + > > +static inline void rpmb_dev_put(struct rpmb_dev *rdev) { } > > + > > +static inline struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent, > > + u8 target) > > +{ > > + return NULL; > > +} > > + > > +static inline > > +struct rpmb_dev *rpmb_dev_get_by_type(enum rpmb_type type) > > +{ > > + return NULL; > > +} > > + > > +static inline void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev) > > +{ > > + return NULL; > > +} > > + > > +static inline void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data) > > +{ > > +} > > + > > +static inline struct rpmb_dev * > > +rpmb_dev_register(struct device *dev, u8 target, const struct rpmb_ops *ops) > > +{ > > + return NULL; > > +} > > + > > +static inline int rpmb_dev_unregister(struct rpmb_dev *dev) > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_dev_unregister_by_device(struct device *dev, u8 target) > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid) > > +{ > > + return 0; > > +} > > + > > +static inline rpmb_set_key(struct rpmb_dev *rdev, u8 *key, int keylen); > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_get_capacity(struct rpmb_dev *rdev) > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_get_write_count(struct rpmb_dev *rdev) > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_write_blocks(struct rpmb_dev *rdev, int addr, int count, > > + u8 *data) > > +{ > > + return 0; > > +} > > + > > +static inline int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count, > > + u8 *data) > > +{ > > + return 0; > > +} > > + > > +#endif /* CONFIG_RPMB */ > > + > > +#endif /* __RPMB_H__ */ > > -- > > 2.20.1 > > -- Alex Bennée KVM/QEMU Hacker for Linaro