source: mainline/uspace/srv/drivers/root/root.c@ 924c75e1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 924c75e1 was 924c75e1, checked in by Lenka Trochtova <trochtova.lenka@…>, 15 years ago

backup (unstable)

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2010 Lenka Trochtova
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 * @defgroup root device driver.
31 * @brief HelenOS root device driver.
32 * @{
33 */
34
35/** @file
36 */
37
38#include <assert.h>
39#include <ipc/services.h>
40#include <ipc/ns.h>
41#include <async.h>
42#include <stdio.h>
43#include <errno.h>
44#include <bool.h>
45#include <fibril_synch.h>
46#include <stdlib.h>
47#include <string.h>
48#include <ctype.h>
49
50#include <ipc/devman.h>
51
52
53////////////////////////////////////////
54// rudiments of generic driver support
55// TODO - create library(ies) for this functionality
56////////////////////////////////////////
57
58typedef enum {
59 DRIVER_DEVMAN = 1,
60 DRIVER_CLIENT,
61 DRIVER_DRIVER
62} driver_interface_t;
63
64typedef struct device {
65 int parent_handle;
66 ipcarg_t parent_phone;
67 // TODO add more items - parent bus type etc.
68 int handle;
69} device_t;
70
71typedef struct driver_ops {
72 bool (*add_device)(device_t *dev);
73 // TODO add other generic driver operations
74} driver_ops_t;
75
76typedef struct driver {
77 const char *name;
78 driver_ops_t *driver_ops;
79} driver_t;
80
81
82static driver_t *driver;
83
84
85static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall)
86{
87 /* Accept connection */
88 ipc_answer_0(iid, EOK);
89
90 bool cont = true;
91 while (cont) {
92 ipc_call_t call;
93 ipc_callid_t callid = async_get_call(&call);
94
95 switch (IPC_GET_METHOD(call)) {
96 case IPC_M_PHONE_HUNGUP:
97 cont = false;
98 continue;
99 case DRIVER_ADD_DEVICE:
100 // TODO
101 break;
102 default:
103 if (!(callid & IPC_CALLID_NOTIFICATION))
104 ipc_answer_0(callid, ENOENT);
105 }
106 }
107
108}
109
110static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
111{
112 // TODO later
113}
114
115static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall)
116{
117 // TODO later
118}
119
120
121
122
123/** Function for handling connections to device driver.
124 *
125 */
126static void driver_connection(ipc_callid_t iid, ipc_call_t *icall)
127{
128 ipc_callid_t callid;
129 /* Select interface */
130 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
131 case DRIVER_DEVMAN:
132 // handle PnP events from device manager
133 driver_connection_devman(iid, icall);
134 break;
135 case DRIVER_DRIVER:
136 // handle request from drivers of child devices
137 driver_connection_driver(iid, icall);
138 break;
139 case DRIVER_CLIENT:
140 // handle requests from client applications
141 driver_connection_client(iid, icall);
142 break;
143
144 default:
145 /* No such interface */
146 ipc_answer_0(iid, ENOENT);
147 }
148}
149
150
151// TODO put this to library (like in device mapper)
152static int devman_phone_driver = -1;
153static int devman_phone_client = -1;
154
155int devman_get_phone(devman_interface_t iface, unsigned int flags)
156{
157 switch (iface) {
158 case DEVMAN_DRIVER:
159 if (devman_phone_driver >= 0)
160 return devman_phone_driver;
161
162 if (flags & IPC_FLAG_BLOCKING)
163 devman_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
164 SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
165 else
166 devman_phone_driver = ipc_connect_me_to(PHONE_NS,
167 SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
168
169 return devman_phone_driver;
170 case DEVMAN_CLIENT:
171 if (devman_phone_client >= 0)
172 return devman_phone_client;
173
174 if (flags & IPC_FLAG_BLOCKING)
175 devman_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
176 SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
177 else
178 devman_phone_client = ipc_connect_me_to(PHONE_NS,
179 SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
180
181 return devman_phone_client;
182 default:
183 return -1;
184 }
185}
186
187/** Register new driver with device manager. */
188int devman_driver_register(const char *name, async_client_conn_t conn)
189{
190 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
191
192 if (phone < 0)
193 return phone;
194
195 async_serialize_start();
196
197 ipc_call_t answer;
198 aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
199
200 ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
201 if (retval != EOK) {
202 async_wait_for(req, NULL);
203 async_serialize_end();
204 return -1;
205 }
206
207 async_set_client_connection(conn);
208
209 ipcarg_t callback_phonehash;
210 ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
211 async_wait_for(req, &retval);
212
213 async_serialize_end();
214
215 return retval;
216}
217
218int driver_main(driver_t *drv)
219{
220 // remember driver structure - driver_ops will be called by generic handler for incoming connections
221 driver = drv;
222
223 // register driver by device manager with generic handler for incoming connections
224 devman_driver_register(driver->name, driver_connection);
225
226 async_manager();
227
228 // Never reached
229 return 0;
230
231}
232
233////////////////////////////////////////
234// ROOT driver
235////////////////////////////////////////
236
237#define NAME "root"
238
239static driver_t root_driver;
240
241bool root_add_device(device_t *dev)
242{
243 // TODO
244 return true;
245}
246
247bool root_init(driver_t *drv, const char *name)
248{
249 // TODO initialize driver structure
250
251 return true;
252}
253
254int main(int argc, char *argv[])
255{
256 printf(NAME ": HelenOS root device driver\n");
257 if (!root_init(&root_driver, argv[0])) {
258 printf(NAME ": Error while initializing driver\n");
259 return -1;
260 }
261
262 return driver_main(&root_driver);
263
264}
Note: See TracBrowser for help on using the repository browser.