source: mainline/uspace/lib/drv/generic/remote_hw_res.c@ eec201d

Last change on this file since eec201d 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: 5.4 KB
Line 
1/*
2 * Copyright (c) 2010 Lenka Trochtova
3 * Copyright (c) 2011 Jan Vesely
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libdrv
31 * @{
32 */
33/** @file
34 */
35
36#include <async.h>
37#include <errno.h>
38#include <macros.h>
39
40#include "ops/hw_res.h"
41#include "ddf/driver.h"
42
43static void remote_hw_res_get_resource_list(ddf_fun_t *, void *, ipc_call_t *);
44static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_call_t *);
45static void remote_hw_res_disable_interrupt(ddf_fun_t *, void *, ipc_call_t *);
46static void remote_hw_res_clear_interrupt(ddf_fun_t *, void *, ipc_call_t *);
47static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_call_t *);
48static void remote_hw_res_dma_channel_remain(ddf_fun_t *, void *, ipc_call_t *);
49
50static const remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
51 [HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
52 [HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
53 [HW_RES_DISABLE_INTERRUPT] = &remote_hw_res_disable_interrupt,
54 [HW_RES_CLEAR_INTERRUPT] = &remote_hw_res_clear_interrupt,
55 [HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
56 [HW_RES_DMA_CHANNEL_REMAIN] = &remote_hw_res_dma_channel_remain,
57};
58
59const remote_iface_t remote_hw_res_iface = {
60 .method_count = ARRAY_SIZE(remote_hw_res_iface_ops),
61 .methods = remote_hw_res_iface_ops
62};
63
64static void remote_hw_res_enable_interrupt(ddf_fun_t *fun, void *ops,
65 ipc_call_t *call)
66{
67 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
68
69 if (hw_res_ops->enable_interrupt == NULL) {
70 async_answer_0(call, ENOTSUP);
71 return;
72 }
73
74 const int irq = DEV_IPC_GET_ARG1(*call);
75 const errno_t ret = hw_res_ops->enable_interrupt(fun, irq);
76 async_answer_0(call, ret);
77}
78
79static void remote_hw_res_disable_interrupt(ddf_fun_t *fun, void *ops,
80 ipc_call_t *call)
81{
82 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
83
84 if (hw_res_ops->disable_interrupt == NULL) {
85 async_answer_0(call, ENOTSUP);
86 return;
87 }
88
89 const int irq = DEV_IPC_GET_ARG1(*call);
90 const errno_t ret = hw_res_ops->disable_interrupt(fun, irq);
91 async_answer_0(call, ret);
92}
93
94static void remote_hw_res_clear_interrupt(ddf_fun_t *fun, void *ops,
95 ipc_call_t *call)
96{
97 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
98
99 if (hw_res_ops->clear_interrupt == NULL) {
100 async_answer_0(call, ENOTSUP);
101 return;
102 }
103
104 const int irq = DEV_IPC_GET_ARG1(*call);
105 const errno_t ret = hw_res_ops->enable_interrupt(fun, irq);
106 async_answer_0(call, ret);
107}
108
109static void remote_hw_res_get_resource_list(ddf_fun_t *fun, void *ops,
110 ipc_call_t *call)
111{
112 hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
113
114 if (hw_res_ops->get_resource_list == NULL) {
115 async_answer_0(call, ENOTSUP);
116 return;
117 }
118
119 hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(fun);
120 if (hw_resources == NULL) {
121 async_answer_0(call, ENOENT);
122 return;
123 }
124
125 async_answer_1(call, EOK, hw_resources->count);
126
127 ipc_call_t data;
128 size_t len;
129 if (!async_data_read_receive(&data, &len)) {
130 /* Protocol error - the recipient is not accepting data */
131 return;
132 }
133
134 async_data_read_finalize(&data, hw_resources->resources, len);
135}
136
137static void remote_hw_res_dma_channel_setup(ddf_fun_t *fun, void *ops,
138 ipc_call_t *call)
139{
140 hw_res_ops_t *hw_res_ops = ops;
141
142 if (hw_res_ops->dma_channel_setup == NULL) {
143 async_answer_0(call, ENOTSUP);
144 return;
145 }
146
147 const unsigned channel = DEV_IPC_GET_ARG1(*call) & 0xffff;
148 const uint8_t mode = DEV_IPC_GET_ARG1(*call) >> 16;
149 const uint32_t address = DEV_IPC_GET_ARG2(*call);
150 const uint32_t size = DEV_IPC_GET_ARG3(*call);
151
152 const errno_t ret = hw_res_ops->dma_channel_setup(
153 fun, channel, address, size, mode);
154 async_answer_0(call, ret);
155}
156
157static void remote_hw_res_dma_channel_remain(ddf_fun_t *fun, void *ops,
158 ipc_call_t *call)
159{
160 hw_res_ops_t *hw_res_ops = ops;
161
162 if (hw_res_ops->dma_channel_setup == NULL) {
163 async_answer_0(call, ENOTSUP);
164 return;
165 }
166
167 const unsigned channel = DEV_IPC_GET_ARG1(*call);
168 size_t remain = 0;
169 const errno_t ret = hw_res_ops->dma_channel_remain(fun, channel, &remain);
170 async_answer_1(call, ret, remain);
171}
172
173/**
174 * @}
175 */
Note: See TracBrowser for help on using the repository browser.