*/
struct mdev_driver {
const char *name;
- int (*probe) (struct device *dev);
- void (*remove) (struct device *dev);
+ int (*probe) (struct mdev_device *dev);
+ void (*remove) (struct mdev_device *dev);
struct device_driver driver;
};
}
EXPORT_SYMBOL(mdev_parent_dev);
-void *mdev_get_drvdata(struct mdev_device *mdev)
-{
- return mdev->driver_data;
-}
-EXPORT_SYMBOL(mdev_get_drvdata);
-
-void mdev_set_drvdata(struct mdev_device *mdev, void *data)
-{
- mdev->driver_data = data;
-}
-EXPORT_SYMBOL(mdev_set_drvdata);
-
-struct device *mdev_dev(struct mdev_device *mdev)
-{
- return &mdev->dev;
-}
-EXPORT_SYMBOL(mdev_dev);
-
-struct mdev_device *mdev_from_dev(struct device *dev)
-{
- return dev_is_mdev(dev) ? to_mdev_device(dev) : NULL;
-}
-EXPORT_SYMBOL(mdev_from_dev);
-
-const guid_t *mdev_uuid(struct mdev_device *mdev)
-{
- return &mdev->uuid;
-}
-EXPORT_SYMBOL(mdev_uuid);
-
/* Should be called holding parent_list_lock */
static struct mdev_parent *__find_parent_device(struct device *dev)
{
int ret;
type = to_mdev_type(mdev->type_kobj);
- mdev_remove_sysfs_files(&mdev->dev, type);
+ mdev_remove_sysfs_files(mdev, type);
device_del(&mdev->dev);
parent = mdev->parent;
lockdep_assert_held(&parent->unreg_sem);
static int mdev_device_remove_cb(struct device *dev, void *data)
{
- if (dev_is_mdev(dev)) {
- struct mdev_device *mdev;
+ struct mdev_device *mdev = mdev_from_dev(dev);
- mdev = to_mdev_device(dev);
+ if (mdev)
mdev_device_remove_common(mdev);
- }
return 0;
}
if (ret)
goto add_fail;
- ret = mdev_create_sysfs_files(&mdev->dev, type);
+ ret = mdev_create_sysfs_files(mdev, type);
if (ret)
goto sysfs_fail;
return ret;
}
-int mdev_device_remove(struct device *dev)
+int mdev_device_remove(struct mdev_device *mdev)
{
- struct mdev_device *mdev, *tmp;
+ struct mdev_device *tmp;
struct mdev_parent *parent;
- mdev = to_mdev_device(dev);
-
mutex_lock(&mdev_list_lock);
list_for_each_entry(tmp, &mdev_list, next) {
if (tmp == mdev)
return 0;
}
-int mdev_set_iommu_device(struct device *dev, struct device *iommu_device)
-{
- struct mdev_device *mdev = to_mdev_device(dev);
-
- mdev->iommu_device = iommu_device;
-
- return 0;
-}
-EXPORT_SYMBOL(mdev_set_iommu_device);
-
-struct device *mdev_get_iommu_device(struct device *dev)
-{
- struct mdev_device *mdev = to_mdev_device(dev);
-
- return mdev->iommu_device;
-}
-EXPORT_SYMBOL(mdev_get_iommu_device);
-
static int __init mdev_init(void)
{
return mdev_bus_register();
return ret;
if (drv && drv->probe) {
- ret = drv->probe(dev);
+ ret = drv->probe(mdev);
if (ret)
mdev_detach_iommu(mdev);
}
struct mdev_device *mdev = to_mdev_device(dev);
if (drv && drv->remove)
- drv->remove(dev);
+ drv->remove(mdev);
mdev_detach_iommu(mdev);
struct rw_semaphore unreg_sem;
};
-struct mdev_device {
- struct device dev;
- struct mdev_parent *parent;
- guid_t uuid;
- void *driver_data;
- struct list_head next;
- struct kobject *type_kobj;
- struct device *iommu_device;
- bool active;
-};
-
-static inline struct mdev_device *to_mdev_device(struct device *dev)
-{
- return container_of(dev, struct mdev_device, dev);
-}
-#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type)
-
struct mdev_type {
struct kobject kobj;
struct kobject *devices_kobj;
int parent_create_sysfs_files(struct mdev_parent *parent);
void parent_remove_sysfs_files(struct mdev_parent *parent);
-int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type);
-void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type);
+int mdev_create_sysfs_files(struct mdev_device *mdev, struct mdev_type *type);
+void mdev_remove_sysfs_files(struct mdev_device *mdev, struct mdev_type *type);
int mdev_device_create(struct kobject *kobj,
struct device *dev, const guid_t *uuid);
-int mdev_device_remove(struct device *dev);
+int mdev_device_remove(struct mdev_device *dev);
#endif /* MDEV_PRIVATE_H */
static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct mdev_device *mdev = to_mdev_device(dev);
unsigned long val;
if (kstrtoul(buf, 0, &val) < 0)
if (val && device_remove_file_self(dev, attr)) {
int ret;
- ret = mdev_device_remove(dev);
+ ret = mdev_device_remove(mdev);
if (ret)
return ret;
}
NULL,
};
-int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type)
+int mdev_create_sysfs_files(struct mdev_device *mdev, struct mdev_type *type)
{
+ struct kobject *kobj = &mdev->dev.kobj;
int ret;
- ret = sysfs_create_link(type->devices_kobj, &dev->kobj, dev_name(dev));
+ ret = sysfs_create_link(type->devices_kobj, kobj, dev_name(&mdev->dev));
if (ret)
return ret;
- ret = sysfs_create_link(&dev->kobj, &type->kobj, "mdev_type");
+ ret = sysfs_create_link(kobj, &type->kobj, "mdev_type");
if (ret)
goto type_link_failed;
- ret = sysfs_create_files(&dev->kobj, mdev_device_attrs);
+ ret = sysfs_create_files(kobj, mdev_device_attrs);
if (ret)
goto create_files_failed;
return ret;
create_files_failed:
- sysfs_remove_link(&dev->kobj, "mdev_type");
+ sysfs_remove_link(kobj, "mdev_type");
type_link_failed:
- sysfs_remove_link(type->devices_kobj, dev_name(dev));
+ sysfs_remove_link(type->devices_kobj, dev_name(&mdev->dev));
return ret;
}
-void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type)
+void mdev_remove_sysfs_files(struct mdev_device *mdev, struct mdev_type *type)
{
- sysfs_remove_files(&dev->kobj, mdev_device_attrs);
- sysfs_remove_link(&dev->kobj, "mdev_type");
- sysfs_remove_link(type->devices_kobj, dev_name(dev));
+ struct kobject *kobj = &mdev->dev.kobj;
+
+ sysfs_remove_files(kobj, mdev_device_attrs);
+ sysfs_remove_link(kobj, "mdev_type");
+ sysfs_remove_link(type->devices_kobj, dev_name(&mdev->dev));
}
.request = vfio_mdev_request,
};
-static int vfio_mdev_probe(struct device *dev)
+static int vfio_mdev_probe(struct mdev_device *mdev)
{
- struct mdev_device *mdev = to_mdev_device(dev);
struct vfio_device *vdev;
int ret;
return 0;
}
-static void vfio_mdev_remove(struct device *dev)
+static void vfio_mdev_remove(struct mdev_device *mdev)
{
- struct vfio_device *vdev = dev_get_drvdata(dev);
+ struct vfio_device *vdev = dev_get_drvdata(&mdev->dev);
vfio_unregister_group_dev(vdev);
kfree(vdev);
return ret;
}
-static struct device *vfio_mdev_get_iommu_device(struct device *dev)
-{
- struct device *(*fn)(struct device *dev);
- struct device *iommu_device;
-
- fn = symbol_get(mdev_get_iommu_device);
- if (fn) {
- iommu_device = fn(dev);
- symbol_put(mdev_get_iommu_device);
-
- return iommu_device;
- }
-
- return NULL;
-}
-
static int vfio_mdev_attach_domain(struct device *dev, void *data)
{
+ struct mdev_device *mdev = to_mdev_device(dev);
struct iommu_domain *domain = data;
struct device *iommu_device;
- iommu_device = vfio_mdev_get_iommu_device(dev);
+ iommu_device = mdev_get_iommu_device(mdev);
if (iommu_device) {
if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
return iommu_aux_attach_device(domain, iommu_device);
static int vfio_mdev_detach_domain(struct device *dev, void *data)
{
+ struct mdev_device *mdev = to_mdev_device(dev);
struct iommu_domain *domain = data;
struct device *iommu_device;
- iommu_device = vfio_mdev_get_iommu_device(dev);
+ iommu_device = mdev_get_iommu_device(mdev);
if (iommu_device) {
if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
iommu_aux_detach_device(domain, iommu_device);
static int vfio_mdev_iommu_device(struct device *dev, void *data)
{
+ struct mdev_device *mdev = to_mdev_device(dev);
struct device **old = data, *new;
- new = vfio_mdev_get_iommu_device(dev);
+ new = mdev_get_iommu_device(mdev);
if (!new || (*old && *old != new))
return -EINVAL;
#ifndef MDEV_H
#define MDEV_H
-struct mdev_device;
+struct mdev_device {
+ struct device dev;
+ struct mdev_parent *parent;
+ guid_t uuid;
+ void *driver_data;
+ struct list_head next;
+ struct kobject *type_kobj;
+ struct device *iommu_device;
+ bool active;
+};
+
+static inline struct mdev_device *to_mdev_device(struct device *dev)
+{
+ return container_of(dev, struct mdev_device, dev);
+}
/*
* Called by the parent device driver to set the device which represents
*
* @dev: the mediated device that iommu will isolate.
* @iommu_device: a pci device which represents the iommu for @dev.
- *
- * Return 0 for success, otherwise negative error value.
*/
-int mdev_set_iommu_device(struct device *dev, struct device *iommu_device);
+static inline void mdev_set_iommu_device(struct mdev_device *mdev,
+ struct device *iommu_device)
+{
+ mdev->iommu_device = iommu_device;
+}
-struct device *mdev_get_iommu_device(struct device *dev);
+static inline struct device *mdev_get_iommu_device(struct mdev_device *mdev)
+{
+ return mdev->iommu_device;
+}
/**
* struct mdev_parent_ops - Structure to be registered for each parent device to
**/
struct mdev_driver {
const char *name;
- int (*probe)(struct device *dev);
- void (*remove)(struct device *dev);
+ int (*probe)(struct mdev_device *dev);
+ void (*remove)(struct mdev_device *dev);
struct device_driver driver;
};
#define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver)
-void *mdev_get_drvdata(struct mdev_device *mdev);
-void mdev_set_drvdata(struct mdev_device *mdev, void *data);
-const guid_t *mdev_uuid(struct mdev_device *mdev);
+static inline void *mdev_get_drvdata(struct mdev_device *mdev)
+{
+ return mdev->driver_data;
+}
+static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data)
+{
+ mdev->driver_data = data;
+}
+static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
+{
+ return &mdev->uuid;
+}
extern struct bus_type mdev_bus_type;
void mdev_unregister_driver(struct mdev_driver *drv);
struct device *mdev_parent_dev(struct mdev_device *mdev);
-struct device *mdev_dev(struct mdev_device *mdev);
-struct mdev_device *mdev_from_dev(struct device *dev);
+static inline struct device *mdev_dev(struct mdev_device *mdev)
+{
+ return &mdev->dev;
+}
+static inline struct mdev_device *mdev_from_dev(struct device *dev)
+{
+ return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL;
+}
#endif /* MDEV_H */