summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2019-09-21 23:32:41 +0300
committerBin Meng <bmeng.cn@gmail.com>2019-10-11 12:37:15 +0300
commit6498fda140f526f82f87e057afb61ca23904770f (patch)
tree8b23c0194eb4e3b783949ce5c040790c9affe433
parent3d95688c85aa26dea5d98e277d724aff571a1b4e (diff)
downloadu-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.c30
-rw-r--r--include/pci.h20
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