diff options
author | Simon Glass <sjg@chromium.org> | 2019-09-21 23:32:41 +0300 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2019-10-11 12:37:15 +0300 |
commit | 6498fda140f526f82f87e057afb61ca23904770f (patch) | |
tree | 8b23c0194eb4e3b783949ce5c040790c9affe433 | |
parent | 3d95688c85aa26dea5d98e277d724aff571a1b4e (diff) | |
download | u-boot-6498fda140f526f82f87e057afb61ca23904770f.tar.xz |
sandbox: pci: Remember the device being emulated
Add a field to the PCI emulator per-device data which records which device
is being emulated. This is useful when the emulator needs to check the
device for something.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
[bmeng: rebase the patch against u-boot-x86/master to get it applied cleanly]
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r-- | drivers/pci/pci-emul-uclass.c | 30 | ||||
-rw-r--r-- | include/pci.h | 20 |
2 files changed, 44 insertions, 6 deletions
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c index 0dcf937d9a..0f63e491a7 100644 --- a/drivers/pci/pci-emul-uclass.c +++ b/drivers/pci/pci-emul-uclass.c @@ -18,6 +18,7 @@ struct sandbox_pci_emul_priv { int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, struct udevice **containerp, struct udevice **emulp) { + struct pci_emul_uc_priv *upriv; struct udevice *dev; int ret; @@ -30,16 +31,32 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, } *containerp = dev; - /* - * See commit 4345998ae9df, - * "pci: sandbox: Support dynamically binding device driver" - */ ret = uclass_get_device_by_phandle(UCLASS_PCI_EMUL, dev, "sandbox,emul", emulp); - if (ret && device_get_uclass_id(dev) != UCLASS_PCI_GENERIC) + if (!ret) { + upriv = dev_get_uclass_priv(*emulp); + + upriv->client = dev; + } else if (device_get_uclass_id(dev) != UCLASS_PCI_GENERIC) { + /* + * See commit 4345998ae9df, + * "pci: sandbox: Support dynamically binding device driver" + */ *emulp = dev; + } + + return 0; +} - return *emulp ? 0 : -ENODEV; +int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp) +{ + struct pci_emul_uc_priv *upriv = dev_get_uclass_priv(emul); + + if (!upriv->client) + return -ENOENT; + *devp = upriv->client; + + return 0; } uint sandbox_pci_read_bar(u32 barval, int type, uint size) @@ -88,6 +105,7 @@ UCLASS_DRIVER(pci_emul) = { .post_probe = sandbox_pci_emul_post_probe, .pre_remove = sandbox_pci_emul_pre_remove, .priv_auto_alloc_size = sizeof(struct sandbox_pci_emul_priv), + .per_device_auto_alloc_size = sizeof(struct pci_emul_uc_priv), }; /* diff --git a/include/pci.h b/include/pci.h index 8aa6636cfb..ff59ac0e69 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1491,6 +1491,17 @@ int dm_pci_find_device(unsigned int vendor, unsigned int device, int index, int dm_pci_find_class(uint find_class, int index, struct udevice **devp); /** + * struct pci_emul_uc_priv - holds info about an emulator device + * + * There is always at most one emulator per client + * + * @client: Client device if any, else NULL + */ +struct pci_emul_uc_priv { + struct udevice *client; +}; + +/** * struct dm_pci_emul_ops - PCI device emulator operations */ struct dm_pci_emul_ops { @@ -1593,6 +1604,15 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, struct udevice **containerp, struct udevice **emulp); /** + * sandbox_pci_get_client() - Find the client for an emulation device + * + * @emul: Emulation device to check + * @devp: Returns the client device emulated by this device + * @return 0 if OK, -ENOENT if the device has no client yet + */ +int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp); + +/** * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device * * Get devfn from fdt_pci_addr of the specified device |