00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <str.h>
00031 #include <ipc/services.h>
00032 #include <ipc/ns.h>
00033 #include <ipc/devmap.h>
00034 #include <devmap.h>
00035 #include <async.h>
00036 #include <errno.h>
00037 #include <malloc.h>
00038 #include <bool.h>
00039
00040 static int devmap_phone_driver = -1;
00041 static int devmap_phone_client = -1;
00042
00044 int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
00045 {
00046 switch (iface) {
00047 case DEVMAP_DRIVER:
00048 if (devmap_phone_driver >= 0)
00049 return devmap_phone_driver;
00050
00051 if (flags & IPC_FLAG_BLOCKING)
00052 devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP,
00053 DEVMAP_DRIVER, 0);
00054 else
00055 devmap_phone_driver = service_connect(SERVICE_DEVMAP,
00056 DEVMAP_DRIVER, 0);
00057
00058 return devmap_phone_driver;
00059 case DEVMAP_CLIENT:
00060 if (devmap_phone_client >= 0)
00061 return devmap_phone_client;
00062
00063 if (flags & IPC_FLAG_BLOCKING)
00064 devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP,
00065 DEVMAP_CLIENT, 0);
00066 else
00067 devmap_phone_client = service_connect(SERVICE_DEVMAP,
00068 DEVMAP_CLIENT, 0);
00069
00070 return devmap_phone_client;
00071 default:
00072 return -1;
00073 }
00074 }
00075
00076 void devmap_hangup_phone(devmap_interface_t iface)
00077 {
00078 switch (iface) {
00079 case DEVMAP_DRIVER:
00080 if (devmap_phone_driver >= 0) {
00081 async_hangup(devmap_phone_driver);
00082 devmap_phone_driver = -1;
00083 }
00084 break;
00085 case DEVMAP_CLIENT:
00086 if (devmap_phone_client >= 0) {
00087 async_hangup(devmap_phone_client);
00088 devmap_phone_client = -1;
00089 }
00090 break;
00091 default:
00092 break;
00093 }
00094 }
00095
00097 int devmap_driver_register(const char *name, async_client_conn_t conn)
00098 {
00099 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
00100
00101 if (phone < 0)
00102 return phone;
00103
00104 async_serialize_start();
00105
00106 ipc_call_t answer;
00107 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
00108
00109 sysarg_t retval = async_data_write_start(phone, name, str_size(name));
00110 if (retval != EOK) {
00111 async_wait_for(req, NULL);
00112 async_serialize_end();
00113 return -1;
00114 }
00115
00116 async_set_client_connection(conn);
00117
00118 async_connect_to_me(phone, 0, 0, 0, NULL);
00119 async_wait_for(req, &retval);
00120
00121 async_serialize_end();
00122
00123 return retval;
00124 }
00125
00139 int devmap_device_register_with_iface(const char *fqdn,
00140 devmap_handle_t *handle, sysarg_t interface)
00141 {
00142 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
00143
00144 if (phone < 0)
00145 return phone;
00146
00147 async_serialize_start();
00148
00149 ipc_call_t answer;
00150 aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0,
00151 &answer);
00152
00153 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
00154 if (retval != EOK) {
00155 async_wait_for(req, NULL);
00156 async_serialize_end();
00157 return retval;
00158 }
00159
00160 async_wait_for(req, &retval);
00161
00162 async_serialize_end();
00163
00164 if (retval != EOK) {
00165 if (handle != NULL)
00166 *handle = -1;
00167 return retval;
00168 }
00169
00170 if (handle != NULL)
00171 *handle = (devmap_handle_t) IPC_GET_ARG1(answer);
00172
00173 return retval;
00174 }
00175
00182 int devmap_device_register(const char *fqdn, devmap_handle_t *handle)
00183 {
00184 return devmap_device_register_with_iface(fqdn, handle, 0);
00185 }
00186
00187
00188 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags)
00189 {
00190 int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
00191
00192 if (phone < 0)
00193 return phone;
00194
00195 async_serialize_start();
00196
00197 ipc_call_t answer;
00198 aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
00199 &answer);
00200
00201 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
00202 if (retval != EOK) {
00203 async_wait_for(req, NULL);
00204 async_serialize_end();
00205 return retval;
00206 }
00207
00208 async_wait_for(req, &retval);
00209
00210 async_serialize_end();
00211
00212 if (retval != EOK) {
00213 if (handle != NULL)
00214 *handle = (devmap_handle_t) -1;
00215 return retval;
00216 }
00217
00218 if (handle != NULL)
00219 *handle = (devmap_handle_t) IPC_GET_ARG1(answer);
00220
00221 return retval;
00222 }
00223
00224 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags)
00225 {
00226 int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
00227
00228 if (phone < 0)
00229 return phone;
00230
00231 async_serialize_start();
00232
00233 ipc_call_t answer;
00234 aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
00235 &answer);
00236
00237 sysarg_t retval = async_data_write_start(phone, name, str_size(name));
00238 if (retval != EOK) {
00239 async_wait_for(req, NULL);
00240 async_serialize_end();
00241 return retval;
00242 }
00243
00244 async_wait_for(req, &retval);
00245
00246 async_serialize_end();
00247
00248 if (retval != EOK) {
00249 if (handle != NULL)
00250 *handle = (devmap_handle_t) -1;
00251 return retval;
00252 }
00253
00254 if (handle != NULL)
00255 *handle = (devmap_handle_t) IPC_GET_ARG1(answer);
00256
00257 return retval;
00258 }
00259
00260 devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle)
00261 {
00262 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00263
00264 if (phone < 0)
00265 return phone;
00266
00267 sysarg_t type;
00268 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
00269 if (retval != EOK)
00270 return DEV_HANDLE_NONE;
00271
00272 return (devmap_handle_type_t) type;
00273 }
00274
00275 int devmap_device_connect(devmap_handle_t handle, unsigned int flags)
00276 {
00277 int phone;
00278
00279 if (flags & IPC_FLAG_BLOCKING) {
00280 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
00281 DEVMAP_CONNECT_TO_DEVICE, handle);
00282 } else {
00283 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
00284 DEVMAP_CONNECT_TO_DEVICE, handle);
00285 }
00286
00287 return phone;
00288 }
00289
00290 int devmap_null_create(void)
00291 {
00292 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00293
00294 if (phone < 0)
00295 return -1;
00296
00297 sysarg_t null_id;
00298 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
00299 if (retval != EOK)
00300 return -1;
00301
00302 return (int) null_id;
00303 }
00304
00305 void devmap_null_destroy(int null_id)
00306 {
00307 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00308
00309 if (phone < 0)
00310 return;
00311
00312 async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
00313 }
00314
00315 static size_t devmap_count_namespaces_internal(int phone)
00316 {
00317 sysarg_t count;
00318 int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
00319 if (retval != EOK)
00320 return 0;
00321
00322 return count;
00323 }
00324
00325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle)
00326 {
00327 sysarg_t count;
00328 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
00329 if (retval != EOK)
00330 return 0;
00331
00332 return count;
00333 }
00334
00335 size_t devmap_count_namespaces(void)
00336 {
00337 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00338
00339 if (phone < 0)
00340 return 0;
00341
00342 return devmap_count_namespaces_internal(phone);
00343 }
00344
00345 size_t devmap_count_devices(devmap_handle_t ns_handle)
00346 {
00347 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00348
00349 if (phone < 0)
00350 return 0;
00351
00352 return devmap_count_devices_internal(phone, ns_handle);
00353 }
00354
00355 size_t devmap_get_namespaces(dev_desc_t **data)
00356 {
00357 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00358
00359 if (phone < 0)
00360 return 0;
00361
00362
00363 while (true) {
00364 size_t count = devmap_count_namespaces_internal(phone);
00365 if (count == 0)
00366 return 0;
00367
00368 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
00369 if (devs == NULL)
00370 return 0;
00371
00372 async_serialize_start();
00373
00374 ipc_call_t answer;
00375 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
00376
00377 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
00378 if (rc == EOVERFLOW) {
00379
00380
00381
00382
00383 async_serialize_end();
00384 free(devs);
00385 continue;
00386 }
00387
00388 if (rc != EOK) {
00389 async_wait_for(req, NULL);
00390 async_serialize_end();
00391 free(devs);
00392 return 0;
00393 }
00394
00395 sysarg_t retval;
00396 async_wait_for(req, &retval);
00397 async_serialize_end();
00398
00399 if (retval != EOK)
00400 return 0;
00401
00402 *data = devs;
00403 return count;
00404 }
00405 }
00406
00407 size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data)
00408 {
00409 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
00410
00411 if (phone < 0)
00412 return 0;
00413
00414
00415 while (true) {
00416 size_t count = devmap_count_devices_internal(phone, ns_handle);
00417 if (count == 0)
00418 return 0;
00419
00420 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
00421 if (devs == NULL)
00422 return 0;
00423
00424 async_serialize_start();
00425
00426 ipc_call_t answer;
00427 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
00428
00429 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
00430 if (rc == EOVERFLOW) {
00431
00432
00433
00434
00435 async_serialize_end();
00436 free(devs);
00437 continue;
00438 }
00439
00440 if (rc != EOK) {
00441 async_wait_for(req, NULL);
00442 async_serialize_end();
00443 free(devs);
00444 return 0;
00445 }
00446
00447 sysarg_t retval;
00448 async_wait_for(req, &retval);
00449 async_serialize_end();
00450
00451 if (retval != EOK)
00452 return 0;
00453
00454 *data = devs;
00455 return count;
00456 }
00457 }