1
2
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
128
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