source: mainline/uspace/drv/bus/pci/pciintel/ctl.c

Last change on this file was fafb8e5, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 6 years ago

Mechanically lowercase IPC_SET_*/IPC_GET_*

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2019 Jiri Svoboda
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/**
30 * @addtogroup pciintel
31 * @{
32 */
33
34/** @file
35 */
36
37#include <async.h>
38#include <ddf/log.h>
39#include <ipc/pci.h>
40#include <macros.h>
41#include <types/pci.h>
42#include "ctl.h"
43#include "pci.h"
44
45static void pci_ctl_get_devices_srv(pci_bus_t *, ipc_call_t *);
46static void pci_ctl_dev_get_info_srv(pci_bus_t *, ipc_call_t *);
47static errno_t pci_ctl_get_devices(pci_bus_t *, devman_handle_t *, size_t,
48 size_t *);
49static errno_t pci_ctl_dev_get_info(pci_fun_t *, pci_dev_info_t *);
50
51/** Handle control service connection */
52void pci_ctl_connection(ipc_call_t *icall, void *arg)
53{
54 ipc_call_t call;
55 pci_bus_t *bus;
56
57 /*
58 * Answer the first IPC_M_CONNECT_ME_TO call.
59 */
60 async_accept_0(icall);
61
62 bus = pci_bus(ddf_fun_get_dev((ddf_fun_t *) arg));
63
64 while (true) {
65 async_get_call(&call);
66
67 if (!ipc_get_imethod(&call))
68 break;
69
70 switch (ipc_get_imethod(&call)) {
71 case PCI_GET_DEVICES:
72 pci_ctl_get_devices_srv(bus, &call);
73 break;
74 case PCI_DEV_GET_INFO:
75 pci_ctl_dev_get_info_srv(bus, &call);
76 break;
77 default:
78 async_answer_0(&call, EINVAL);
79 break;
80 }
81 }
82}
83
84/** Handle request to get list of PCI devices.
85 *
86 * @param bus PCI bus
87 * @param call Async request
88 */
89static void pci_ctl_get_devices_srv(pci_bus_t *bus, ipc_call_t *icall)
90{
91 ipc_call_t call;
92 size_t size;
93 size_t act_size;
94 devman_handle_t *buf;
95 errno_t rc;
96
97 if (!async_data_read_receive(&call, &size)) {
98 async_answer_0(&call, EREFUSED);
99 async_answer_0(icall, EREFUSED);
100 return;
101 }
102
103 if ((size % sizeof(devman_handle_t)) != 0) {
104 async_answer_0(&call, EINVAL);
105 async_answer_0(icall, EINVAL);
106 return;
107 }
108
109 buf = malloc(max(1, size));
110 if (buf == NULL) {
111 async_answer_0(&call, ENOMEM);
112 async_answer_0(icall, ENOMEM);
113 return;
114 }
115
116 rc = pci_ctl_get_devices(bus, buf, size, &act_size);
117 if (rc != EOK) {
118 free(buf);
119 async_answer_0(&call, rc);
120 async_answer_0(icall, rc);
121 return;
122 }
123
124 errno_t retval = async_data_read_finalize(&call, buf, size);
125
126 free(buf);
127 async_answer_1(icall, retval, act_size);
128}
129
130/** Handle request to get PCI device information.
131 *
132 * @param bus PCI bus
133 * @param call Async request
134 */
135static void pci_ctl_dev_get_info_srv(pci_bus_t *bus, ipc_call_t *icall)
136{
137 devman_handle_t dev_handle;
138 pci_fun_t *fun;
139 pci_dev_info_t info;
140 errno_t rc;
141
142 dev_handle = ipc_get_arg1(icall);
143 log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv(%zu)",
144 dev_handle);
145 fun = pci_fun_first(bus);
146 while (fun != NULL) {
147 if (ddf_fun_get_handle(fun->fnode) == dev_handle)
148 break;
149
150 fun = pci_fun_next(fun);
151 }
152
153 if (fun == NULL) {
154 log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
155 "device %zu not found", dev_handle);
156 async_answer_0(icall, ENOENT);
157 return;
158 }
159
160 log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
161 "vol_volume_get_info");
162 rc = pci_ctl_dev_get_info(fun, &info);
163 if (rc != EOK) {
164 async_answer_0(icall, EIO);
165 return;
166 }
167
168 ipc_call_t call;
169 size_t size;
170 if (!async_data_read_receive(&call, &size)) {
171 async_answer_0(&call, EREFUSED);
172 async_answer_0(icall, EREFUSED);
173 return;
174 }
175
176 if (size != sizeof(pci_dev_info_t)) {
177 async_answer_0(&call, EINVAL);
178 async_answer_0(icall, EINVAL);
179 return;
180 }
181
182 rc = async_data_read_finalize(&call, &info,
183 min(size, sizeof(info)));
184 if (rc != EOK) {
185 async_answer_0(&call, rc);
186 async_answer_0(icall, rc);
187 return;
188 }
189
190 async_answer_0(icall, EOK);
191}
192
193/** Get list of PCI devices.
194 *
195 * @param bus PCI bus
196 * @param call Async request
197 */
198static errno_t pci_ctl_get_devices(pci_bus_t *bus, devman_handle_t *id_buf,
199 size_t size, size_t *act_size)
200{
201 pci_fun_t *fun;
202 size_t cnt;
203
204 ddf_msg(LVL_NOTE, "pci_ctl_get_devices(%p, %p, %zu, %p)\n",
205 bus, id_buf, size, act_size);
206
207 fun = pci_fun_first(bus);
208 cnt = 0;
209 while (fun != NULL) {
210 if (sizeof(devman_handle_t) * cnt < size)
211 id_buf[cnt] = ddf_fun_get_handle(fun->fnode);
212 ++cnt;
213 fun = pci_fun_next(fun);
214 }
215
216 *act_size = sizeof(devman_handle_t) * cnt;
217 return EOK;
218}
219
220/** Get PCI device information.
221 *
222 * @param fun PCI function
223 * @param info Place to store information
224 *
225 * @return EOK on success or an error code
226 */
227static errno_t pci_ctl_dev_get_info(pci_fun_t *fun, pci_dev_info_t *info)
228{
229 info->dev_handle = ddf_fun_get_handle(fun->fnode);
230 info->bus_num = fun->bus;
231 info->dev_num = fun->dev;
232 info->fn_num = fun->fn;
233 info->vendor_id = fun->vendor_id;
234 info->device_id = fun->device_id;
235 return EOK;
236}
237
238/**
239 * @}
240 */
Note: See TracBrowser for help on using the repository browser.