source: mainline/uspace/lib/drv/generic/remote_pci.c@ 63d46341

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 63d46341 was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libdrv
30 * @{
31 */
32/** @file
33 */
34
35#include <assert.h>
36#include <async.h>
37#include <errno.h>
38#include <macros.h>
39
40#include "pci_dev_iface.h"
41#include "ddf/driver.h"
42
43typedef enum {
44 IPC_M_CONFIG_SPACE_READ_8,
45 IPC_M_CONFIG_SPACE_READ_16,
46 IPC_M_CONFIG_SPACE_READ_32,
47
48 IPC_M_CONFIG_SPACE_WRITE_8,
49 IPC_M_CONFIG_SPACE_WRITE_16,
50 IPC_M_CONFIG_SPACE_WRITE_32
51} pci_dev_iface_funcs_t;
52
53errno_t pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
54{
55 sysarg_t res = 0;
56
57 async_exch_t *exch = async_exchange_begin(sess);
58 errno_t rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
59 IPC_M_CONFIG_SPACE_READ_8, address, &res);
60 async_exchange_end(exch);
61
62 *val = (uint8_t) res;
63 return rc;
64}
65
66errno_t pci_config_space_read_16(async_sess_t *sess, uint32_t address,
67 uint16_t *val)
68{
69 sysarg_t res = 0;
70
71 async_exch_t *exch = async_exchange_begin(sess);
72 errno_t rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
73 IPC_M_CONFIG_SPACE_READ_16, address, &res);
74 async_exchange_end(exch);
75
76 *val = (uint16_t) res;
77 return rc;
78}
79
80errno_t pci_config_space_read_32(async_sess_t *sess, uint32_t address,
81 uint32_t *val)
82{
83 sysarg_t res = 0;
84
85 async_exch_t *exch = async_exchange_begin(sess);
86 errno_t rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
87 IPC_M_CONFIG_SPACE_READ_32, address, &res);
88 async_exchange_end(exch);
89
90 *val = (uint32_t) res;
91 return rc;
92}
93
94errno_t pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
95{
96 async_exch_t *exch = async_exchange_begin(sess);
97 errno_t rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
98 IPC_M_CONFIG_SPACE_WRITE_8, address, val);
99 async_exchange_end(exch);
100
101 return rc;
102}
103
104errno_t pci_config_space_write_16(async_sess_t *sess, uint32_t address,
105 uint16_t val)
106{
107 async_exch_t *exch = async_exchange_begin(sess);
108 errno_t rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
109 IPC_M_CONFIG_SPACE_WRITE_16, address, val);
110 async_exchange_end(exch);
111
112 return rc;
113}
114
115errno_t pci_config_space_write_32(async_sess_t *sess, uint32_t address,
116 uint32_t val)
117{
118 async_exch_t *exch = async_exchange_begin(sess);
119 errno_t rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
120 IPC_M_CONFIG_SPACE_WRITE_32, address, val);
121 async_exchange_end(exch);
122
123 return rc;
124}
125
126static void remote_config_space_read_8(ddf_fun_t *, void *, ipc_call_t *);
127static void remote_config_space_read_16(ddf_fun_t *, void *, ipc_call_t *);
128static void remote_config_space_read_32(ddf_fun_t *, void *, ipc_call_t *);
129
130static void remote_config_space_write_8(ddf_fun_t *, void *, ipc_call_t *);
131static void remote_config_space_write_16(ddf_fun_t *, void *, ipc_call_t *);
132static void remote_config_space_write_32(ddf_fun_t *, void *, ipc_call_t *);
133
134/** Remote USB interface operations. */
135static const remote_iface_func_ptr_t remote_pci_iface_ops [] = {
136 [IPC_M_CONFIG_SPACE_READ_8] = remote_config_space_read_8,
137 [IPC_M_CONFIG_SPACE_READ_16] = remote_config_space_read_16,
138 [IPC_M_CONFIG_SPACE_READ_32] = remote_config_space_read_32,
139
140 [IPC_M_CONFIG_SPACE_WRITE_8] = remote_config_space_write_8,
141 [IPC_M_CONFIG_SPACE_WRITE_16] = remote_config_space_write_16,
142 [IPC_M_CONFIG_SPACE_WRITE_32] = remote_config_space_write_32
143};
144
145/** Remote USB interface structure.
146 */
147const remote_iface_t remote_pci_iface = {
148 .method_count = ARRAY_SIZE(remote_pci_iface_ops),
149 .methods = remote_pci_iface_ops
150};
151
152void remote_config_space_read_8(ddf_fun_t *fun, void *iface, ipc_call_t *call)
153{
154 assert(iface);
155 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
156 if (pci_iface->config_space_read_8 == NULL) {
157 async_answer_0(call, ENOTSUP);
158 return;
159 }
160 uint32_t address = DEV_IPC_GET_ARG1(*call);
161 uint8_t value;
162 errno_t ret = pci_iface->config_space_read_8(fun, address, &value);
163 if (ret != EOK) {
164 async_answer_0(call, ret);
165 } else {
166 async_answer_1(call, EOK, value);
167 }
168}
169
170void remote_config_space_read_16(ddf_fun_t *fun, void *iface, ipc_call_t *call)
171{
172 assert(iface);
173 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
174 if (pci_iface->config_space_read_16 == NULL) {
175 async_answer_0(call, ENOTSUP);
176 return;
177 }
178 uint32_t address = DEV_IPC_GET_ARG1(*call);
179 uint16_t value;
180 errno_t ret = pci_iface->config_space_read_16(fun, address, &value);
181 if (ret != EOK) {
182 async_answer_0(call, ret);
183 } else {
184 async_answer_1(call, EOK, value);
185 }
186}
187void remote_config_space_read_32(ddf_fun_t *fun, void *iface, ipc_call_t *call)
188{
189 assert(iface);
190 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
191 if (pci_iface->config_space_read_32 == NULL) {
192 async_answer_0(call, ENOTSUP);
193 return;
194 }
195 uint32_t address = DEV_IPC_GET_ARG1(*call);
196 uint32_t value;
197 errno_t ret = pci_iface->config_space_read_32(fun, address, &value);
198 if (ret != EOK) {
199 async_answer_0(call, ret);
200 } else {
201 async_answer_1(call, EOK, value);
202 }
203}
204
205void remote_config_space_write_8(ddf_fun_t *fun, void *iface, ipc_call_t *call)
206{
207 assert(iface);
208 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
209 if (pci_iface->config_space_write_8 == NULL) {
210 async_answer_0(call, ENOTSUP);
211 return;
212 }
213 uint32_t address = DEV_IPC_GET_ARG1(*call);
214 uint8_t value = DEV_IPC_GET_ARG2(*call);
215 errno_t ret = pci_iface->config_space_write_8(fun, address, value);
216 if (ret != EOK) {
217 async_answer_0(call, ret);
218 } else {
219 async_answer_0(call, EOK);
220 }
221}
222
223void remote_config_space_write_16(ddf_fun_t *fun, void *iface, ipc_call_t *call)
224{
225 assert(iface);
226 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
227 if (pci_iface->config_space_write_16 == NULL) {
228 async_answer_0(call, ENOTSUP);
229 return;
230 }
231 uint32_t address = DEV_IPC_GET_ARG1(*call);
232 uint16_t value = DEV_IPC_GET_ARG2(*call);
233 errno_t ret = pci_iface->config_space_write_16(fun, address, value);
234 if (ret != EOK) {
235 async_answer_0(call, ret);
236 } else {
237 async_answer_0(call, EOK);
238 }
239}
240
241void remote_config_space_write_32(ddf_fun_t *fun, void *iface, ipc_call_t *call)
242{
243 assert(iface);
244 pci_dev_iface_t *pci_iface = (pci_dev_iface_t *)iface;
245 if (pci_iface->config_space_write_32 == NULL) {
246 async_answer_0(call, ENOTSUP);
247 return;
248 }
249 uint32_t address = DEV_IPC_GET_ARG1(*call);
250 uint32_t value = DEV_IPC_GET_ARG2(*call);
251 errno_t ret = pci_iface->config_space_write_32(fun, address, value);
252 if (ret != EOK) {
253 async_answer_0(call, ret);
254 } else {
255 async_answer_0(call, EOK);
256 }
257}
258
259/**
260 * @}
261 */
Note: See TracBrowser for help on using the repository browser.