VFIO updates for v5.1-rc1
- Switch mdev to generic UUID API (Andy Shevchenko) - Fixup platform reset include paths (Masahiro Yamada) - Fix usage of MINORMASK (Chengguang Xu) - Remove noise from duplicate spapr table unsets (Alexey Kardashevskiy) - Restore device state after PM reset (Alex Williamson) - Ensure memory translation enabled for PCI ROM access (Eric Auger) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJccCxQAAoJECObm247sIsiRBwQAIwGszzvz7688BRrbm6y6BA5 z0jptLODKAecSfS/oQlIwNFsGOjfBK51C1u6+AgZbeizn9hCTUEKU8uFBZWmjLJX LjndZa4e3/x177K21FWRlmwON/ECclFbsfmUIrejulvMZMRYP+ruawm1WctQqdai GmNvggjqoP+yk1MHN+riULh+3uSRjQB9kOMFnlwxa8AgTlfUh85jvYe8tdGd04Lh if6ulyIZXHdMZbY0XUKQIUwEsKCHaC/p9E+gyq0dNaLyoXL86bR5iVWackGGBzCx nWvpBtpNIrvBekk5fEWGP3ItfxTIPE1TOuDSktUhQNkJrs1GQXu5K2cnuCECdHu7 3ffNg4E3fhRtv+MzgNxx6tTelWUoZDZodHDFtim4i+FqxpjJnLjO3ztHKf+ZEYOv NB24WAE1uAqDEk28CMj4N/DWu2oBrwk4rfGtNc7SA2WL+CIdRr7aQwjxfXn2R+hx 6kzicR3lsgwHiuw9SmNXlFspqnnNSby1CqauxqdVDbiQC2FDvh5Q8+7PxwvA4ULS 49LKm7vzjiYE9eS4eZyWnmRQV2UwBvEv85HFjktyYGjEMcMtpZk07BjPxkeHCJwl rPYwY+1c16Jk11rfm69xCzztur/WLqTP+GhZ0nU7zOgS2jzWuIL6mURcmf82z433 IDBNyZ2pUWGIWSIU6ZTt =9Ahg -----END PGP SIGNATURE----- Merge tag 'vfio-v5.1-rc1' of git://github.com/awilliam/linux-vfio Pull VFIO updates from Alex Williamson: - Switch mdev to generic UUID API (Andy Shevchenko) - Fixup platform reset include paths (Masahiro Yamada) - Fix usage of MINORMASK (Chengguang Xu) - Remove noise from duplicate spapr table unsets (Alexey Kardashevskiy) - Restore device state after PM reset (Alex Williamson) - Ensure memory translation enabled for PCI ROM access (Eric Auger) * tag 'vfio-v5.1-rc1' of git://github.com/awilliam/linux-vfio: vfio_pci: Enable memory accesses before calling pci_map_rom vfio/pci: Restore device state on PM transition vfio/spapr_tce: Skip unsetting already unset table samples/vfio-mdev/mtty: expand minor range when registering chrdev region samples/vfio-mdev/mdpy: expand minor range when registering chrdev region samples/vfio-mdev/mbochs: expand minor range when registering chrdev region vfio: expand minor range when registering chrdev region vfio: platform: reset: fix up include directives to remove ccflags-y vfio-mdev: Switch to use new generic UUID API
This commit is contained in:
Коммит
a83b04232c
|
@ -60,9 +60,9 @@ struct mdev_device *mdev_from_dev(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(mdev_from_dev);
|
||||
|
||||
uuid_le mdev_uuid(struct mdev_device *mdev)
|
||||
const guid_t *mdev_uuid(struct mdev_device *mdev)
|
||||
{
|
||||
return mdev->uuid;
|
||||
return &mdev->uuid;
|
||||
}
|
||||
EXPORT_SYMBOL(mdev_uuid);
|
||||
|
||||
|
@ -88,8 +88,7 @@ static void mdev_release_parent(struct kref *kref)
|
|||
put_device(dev);
|
||||
}
|
||||
|
||||
static
|
||||
inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent)
|
||||
static inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent)
|
||||
{
|
||||
if (parent)
|
||||
kref_get(&parent->ref);
|
||||
|
@ -276,7 +275,8 @@ static void mdev_device_release(struct device *dev)
|
|||
kfree(mdev);
|
||||
}
|
||||
|
||||
int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
|
||||
int mdev_device_create(struct kobject *kobj,
|
||||
struct device *dev, const guid_t *uuid)
|
||||
{
|
||||
int ret;
|
||||
struct mdev_device *mdev, *tmp;
|
||||
|
@ -291,7 +291,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
|
|||
|
||||
/* Check for duplicate */
|
||||
list_for_each_entry(tmp, &mdev_list, next) {
|
||||
if (!uuid_le_cmp(tmp->uuid, uuid)) {
|
||||
if (guid_equal(&tmp->uuid, uuid)) {
|
||||
mutex_unlock(&mdev_list_lock);
|
||||
ret = -EEXIST;
|
||||
goto mdev_fail;
|
||||
|
@ -305,7 +305,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
|
|||
goto mdev_fail;
|
||||
}
|
||||
|
||||
memcpy(&mdev->uuid, &uuid, sizeof(uuid_le));
|
||||
guid_copy(&mdev->uuid, uuid);
|
||||
list_add(&mdev->next, &mdev_list);
|
||||
mutex_unlock(&mdev_list_lock);
|
||||
|
||||
|
@ -315,7 +315,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
|
|||
mdev->dev.parent = dev;
|
||||
mdev->dev.bus = &mdev_bus_type;
|
||||
mdev->dev.release = mdev_device_release;
|
||||
dev_set_name(&mdev->dev, "%pUl", uuid.b);
|
||||
dev_set_name(&mdev->dev, "%pUl", uuid);
|
||||
|
||||
ret = device_register(&mdev->dev);
|
||||
if (ret) {
|
||||
|
|
|
@ -28,7 +28,7 @@ struct mdev_parent {
|
|||
struct mdev_device {
|
||||
struct device dev;
|
||||
struct mdev_parent *parent;
|
||||
uuid_le uuid;
|
||||
guid_t uuid;
|
||||
void *driver_data;
|
||||
struct kref ref;
|
||||
struct list_head next;
|
||||
|
@ -58,7 +58,8 @@ 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_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid);
|
||||
int mdev_device_create(struct kobject *kobj,
|
||||
struct device *dev, const guid_t *uuid);
|
||||
int mdev_device_remove(struct device *dev, bool force_remove);
|
||||
|
||||
#endif /* MDEV_PRIVATE_H */
|
||||
|
|
|
@ -55,7 +55,7 @@ static ssize_t create_store(struct kobject *kobj, struct device *dev,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
char *str;
|
||||
uuid_le uuid;
|
||||
guid_t uuid;
|
||||
int ret;
|
||||
|
||||
if ((count < UUID_STRING_LEN) || (count > UUID_STRING_LEN + 1))
|
||||
|
@ -65,12 +65,12 @@ static ssize_t create_store(struct kobject *kobj, struct device *dev,
|
|||
if (!str)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = uuid_le_to_bin(str, &uuid);
|
||||
ret = guid_parse(str, &uuid);
|
||||
kfree(str);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mdev_device_create(kobj, dev, uuid);
|
||||
ret = mdev_device_create(kobj, dev, &uuid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -209,6 +209,57 @@ static bool vfio_pci_nointx(struct pci_dev *pdev)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void vfio_pci_probe_power_state(struct vfio_pci_device *vdev)
|
||||
{
|
||||
struct pci_dev *pdev = vdev->pdev;
|
||||
u16 pmcsr;
|
||||
|
||||
if (!pdev->pm_cap)
|
||||
return;
|
||||
|
||||
pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &pmcsr);
|
||||
|
||||
vdev->needs_pm_restore = !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET);
|
||||
}
|
||||
|
||||
/*
|
||||
* pci_set_power_state() wrapper handling devices which perform a soft reset on
|
||||
* D3->D0 transition. Save state prior to D0/1/2->D3, stash it on the vdev,
|
||||
* restore when returned to D0. Saved separately from pci_saved_state for use
|
||||
* by PM capability emulation and separately from pci_dev internal saved state
|
||||
* to avoid it being overwritten and consumed around other resets.
|
||||
*/
|
||||
int vfio_pci_set_power_state(struct vfio_pci_device *vdev, pci_power_t state)
|
||||
{
|
||||
struct pci_dev *pdev = vdev->pdev;
|
||||
bool needs_restore = false, needs_save = false;
|
||||
int ret;
|
||||
|
||||
if (vdev->needs_pm_restore) {
|
||||
if (pdev->current_state < PCI_D3hot && state >= PCI_D3hot) {
|
||||
pci_save_state(pdev);
|
||||
needs_save = true;
|
||||
}
|
||||
|
||||
if (pdev->current_state >= PCI_D3hot && state <= PCI_D0)
|
||||
needs_restore = true;
|
||||
}
|
||||
|
||||
ret = pci_set_power_state(pdev, state);
|
||||
|
||||
if (!ret) {
|
||||
/* D3 might be unsupported via quirk, skip unless in D3 */
|
||||
if (needs_save && pdev->current_state >= PCI_D3hot) {
|
||||
vdev->pm_save = pci_store_saved_state(pdev);
|
||||
} else if (needs_restore) {
|
||||
pci_load_and_free_saved_state(pdev, &vdev->pm_save);
|
||||
pci_restore_state(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfio_pci_enable(struct vfio_pci_device *vdev)
|
||||
{
|
||||
struct pci_dev *pdev = vdev->pdev;
|
||||
|
@ -216,7 +267,7 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
|
|||
u16 cmd;
|
||||
u8 msix_pos;
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
vfio_pci_set_power_state(vdev, PCI_D0);
|
||||
|
||||
/* Don't allow our initial saved state to include busmaster */
|
||||
pci_clear_master(pdev);
|
||||
|
@ -407,7 +458,7 @@ out:
|
|||
vfio_pci_try_bus_reset(vdev);
|
||||
|
||||
if (!disable_idle_d3)
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
vfio_pci_set_power_state(vdev, PCI_D3hot);
|
||||
}
|
||||
|
||||
static void vfio_pci_release(void *device_data)
|
||||
|
@ -708,6 +759,7 @@ static long vfio_pci_ioctl(void *device_data,
|
|||
{
|
||||
void __iomem *io;
|
||||
size_t size;
|
||||
u16 orig_cmd;
|
||||
|
||||
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
|
||||
info.flags = 0;
|
||||
|
@ -723,15 +775,23 @@ static long vfio_pci_ioctl(void *device_data,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Is it really there? */
|
||||
io = pci_map_rom(pdev, &size);
|
||||
if (!io || !size) {
|
||||
info.size = 0;
|
||||
break;
|
||||
}
|
||||
pci_unmap_rom(pdev, io);
|
||||
/*
|
||||
* Is it really there? Enable memory decode for
|
||||
* implicit access in pci_map_rom().
|
||||
*/
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &orig_cmd);
|
||||
pci_write_config_word(pdev, PCI_COMMAND,
|
||||
orig_cmd | PCI_COMMAND_MEMORY);
|
||||
|
||||
info.flags = VFIO_REGION_INFO_FLAG_READ;
|
||||
io = pci_map_rom(pdev, &size);
|
||||
if (io) {
|
||||
info.flags = VFIO_REGION_INFO_FLAG_READ;
|
||||
pci_unmap_rom(pdev, io);
|
||||
} else {
|
||||
info.size = 0;
|
||||
}
|
||||
|
||||
pci_write_config_word(pdev, PCI_COMMAND, orig_cmd);
|
||||
break;
|
||||
}
|
||||
case VFIO_PCI_VGA_REGION_INDEX:
|
||||
|
@ -1286,6 +1346,8 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
vfio_pci_set_vga_decode(vdev, false));
|
||||
}
|
||||
|
||||
vfio_pci_probe_power_state(vdev);
|
||||
|
||||
if (!disable_idle_d3) {
|
||||
/*
|
||||
* pci-core sets the device power state to an unknown value at
|
||||
|
@ -1296,8 +1358,8 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
* be able to get to D3. Therefore first do a D0 transition
|
||||
* before going to D3.
|
||||
*/
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
vfio_pci_set_power_state(vdev, PCI_D0);
|
||||
vfio_pci_set_power_state(vdev, PCI_D3hot);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1316,6 +1378,11 @@ static void vfio_pci_remove(struct pci_dev *pdev)
|
|||
vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev);
|
||||
kfree(vdev->region);
|
||||
mutex_destroy(&vdev->ioeventfds_lock);
|
||||
|
||||
if (!disable_idle_d3)
|
||||
vfio_pci_set_power_state(vdev, PCI_D0);
|
||||
|
||||
kfree(vdev->pm_save);
|
||||
kfree(vdev);
|
||||
|
||||
if (vfio_pci_is_vga(pdev)) {
|
||||
|
@ -1324,9 +1391,6 @@ static void vfio_pci_remove(struct pci_dev *pdev)
|
|||
VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM |
|
||||
VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM);
|
||||
}
|
||||
|
||||
if (!disable_idle_d3)
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
}
|
||||
|
||||
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
|
||||
|
@ -1551,7 +1615,7 @@ put_devs:
|
|||
tmp->needs_reset = false;
|
||||
|
||||
if (tmp != vdev && !disable_idle_d3)
|
||||
pci_set_power_state(tmp->pdev, PCI_D3hot);
|
||||
vfio_pci_set_power_state(tmp, PCI_D3hot);
|
||||
}
|
||||
|
||||
vfio_device_put(devs.devices[i]);
|
||||
|
|
|
@ -691,7 +691,7 @@ static int vfio_pm_config_write(struct vfio_pci_device *vdev, int pos,
|
|||
break;
|
||||
}
|
||||
|
||||
pci_set_power_state(vdev->pdev, state);
|
||||
vfio_pci_set_power_state(vdev, state);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
|
@ -114,7 +114,9 @@ struct vfio_pci_device {
|
|||
bool has_vga;
|
||||
bool needs_reset;
|
||||
bool nointx;
|
||||
bool needs_pm_restore;
|
||||
struct pci_saved_state *pci_saved_state;
|
||||
struct pci_saved_state *pm_save;
|
||||
struct vfio_pci_reflck *reflck;
|
||||
int refcnt;
|
||||
int ioeventfds_nr;
|
||||
|
@ -161,6 +163,10 @@ extern int vfio_pci_register_dev_region(struct vfio_pci_device *vdev,
|
|||
unsigned int type, unsigned int subtype,
|
||||
const struct vfio_pci_regops *ops,
|
||||
size_t size, u32 flags, void *data);
|
||||
|
||||
extern int vfio_pci_set_power_state(struct vfio_pci_device *vdev,
|
||||
pci_power_t state);
|
||||
|
||||
#ifdef CONFIG_VFIO_PCI_IGD
|
||||
extern int vfio_pci_igd_init(struct vfio_pci_device *vdev);
|
||||
#else
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
vfio-platform-calxedaxgmac-y := vfio_platform_calxedaxgmac.o
|
||||
vfio-platform-amdxgbe-y := vfio_platform_amdxgbe.o
|
||||
|
||||
ccflags-y += -Idrivers/vfio/platform
|
||||
|
||||
obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += vfio-platform-calxedaxgmac.o
|
||||
obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o
|
||||
obj-$(CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET) += vfio_platform_bcmflexrm.o
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <uapi/linux/mdio.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "vfio_platform_private.h"
|
||||
#include "../vfio_platform_private.h"
|
||||
|
||||
#define DMA_MR 0x3000
|
||||
#define MAC_VR 0x0110
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "vfio_platform_private.h"
|
||||
#include "../vfio_platform_private.h"
|
||||
|
||||
/* FlexRM configuration */
|
||||
#define RING_REGS_SIZE 0x10000
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "vfio_platform_private.h"
|
||||
#include "../vfio_platform_private.h"
|
||||
|
||||
#define DRIVER_VERSION "0.1"
|
||||
#define DRIVER_AUTHOR "Eric Auger <eric.auger@linaro.org>"
|
||||
|
|
|
@ -2219,12 +2219,12 @@ static int __init vfio_init(void)
|
|||
|
||||
vfio.class->devnode = vfio_devnode;
|
||||
|
||||
ret = alloc_chrdev_region(&vfio.group_devt, 0, MINORMASK, "vfio");
|
||||
ret = alloc_chrdev_region(&vfio.group_devt, 0, MINORMASK + 1, "vfio");
|
||||
if (ret)
|
||||
goto err_alloc_chrdev;
|
||||
|
||||
cdev_init(&vfio.group_cdev, &vfio_group_fops);
|
||||
ret = cdev_add(&vfio.group_cdev, vfio.group_devt, MINORMASK);
|
||||
ret = cdev_add(&vfio.group_cdev, vfio.group_devt, MINORMASK + 1);
|
||||
if (ret)
|
||||
goto err_cdev_add;
|
||||
|
||||
|
@ -2236,7 +2236,7 @@ static int __init vfio_init(void)
|
|||
return 0;
|
||||
|
||||
err_cdev_add:
|
||||
unregister_chrdev_region(vfio.group_devt, MINORMASK);
|
||||
unregister_chrdev_region(vfio.group_devt, MINORMASK + 1);
|
||||
err_alloc_chrdev:
|
||||
class_destroy(vfio.class);
|
||||
vfio.class = NULL;
|
||||
|
@ -2254,7 +2254,7 @@ static void __exit vfio_cleanup(void)
|
|||
#endif
|
||||
idr_destroy(&vfio.group_idr);
|
||||
cdev_del(&vfio.group_cdev);
|
||||
unregister_chrdev_region(vfio.group_devt, MINORMASK);
|
||||
unregister_chrdev_region(vfio.group_devt, MINORMASK + 1);
|
||||
class_destroy(vfio.class);
|
||||
vfio.class = NULL;
|
||||
misc_deregister(&vfio_dev);
|
||||
|
|
|
@ -1235,7 +1235,8 @@ static void tce_iommu_release_ownership_ddw(struct tce_container *container,
|
|||
}
|
||||
|
||||
for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
|
||||
table_group->ops->unset_window(table_group, i);
|
||||
if (container->tables[i])
|
||||
table_group->ops->unset_window(table_group, i);
|
||||
|
||||
table_group->ops->release_ownership(table_group);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ struct mdev_driver {
|
|||
|
||||
extern void *mdev_get_drvdata(struct mdev_device *mdev);
|
||||
extern void mdev_set_drvdata(struct mdev_device *mdev, void *data);
|
||||
extern uuid_le mdev_uuid(struct mdev_device *mdev);
|
||||
extern const guid_t *mdev_uuid(struct mdev_device *mdev);
|
||||
|
||||
extern struct bus_type mdev_bus_type;
|
||||
|
||||
|
|
|
@ -1448,13 +1448,13 @@ static int __init mbochs_dev_init(void)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = alloc_chrdev_region(&mbochs_devt, 0, MINORMASK, MBOCHS_NAME);
|
||||
ret = alloc_chrdev_region(&mbochs_devt, 0, MINORMASK + 1, MBOCHS_NAME);
|
||||
if (ret < 0) {
|
||||
pr_err("Error: failed to register mbochs_dev, err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
cdev_init(&mbochs_cdev, &vd_fops);
|
||||
cdev_add(&mbochs_cdev, mbochs_devt, MINORMASK);
|
||||
cdev_add(&mbochs_cdev, mbochs_devt, MINORMASK + 1);
|
||||
pr_info("%s: major %d\n", __func__, MAJOR(mbochs_devt));
|
||||
|
||||
mbochs_class = class_create(THIS_MODULE, MBOCHS_CLASS_NAME);
|
||||
|
@ -1483,7 +1483,7 @@ failed2:
|
|||
class_destroy(mbochs_class);
|
||||
failed1:
|
||||
cdev_del(&mbochs_cdev);
|
||||
unregister_chrdev_region(mbochs_devt, MINORMASK);
|
||||
unregister_chrdev_region(mbochs_devt, MINORMASK + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1494,7 +1494,7 @@ static void __exit mbochs_dev_exit(void)
|
|||
|
||||
device_unregister(&mbochs_dev);
|
||||
cdev_del(&mbochs_cdev);
|
||||
unregister_chrdev_region(mbochs_devt, MINORMASK);
|
||||
unregister_chrdev_region(mbochs_devt, MINORMASK + 1);
|
||||
class_destroy(mbochs_class);
|
||||
mbochs_class = NULL;
|
||||
}
|
||||
|
|
|
@ -752,13 +752,13 @@ static int __init mdpy_dev_init(void)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = alloc_chrdev_region(&mdpy_devt, 0, MINORMASK, MDPY_NAME);
|
||||
ret = alloc_chrdev_region(&mdpy_devt, 0, MINORMASK + 1, MDPY_NAME);
|
||||
if (ret < 0) {
|
||||
pr_err("Error: failed to register mdpy_dev, err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
cdev_init(&mdpy_cdev, &vd_fops);
|
||||
cdev_add(&mdpy_cdev, mdpy_devt, MINORMASK);
|
||||
cdev_add(&mdpy_cdev, mdpy_devt, MINORMASK + 1);
|
||||
pr_info("%s: major %d\n", __func__, MAJOR(mdpy_devt));
|
||||
|
||||
mdpy_class = class_create(THIS_MODULE, MDPY_CLASS_NAME);
|
||||
|
@ -787,7 +787,7 @@ failed2:
|
|||
class_destroy(mdpy_class);
|
||||
failed1:
|
||||
cdev_del(&mdpy_cdev);
|
||||
unregister_chrdev_region(mdpy_devt, MINORMASK);
|
||||
unregister_chrdev_region(mdpy_devt, MINORMASK + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -798,7 +798,7 @@ static void __exit mdpy_dev_exit(void)
|
|||
|
||||
device_unregister(&mdpy_dev);
|
||||
cdev_del(&mdpy_cdev);
|
||||
unregister_chrdev_region(mdpy_devt, MINORMASK);
|
||||
unregister_chrdev_region(mdpy_devt, MINORMASK + 1);
|
||||
class_destroy(mdpy_class);
|
||||
mdpy_class = NULL;
|
||||
}
|
||||
|
|
|
@ -156,15 +156,15 @@ static const struct file_operations vd_fops = {
|
|||
|
||||
/* function prototypes */
|
||||
|
||||
static int mtty_trigger_interrupt(uuid_le uuid);
|
||||
static int mtty_trigger_interrupt(const guid_t *uuid);
|
||||
|
||||
/* Helper functions */
|
||||
static struct mdev_state *find_mdev_state_by_uuid(uuid_le uuid)
|
||||
static struct mdev_state *find_mdev_state_by_uuid(const guid_t *uuid)
|
||||
{
|
||||
struct mdev_state *mds;
|
||||
|
||||
list_for_each_entry(mds, &mdev_devices_list, next) {
|
||||
if (uuid_le_cmp(mdev_uuid(mds->mdev), uuid) == 0)
|
||||
if (guid_equal(mdev_uuid(mds->mdev), uuid))
|
||||
return mds;
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1032,7 @@ static int mtty_set_irqs(struct mdev_device *mdev, uint32_t flags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mtty_trigger_interrupt(uuid_le uuid)
|
||||
static int mtty_trigger_interrupt(const guid_t *uuid)
|
||||
{
|
||||
int ret = -1;
|
||||
struct mdev_state *mdev_state;
|
||||
|
@ -1442,7 +1442,8 @@ static int __init mtty_dev_init(void)
|
|||
|
||||
idr_init(&mtty_dev.vd_idr);
|
||||
|
||||
ret = alloc_chrdev_region(&mtty_dev.vd_devt, 0, MINORMASK, MTTY_NAME);
|
||||
ret = alloc_chrdev_region(&mtty_dev.vd_devt, 0, MINORMASK + 1,
|
||||
MTTY_NAME);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_err("Error: failed to register mtty_dev, err:%d\n", ret);
|
||||
|
@ -1450,7 +1451,7 @@ static int __init mtty_dev_init(void)
|
|||
}
|
||||
|
||||
cdev_init(&mtty_dev.vd_cdev, &vd_fops);
|
||||
cdev_add(&mtty_dev.vd_cdev, mtty_dev.vd_devt, MINORMASK);
|
||||
cdev_add(&mtty_dev.vd_cdev, mtty_dev.vd_devt, MINORMASK + 1);
|
||||
|
||||
pr_info("major_number:%d\n", MAJOR(mtty_dev.vd_devt));
|
||||
|
||||
|
@ -1487,7 +1488,7 @@ failed2:
|
|||
|
||||
failed1:
|
||||
cdev_del(&mtty_dev.vd_cdev);
|
||||
unregister_chrdev_region(mtty_dev.vd_devt, MINORMASK);
|
||||
unregister_chrdev_region(mtty_dev.vd_devt, MINORMASK + 1);
|
||||
|
||||
all_done:
|
||||
return ret;
|
||||
|
@ -1501,7 +1502,7 @@ static void __exit mtty_dev_exit(void)
|
|||
device_unregister(&mtty_dev.dev);
|
||||
idr_destroy(&mtty_dev.vd_idr);
|
||||
cdev_del(&mtty_dev.vd_cdev);
|
||||
unregister_chrdev_region(mtty_dev.vd_devt, MINORMASK);
|
||||
unregister_chrdev_region(mtty_dev.vd_devt, MINORMASK + 1);
|
||||
class_destroy(mtty_dev.vd_class);
|
||||
mtty_dev.vd_class = NULL;
|
||||
pr_info("mtty_dev: Unloaded!\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче