Add missing calls to refcount_init()
[helenos.git] / uspace / lib / drv / generic / remote_pci.c
blob60ce7faabeec8b83f734428c9fbd1c942700abff
1 /*
2 * Copyright (c) 2011 Jan Vesely
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
29 /** @addtogroup libdrv
30 * @{
32 /** @file
35 #include <assert.h>
36 #include <async.h>
37 #include <errno.h>
38 #include <macros.h>
40 #include "pci_dev_iface.h"
41 #include "ddf/driver.h"
43 typedef enum {
44 IPC_M_CONFIG_SPACE_READ_8,
45 IPC_M_CONFIG_SPACE_READ_16,
46 IPC_M_CONFIG_SPACE_READ_32,
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;
53 errno_t pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
55 sysarg_t res = 0;
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);
62 *val = (uint8_t) res;
63 return rc;
66 errno_t pci_config_space_read_16(async_sess_t *sess, uint32_t address,
67 uint16_t *val)
69 sysarg_t res = 0;
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);
76 *val = (uint16_t) res;
77 return rc;
80 errno_t pci_config_space_read_32(async_sess_t *sess, uint32_t address,
81 uint32_t *val)
83 sysarg_t res = 0;
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);
90 *val = (uint32_t) res;
91 return rc;
94 errno_t pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
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);
101 return rc;
104 errno_t pci_config_space_write_16(async_sess_t *sess, uint32_t address,
105 uint16_t val)
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);
112 return rc;
115 errno_t pci_config_space_write_32(async_sess_t *sess, uint32_t address,
116 uint32_t val)
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);
123 return rc;
126 static void remote_config_space_read_8(ddf_fun_t *, void *, ipc_call_t *);
127 static void remote_config_space_read_16(ddf_fun_t *, void *, ipc_call_t *);
128 static void remote_config_space_read_32(ddf_fun_t *, void *, ipc_call_t *);
130 static void remote_config_space_write_8(ddf_fun_t *, void *, ipc_call_t *);
131 static void remote_config_space_write_16(ddf_fun_t *, void *, ipc_call_t *);
132 static void remote_config_space_write_32(ddf_fun_t *, void *, ipc_call_t *);
134 /** Remote USB interface operations. */
135 static 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,
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
145 /** Remote USB interface structure.
147 const remote_iface_t remote_pci_iface = {
148 .method_count = ARRAY_SIZE(remote_pci_iface_ops),
149 .methods = remote_pci_iface_ops
152 void remote_config_space_read_8(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
170 void remote_config_space_read_16(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
187 void remote_config_space_read_32(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
205 void remote_config_space_write_8(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
223 void remote_config_space_write_16(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
241 void remote_config_space_write_32(ddf_fun_t *fun, void *iface, ipc_call_t *call)
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;
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);
260 * @}