18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#ifndef __KVM_IODEV_H__
48c2ecf20Sopenharmony_ci#define __KVM_IODEV_H__
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/kvm_types.h>
78c2ecf20Sopenharmony_ci#include <linux/errno.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistruct kvm_io_device;
108c2ecf20Sopenharmony_cistruct kvm_vcpu;
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/**
138c2ecf20Sopenharmony_ci * kvm_io_device_ops are called under kvm slots_lock.
148c2ecf20Sopenharmony_ci * read and write handlers return 0 if the transaction has been handled,
158c2ecf20Sopenharmony_ci * or non-zero to have it passed to the next device.
168c2ecf20Sopenharmony_ci **/
178c2ecf20Sopenharmony_cistruct kvm_io_device_ops {
188c2ecf20Sopenharmony_ci	int (*read)(struct kvm_vcpu *vcpu,
198c2ecf20Sopenharmony_ci		    struct kvm_io_device *this,
208c2ecf20Sopenharmony_ci		    gpa_t addr,
218c2ecf20Sopenharmony_ci		    int len,
228c2ecf20Sopenharmony_ci		    void *val);
238c2ecf20Sopenharmony_ci	int (*write)(struct kvm_vcpu *vcpu,
248c2ecf20Sopenharmony_ci		     struct kvm_io_device *this,
258c2ecf20Sopenharmony_ci		     gpa_t addr,
268c2ecf20Sopenharmony_ci		     int len,
278c2ecf20Sopenharmony_ci		     const void *val);
288c2ecf20Sopenharmony_ci	void (*destructor)(struct kvm_io_device *this);
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistruct kvm_io_device {
338c2ecf20Sopenharmony_ci	const struct kvm_io_device_ops *ops;
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic inline void kvm_iodevice_init(struct kvm_io_device *dev,
378c2ecf20Sopenharmony_ci				     const struct kvm_io_device_ops *ops)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	dev->ops = ops;
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic inline int kvm_iodevice_read(struct kvm_vcpu *vcpu,
438c2ecf20Sopenharmony_ci				    struct kvm_io_device *dev, gpa_t addr,
448c2ecf20Sopenharmony_ci				    int l, void *v)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	return dev->ops->read ? dev->ops->read(vcpu, dev, addr, l, v)
478c2ecf20Sopenharmony_ci				: -EOPNOTSUPP;
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic inline int kvm_iodevice_write(struct kvm_vcpu *vcpu,
518c2ecf20Sopenharmony_ci				     struct kvm_io_device *dev, gpa_t addr,
528c2ecf20Sopenharmony_ci				     int l, const void *v)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	return dev->ops->write ? dev->ops->write(vcpu, dev, addr, l, v)
558c2ecf20Sopenharmony_ci				 : -EOPNOTSUPP;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic inline void kvm_iodevice_destructor(struct kvm_io_device *dev)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	if (dev->ops->destructor)
618c2ecf20Sopenharmony_ci		dev->ops->destructor(dev);
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#endif /* __KVM_IODEV_H__ */
65