linux/tools/testing/cxl/test/mock.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2//Copyright(c) 2021 Intel Corporation. All rights reserved.
   3
   4#include <linux/libnvdimm.h>
   5#include <linux/rculist.h>
   6#include <linux/device.h>
   7#include <linux/export.h>
   8#include <linux/acpi.h>
   9#include <linux/pci.h>
  10#include "mock.h"
  11
  12static LIST_HEAD(mock);
  13
  14void register_cxl_mock_ops(struct cxl_mock_ops *ops)
  15{
  16        list_add_rcu(&ops->list, &mock);
  17}
  18EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
  19
  20static DEFINE_SRCU(cxl_mock_srcu);
  21
  22void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
  23{
  24        list_del_rcu(&ops->list);
  25        synchronize_srcu(&cxl_mock_srcu);
  26}
  27EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
  28
  29struct cxl_mock_ops *get_cxl_mock_ops(int *index)
  30{
  31        *index = srcu_read_lock(&cxl_mock_srcu);
  32        return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
  33}
  34EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
  35
  36void put_cxl_mock_ops(int index)
  37{
  38        srcu_read_unlock(&cxl_mock_srcu, index);
  39}
  40EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
  41
  42bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
  43{
  44        struct acpi_device *adev =
  45                container_of(fwnode, struct acpi_device, fwnode);
  46        int index;
  47        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  48        bool retval = false;
  49
  50        if (ops)
  51                retval = ops->is_mock_adev(adev);
  52
  53        if (!retval)
  54                retval = is_acpi_device_node(fwnode);
  55
  56        put_cxl_mock_ops(index);
  57        return retval;
  58}
  59EXPORT_SYMBOL(__wrap_is_acpi_device_node);
  60
  61int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
  62                                 acpi_tbl_entry_handler_arg handler_arg,
  63                                 void *arg)
  64{
  65        int index, rc;
  66        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  67
  68        if (ops)
  69                rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
  70        else
  71                rc = acpi_table_parse_cedt(id, handler_arg, arg);
  72
  73        put_cxl_mock_ops(index);
  74
  75        return rc;
  76}
  77EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI);
  78
  79acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
  80                                         acpi_string pathname,
  81                                         struct acpi_object_list *arguments,
  82                                         unsigned long long *data)
  83{
  84        int index;
  85        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
  86        acpi_status status;
  87
  88        if (ops)
  89                status = ops->acpi_evaluate_integer(handle, pathname, arguments,
  90                                                    data);
  91        else
  92                status = acpi_evaluate_integer(handle, pathname, arguments,
  93                                               data);
  94        put_cxl_mock_ops(index);
  95
  96        return status;
  97}
  98EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
  99
 100struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
 101{
 102        int index;
 103        struct acpi_pci_root *root;
 104        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
 105
 106        if (ops)
 107                root = ops->acpi_pci_find_root(handle);
 108        else
 109                root = acpi_pci_find_root(handle);
 110
 111        put_cxl_mock_ops(index);
 112
 113        return root;
 114}
 115EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
 116
 117void __wrap_pci_walk_bus(struct pci_bus *bus,
 118                         int (*cb)(struct pci_dev *, void *), void *userdata)
 119{
 120        int index;
 121        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
 122
 123        if (ops && ops->is_mock_bus(bus)) {
 124                int rc, i;
 125
 126                /*
 127                 * Simulate 2 root ports per host-bridge and no
 128                 * depth recursion.
 129                 */
 130                for (i = 0; i < 2; i++) {
 131                        rc = cb((struct pci_dev *) ops->mock_port(bus, i),
 132                                userdata);
 133                        if (rc)
 134                                break;
 135                }
 136        } else
 137                pci_walk_bus(bus, cb, userdata);
 138
 139        put_cxl_mock_ops(index);
 140}
 141EXPORT_SYMBOL_GPL(__wrap_pci_walk_bus);
 142
 143struct nvdimm_bus *
 144__wrap_nvdimm_bus_register(struct device *dev,
 145                           struct nvdimm_bus_descriptor *nd_desc)
 146{
 147        int index;
 148        struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
 149
 150        if (ops && ops->is_mock_dev(dev->parent->parent))
 151                nd_desc->provider_name = "cxl_test";
 152        put_cxl_mock_ops(index);
 153
 154        return nvdimm_bus_register(dev, nd_desc);
 155}
 156EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
 157
 158MODULE_LICENSE("GPL v2");
 159MODULE_IMPORT_NS(ACPI);
 160