Changes in uspace/srv/fs/devfs/devfs_ops.c [cfd630af:0143f72] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
rcfd630af r0143f72 36 36 */ 37 37 38 #include < macros.h>38 #include <ipc/ipc.h> 39 39 #include <bool.h> 40 40 #include <errno.h> 41 41 #include <malloc.h> 42 #include <str .h>42 #include <string.h> 43 43 #include <libfs.h> 44 #include <fibril_sync h.h>44 #include <fibril_sync.h> 45 45 #include <adt/hash_table.h> 46 #include <ipc/devmap.h>47 46 #include <sys/stat.h> 48 #include <libfs.h>49 #include <assert.h>50 47 #include "devfs.h" 51 48 #include "devfs_ops.h" 52 49 53 typedef struct { 54 devmap_handle_type_t type; 55 devmap_handle_t handle; 56 } devfs_node_t; 50 #define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE]) 57 51 58 52 /** Opened devices structure */ 59 53 typedef struct { 60 dev map_handle_t handle;61 int phone; /**< When < 0, the structure is incomplete. */54 dev_handle_t handle; 55 int phone; 62 56 size_t refcount; 63 57 link_t link; 64 fibril_condvar_t cv; /**< Broadcast when completed. */65 58 } device_t; 66 59 … … 84 77 { 85 78 device_t *dev = hash_table_get_instance(item, device_t, link); 86 return (dev->handle == (dev map_handle_t) key[DEVICES_KEY_HANDLE]);79 return (dev->handle == (dev_handle_t) key[DEVICES_KEY_HANDLE]); 87 80 } 88 81 … … 98 91 }; 99 92 100 static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type,101 devmap_handle_t handle)102 {103 devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t));104 if (node == NULL) {105 *rfn = NULL;106 return ENOMEM;107 }108 109 *rfn = (fs_node_t *) malloc(sizeof(fs_node_t));110 if (*rfn == NULL) {111 free(node);112 *rfn = NULL;113 return ENOMEM;114 }115 116 fs_node_initialize(*rfn);117 node->type = type;118 node->handle = handle;119 120 (*rfn)->data = node;121 return EOK;122 }123 124 static int devfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)125 {126 return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0);127 }128 129 static int devfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)130 {131 devfs_node_t *node = (devfs_node_t *) pfn->data;132 int ret;133 134 if (node->handle == 0) {135 /* Root directory */136 137 dev_desc_t *devs;138 size_t count = devmap_get_namespaces(&devs);139 140 if (count > 0) {141 size_t pos;142 for (pos = 0; pos < count; pos++) {143 /* Ignore root namespace */144 if (str_cmp(devs[pos].name, "") == 0)145 continue;146 147 if (str_cmp(devs[pos].name, component) == 0) {148 ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);149 free(devs);150 return ret;151 }152 }153 154 free(devs);155 }156 157 /* Search root namespace */158 devmap_handle_t namespace;159 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {160 count = devmap_get_devices(namespace, &devs);161 162 if (count > 0) {163 size_t pos;164 for (pos = 0; pos < count; pos++) {165 if (str_cmp(devs[pos].name, component) == 0) {166 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);167 free(devs);168 return ret;169 }170 }171 172 free(devs);173 }174 }175 176 *rfn = NULL;177 return EOK;178 }179 180 if (node->type == DEV_HANDLE_NAMESPACE) {181 /* Namespace directory */182 183 dev_desc_t *devs;184 size_t count = devmap_get_devices(node->handle, &devs);185 if (count > 0) {186 size_t pos;187 for (pos = 0; pos < count; pos++) {188 if (str_cmp(devs[pos].name, component) == 0) {189 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);190 free(devs);191 return ret;192 }193 }194 195 free(devs);196 }197 198 *rfn = NULL;199 return EOK;200 }201 202 *rfn = NULL;203 return EOK;204 }205 206 static int devfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)207 {208 return devfs_node_get_internal(rfn, devmap_handle_probe(index), index);209 }210 211 static int devfs_node_open(fs_node_t *fn)212 {213 devfs_node_t *node = (devfs_node_t *) fn->data;214 215 if (node->handle == 0) {216 /* Root directory */217 return EOK;218 }219 220 devmap_handle_type_t type = devmap_handle_probe(node->handle);221 222 if (type == DEV_HANDLE_NAMESPACE) {223 /* Namespace directory */224 return EOK;225 }226 227 if (type == DEV_HANDLE_DEVICE) {228 /* Device node */229 230 unsigned long key[] = {231 [DEVICES_KEY_HANDLE] = (unsigned long) node->handle232 };233 link_t *lnk;234 235 fibril_mutex_lock(&devices_mutex);236 restart:237 lnk = hash_table_find(&devices, key);238 if (lnk == NULL) {239 device_t *dev = (device_t *) malloc(sizeof(device_t));240 if (dev == NULL) {241 fibril_mutex_unlock(&devices_mutex);242 return ENOMEM;243 }244 245 dev->handle = node->handle;246 dev->phone = -1; /* mark as incomplete */247 dev->refcount = 1;248 fibril_condvar_initialize(&dev->cv);249 250 /*251 * Insert the incomplete device structure so that other252 * fibrils will not race with us when we drop the mutex253 * below.254 */255 hash_table_insert(&devices, key, &dev->link);256 257 /*258 * Drop the mutex to allow recursive devfs requests.259 */260 fibril_mutex_unlock(&devices_mutex);261 262 int phone = devmap_device_connect(node->handle, 0);263 264 fibril_mutex_lock(&devices_mutex);265 266 /*267 * Notify possible waiters about this device structure268 * being completed (or destroyed).269 */270 fibril_condvar_broadcast(&dev->cv);271 272 if (phone < 0) {273 /*274 * Connecting failed, need to remove the275 * entry and free the device structure.276 */277 hash_table_remove(&devices, key, DEVICES_KEYS);278 fibril_mutex_unlock(&devices_mutex);279 280 return ENOENT;281 }282 283 /* Set the correct phone. */284 dev->phone = phone;285 } else {286 device_t *dev = hash_table_get_instance(lnk, device_t, link);287 288 if (dev->phone < 0) {289 /*290 * Wait until the device structure is completed291 * and start from the beginning as the device292 * structure might have entirely disappeared293 * while we were not holding the mutex in294 * fibril_condvar_wait().295 */296 fibril_condvar_wait(&dev->cv, &devices_mutex);297 goto restart;298 }299 300 dev->refcount++;301 }302 303 fibril_mutex_unlock(&devices_mutex);304 305 return EOK;306 }307 308 return ENOENT;309 }310 311 static int devfs_node_put(fs_node_t *fn)312 {313 free(fn->data);314 free(fn);315 return EOK;316 }317 318 static int devfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)319 {320 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));321 322 *rfn = NULL;323 return ENOTSUP;324 }325 326 static int devfs_destroy_node(fs_node_t *fn)327 {328 return ENOTSUP;329 }330 331 static int devfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)332 {333 return ENOTSUP;334 }335 336 static int devfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)337 {338 return ENOTSUP;339 }340 341 static int devfs_has_children(bool *has_children, fs_node_t *fn)342 {343 devfs_node_t *node = (devfs_node_t *) fn->data;344 345 if (node->handle == 0) {346 size_t count = devmap_count_namespaces();347 if (count > 0) {348 *has_children = true;349 return EOK;350 }351 352 /* Root namespace */353 devmap_handle_t namespace;354 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) {355 count = devmap_count_devices(namespace);356 if (count > 0) {357 *has_children = true;358 return EOK;359 }360 }361 362 *has_children = false;363 return EOK;364 }365 366 if (node->type == DEV_HANDLE_NAMESPACE) {367 size_t count = devmap_count_devices(node->handle);368 if (count > 0) {369 *has_children = true;370 return EOK;371 }372 373 *has_children = false;374 return EOK;375 }376 377 *has_children = false;378 return EOK;379 }380 381 static fs_index_t devfs_index_get(fs_node_t *fn)382 {383 devfs_node_t *node = (devfs_node_t *) fn->data;384 return node->handle;385 }386 387 static aoff64_t devfs_size_get(fs_node_t *fn)388 {389 return 0;390 }391 392 static unsigned int devfs_lnkcnt_get(fs_node_t *fn)393 {394 devfs_node_t *node = (devfs_node_t *) fn->data;395 396 if (node->handle == 0)397 return 0;398 399 return 1;400 }401 402 static char devfs_plb_get_char(unsigned pos)403 {404 return devfs_reg.plb_ro[pos % PLB_SIZE];405 }406 407 static bool devfs_is_directory(fs_node_t *fn)408 {409 devfs_node_t *node = (devfs_node_t *) fn->data;410 411 return ((node->type == DEV_HANDLE_NONE) || (node->type == DEV_HANDLE_NAMESPACE));412 }413 414 static bool devfs_is_file(fs_node_t *fn)415 {416 devfs_node_t *node = (devfs_node_t *) fn->data;417 418 return (node->type == DEV_HANDLE_DEVICE);419 }420 421 static devmap_handle_t devfs_device_get(fs_node_t *fn)422 {423 devfs_node_t *node = (devfs_node_t *) fn->data;424 425 if (node->type == DEV_HANDLE_DEVICE)426 return node->handle;427 428 return 0;429 }430 431 /** libfs operations */432 libfs_ops_t devfs_libfs_ops = {433 .root_get = devfs_root_get,434 .match = devfs_match,435 .node_get = devfs_node_get,436 .node_open = devfs_node_open,437 .node_put = devfs_node_put,438 .create = devfs_create_node,439 .destroy = devfs_destroy_node,440 .link = devfs_link_node,441 .unlink = devfs_unlink_node,442 .has_children = devfs_has_children,443 .index_get = devfs_index_get,444 .size_get = devfs_size_get,445 .lnkcnt_get = devfs_lnkcnt_get,446 .plb_get_char = devfs_plb_get_char,447 .is_directory = devfs_is_directory,448 .is_file = devfs_is_file,449 .device_get = devfs_device_get450 };451 452 93 bool devfs_init(void) 453 94 { … … 456 97 return false; 457 98 99 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0) 100 return false; 101 458 102 return true; 459 103 } … … 461 105 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 462 106 { 463 char *opts;464 465 107 /* Accept the mount options */ 466 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 467 0, NULL); 108 ipc_callid_t callid; 109 size_t size; 110 if (!ipc_data_write_receive(&callid, &size)) { 111 ipc_answer_0(callid, EINVAL); 112 ipc_answer_0(rid, EINVAL); 113 return; 114 } 115 116 char *opts = malloc(size + 1); 117 if (!opts) { 118 ipc_answer_0(callid, ENOMEM); 119 ipc_answer_0(rid, ENOMEM); 120 return; 121 } 122 123 ipcarg_t retval = ipc_data_write_finalize(callid, opts, size); 468 124 if (retval != EOK) { 469 async_answer_0(rid, retval); 125 ipc_answer_0(rid, retval); 126 free(opts); 470 127 return; 471 128 } 472 129 473 130 free(opts); 474 async_answer_3(rid, EOK, 0, 0, 0); 131 132 ipc_answer_3(rid, EOK, 0, 0, 0); 475 133 } 476 134 477 135 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 478 136 { 479 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 480 } 481 482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 483 { 484 async_answer_0(rid, ENOTSUP); 485 } 486 487 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 488 { 489 libfs_unmount(&devfs_libfs_ops, rid, request); 137 ipc_answer_0(rid, ENOTSUP); 490 138 } 491 139 492 140 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 493 141 { 494 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 495 } 496 497 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 498 { 499 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 500 } 501 502 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 503 { 504 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 505 } 506 507 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 508 { 509 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 510 aoff64_t pos = 511 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 512 513 if (index == 0) { 514 ipc_callid_t callid; 515 size_t size; 516 if (!async_data_read_receive(&callid, &size)) { 517 async_answer_0(callid, EINVAL); 518 async_answer_0(rid, EINVAL); 519 return; 520 } 521 522 dev_desc_t *desc; 523 size_t count = devmap_get_namespaces(&desc); 524 525 /* Get rid of root namespace */ 526 size_t i; 527 for (i = 0; i < count; i++) { 528 if (str_cmp(desc[i].name, "") == 0) { 529 if (pos >= i) 530 pos++; 531 532 break; 533 } 534 } 535 536 if (pos < count) { 537 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 538 free(desc); 539 async_answer_1(rid, EOK, 1); 540 return; 541 } 542 543 free(desc); 544 pos -= count; 545 546 /* Search root namespace */ 547 devmap_handle_t namespace; 548 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 549 count = devmap_get_devices(namespace, &desc); 550 551 if (pos < count) { 552 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 553 free(desc); 554 async_answer_1(rid, EOK, 1); 142 ipcarg_t first = IPC_GET_ARG1(*request); 143 ipcarg_t last = IPC_GET_ARG2(*request); 144 dev_handle_t dev_handle = IPC_GET_ARG3(*request); 145 ipcarg_t lflag = IPC_GET_ARG4(*request); 146 fs_index_t index = IPC_GET_ARG5(*request); 147 148 /* Hierarchy is flat, no altroot is supported */ 149 if (index != 0) { 150 ipc_answer_0(rid, ENOENT); 151 return; 152 } 153 154 if ((lflag & L_LINK) || (lflag & L_UNLINK)) { 155 ipc_answer_0(rid, ENOTSUP); 156 return; 157 } 158 159 /* Eat slash */ 160 if (PLB_GET_CHAR(first) == '/') { 161 first++; 162 first %= PLB_SIZE; 163 } 164 165 if (first >= last) { 166 /* Root entry */ 167 if (!(lflag & L_FILE)) 168 ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0); 169 else 170 ipc_answer_0(rid, ENOENT); 171 } else { 172 if (!(lflag & L_DIRECTORY)) { 173 size_t len; 174 if (last >= first) 175 len = last - first + 1; 176 else 177 len = first + PLB_SIZE - last + 1; 178 179 char *name = (char *) malloc(len + 1); 180 if (name == NULL) { 181 ipc_answer_0(rid, ENOMEM); 555 182 return; 556 183 } 557 184 558 free(desc); 559 } 560 561 async_answer_0(callid, ENOENT); 562 async_answer_1(rid, ENOENT, 0); 185 size_t i; 186 for (i = 0; i < len; i++) 187 name[i] = PLB_GET_CHAR(first + i); 188 189 name[len] = 0; 190 191 dev_handle_t handle; 192 if (devmap_device_get_handle(name, &handle, 0) != EOK) { 193 free(name); 194 ipc_answer_0(rid, ENOENT); 195 return; 196 } 197 198 if (lflag & L_OPEN) { 199 unsigned long key[] = { 200 [DEVICES_KEY_HANDLE] = (unsigned long) handle 201 }; 202 203 fibril_mutex_lock(&devices_mutex); 204 link_t *lnk = hash_table_find(&devices, key); 205 if (lnk == NULL) { 206 int phone = devmap_device_connect(handle, 0); 207 if (phone < 0) { 208 fibril_mutex_unlock(&devices_mutex); 209 free(name); 210 ipc_answer_0(rid, ENOENT); 211 return; 212 } 213 214 device_t *dev = (device_t *) malloc(sizeof(device_t)); 215 if (dev == NULL) { 216 fibril_mutex_unlock(&devices_mutex); 217 free(name); 218 ipc_answer_0(rid, ENOMEM); 219 return; 220 } 221 222 dev->handle = handle; 223 dev->phone = phone; 224 dev->refcount = 1; 225 226 hash_table_insert(&devices, key, &dev->link); 227 } else { 228 device_t *dev = hash_table_get_instance(lnk, device_t, link); 229 dev->refcount++; 230 } 231 fibril_mutex_unlock(&devices_mutex); 232 } 233 234 free(name); 235 236 ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1); 237 } else 238 ipc_answer_0(rid, ENOENT); 239 } 240 } 241 242 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 243 { 244 dev_handle_t handle = IPC_GET_ARG2(*request); 245 246 unsigned long key[] = { 247 [DEVICES_KEY_HANDLE] = (unsigned long) handle 248 }; 249 250 fibril_mutex_lock(&devices_mutex); 251 link_t *lnk = hash_table_find(&devices, key); 252 if (lnk == NULL) { 253 int phone = devmap_device_connect(handle, 0); 254 if (phone < 0) { 255 fibril_mutex_unlock(&devices_mutex); 256 ipc_answer_0(rid, ENOENT); 257 return; 258 } 259 260 device_t *dev = (device_t *) malloc(sizeof(device_t)); 261 if (dev == NULL) { 262 fibril_mutex_unlock(&devices_mutex); 263 ipc_answer_0(rid, ENOMEM); 264 return; 265 } 266 267 dev->handle = handle; 268 dev->phone = phone; 269 dev->refcount = 1; 270 271 hash_table_insert(&devices, key, &dev->link); 272 } else { 273 device_t *dev = hash_table_get_instance(lnk, device_t, link); 274 dev->refcount++; 275 } 276 fibril_mutex_unlock(&devices_mutex); 277 278 ipc_answer_3(rid, EOK, 0, 1, L_FILE); 279 } 280 281 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 282 { 283 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 284 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 285 286 ipc_callid_t callid; 287 size_t size; 288 if (!ipc_data_read_receive(&callid, &size) || 289 size != sizeof(struct stat)) { 290 ipc_answer_0(callid, EINVAL); 291 ipc_answer_0(rid, EINVAL); 563 292 return; 564 293 } 565 566 devmap_handle_type_t type = devmap_handle_probe(index); 567 568 if (type == DEV_HANDLE_NAMESPACE) { 569 /* Namespace directory */ 570 ipc_callid_t callid; 571 size_t size; 572 if (!async_data_read_receive(&callid, &size)) { 573 async_answer_0(callid, EINVAL); 574 async_answer_0(rid, EINVAL); 575 return; 576 } 577 578 dev_desc_t *desc; 579 size_t count = devmap_get_devices(index, &desc); 580 581 if (pos < count) { 582 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 583 free(desc); 584 async_answer_1(rid, EOK, 1); 585 return; 586 } 587 588 free(desc); 589 async_answer_0(callid, ENOENT); 590 async_answer_1(rid, ENOENT, 0); 591 return; 592 } 593 594 if (type == DEV_HANDLE_DEVICE) { 595 /* Device node */ 596 294 295 struct stat stat; 296 memset(&stat, 0, sizeof(struct stat)); 297 298 stat.fs_handle = devfs_reg.fs_handle; 299 stat.dev_handle = dev_handle; 300 stat.index = index; 301 stat.lnkcnt = 1; 302 stat.is_file = (index != 0); 303 stat.size = 0; 304 305 if (index != 0) { 597 306 unsigned long key[] = { 598 307 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 601 310 fibril_mutex_lock(&devices_mutex); 602 311 link_t *lnk = hash_table_find(&devices, key); 603 if (lnk == NULL) { 604 fibril_mutex_unlock(&devices_mutex); 605 async_answer_0(rid, ENOENT); 606 return; 607 } 608 609 device_t *dev = hash_table_get_instance(lnk, device_t, link); 610 assert(dev->phone >= 0); 611 612 ipc_callid_t callid; 613 if (!async_data_read_receive(&callid, NULL)) { 614 fibril_mutex_unlock(&devices_mutex); 615 async_answer_0(callid, EINVAL); 616 async_answer_0(rid, EINVAL); 617 return; 618 } 619 620 /* Make a request at the driver */ 621 ipc_call_t answer; 622 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 623 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 624 IPC_GET_ARG3(*request), &answer); 625 626 /* Forward the IPC_M_DATA_READ request to the driver */ 627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 312 if (lnk != NULL) 313 stat.devfs_stat.device = (dev_handle_t)index; 628 314 fibril_mutex_unlock(&devices_mutex); 629 630 /* Wait for reply from the driver. */ 631 sysarg_t rc; 632 async_wait_for(msg, &rc); 633 size_t bytes = IPC_GET_ARG1(answer); 634 635 /* Driver reply is the final result of the whole operation */ 636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 641 } 642 643 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 315 } 316 317 ipc_data_read_finalize(callid, &stat, sizeof(struct stat)); 318 ipc_answer_0(rid, EOK); 319 } 320 321 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 644 322 { 645 323 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 646 if (index == 0) { 647 async_answer_0(rid, ENOTSUP); 648 return; 649 } 650 651 devmap_handle_type_t type = devmap_handle_probe(index); 652 653 if (type == DEV_HANDLE_NAMESPACE) { 654 /* Namespace directory */ 655 async_answer_0(rid, ENOTSUP); 656 return; 657 } 658 659 if (type == DEV_HANDLE_DEVICE) { 660 /* Device node */ 324 off_t pos = (off_t) IPC_GET_ARG3(*request); 325 326 if (index != 0) { 661 327 unsigned long key[] = { 662 328 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 667 333 if (lnk == NULL) { 668 334 fibril_mutex_unlock(&devices_mutex); 669 async_answer_0(rid, ENOENT);335 ipc_answer_0(rid, ENOENT); 670 336 return; 671 337 } 672 338 673 339 device_t *dev = hash_table_get_instance(lnk, device_t, link); 674 assert(dev->phone >= 0);675 340 676 341 ipc_callid_t callid; 677 if (! async_data_write_receive(&callid, NULL)) {678 fibril_mutex_unlock(&devices_mutex); 679 async_answer_0(callid, EINVAL);680 async_answer_0(rid, EINVAL);342 if (!ipc_data_read_receive(&callid, NULL)) { 343 fibril_mutex_unlock(&devices_mutex); 344 ipc_answer_0(callid, EINVAL); 345 ipc_answer_0(rid, EINVAL); 681 346 return; 682 347 } … … 684 349 /* Make a request at the driver */ 685 350 ipc_call_t answer; 686 aid_t msg = async_send_3(dev->phone, IPC_GET_ IMETHOD(*request),351 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request), 687 352 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 688 353 IPC_GET_ARG3(*request), &answer); 689 354 690 /* Forward the IPC_M_DATA_WRITE request to the driver */ 691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 692 355 /* Forward the IPC_M_DATA_READ request to the driver */ 356 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 693 357 fibril_mutex_unlock(&devices_mutex); 694 358 695 359 /* Wait for reply from the driver. */ 696 sysarg_t rc;360 ipcarg_t rc; 697 361 async_wait_for(msg, &rc); 698 362 size_t bytes = IPC_GET_ARG1(answer); 699 363 700 364 /* Driver reply is the final result of the whole operation */ 701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 706 } 707 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 709 { 710 async_answer_0(rid, ENOTSUP); 711 } 712 713 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 365 ipc_answer_1(rid, rc, bytes); 366 } else { 367 ipc_callid_t callid; 368 size_t size; 369 if (!ipc_data_read_receive(&callid, &size)) { 370 ipc_answer_0(callid, EINVAL); 371 ipc_answer_0(rid, EINVAL); 372 return; 373 } 374 375 size_t count = devmap_device_get_count(); 376 dev_desc_t *desc = malloc(count * sizeof(dev_desc_t)); 377 if (desc == NULL) { 378 ipc_answer_0(callid, ENOMEM); 379 ipc_answer_1(rid, ENOMEM, 0); 380 return; 381 } 382 383 size_t max = devmap_device_get_devices(count, desc); 384 385 if (pos < max) { 386 ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 387 } else { 388 ipc_answer_0(callid, ENOENT); 389 ipc_answer_1(rid, ENOENT, 0); 390 return; 391 } 392 393 free(desc); 394 395 ipc_answer_1(rid, EOK, 1); 396 } 397 } 398 399 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 714 400 { 715 401 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 716 717 if (index == 0) { 718 async_answer_0(rid, EOK); 719 return; 720 } 721 722 devmap_handle_type_t type = devmap_handle_probe(index); 723 724 if (type == DEV_HANDLE_NAMESPACE) { 725 /* Namespace directory */ 726 async_answer_0(rid, EOK); 727 return; 728 } 729 730 if (type == DEV_HANDLE_DEVICE) { 402 off_t pos = (off_t) IPC_GET_ARG3(*request); 403 404 if (index != 0) { 731 405 unsigned long key[] = { 732 406 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 737 411 if (lnk == NULL) { 738 412 fibril_mutex_unlock(&devices_mutex); 739 async_answer_0(rid, ENOENT);413 ipc_answer_0(rid, ENOENT); 740 414 return; 741 415 } 742 416 743 417 device_t *dev = hash_table_get_instance(lnk, device_t, link); 744 assert(dev->phone >= 0); 745 dev->refcount--; 746 747 if (dev->refcount == 0) { 748 async_hangup(dev->phone); 749 hash_table_remove(&devices, key, DEVICES_KEYS); 750 } 418 419 ipc_callid_t callid; 420 if (!ipc_data_write_receive(&callid, NULL)) { 421 fibril_mutex_unlock(&devices_mutex); 422 ipc_answer_0(callid, EINVAL); 423 ipc_answer_0(rid, EINVAL); 424 return; 425 } 426 427 /* Make a request at the driver */ 428 ipc_call_t answer; 429 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request), 430 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 431 IPC_GET_ARG3(*request), &answer); 432 433 /* Forward the IPC_M_DATA_WRITE request to the driver */ 434 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 751 435 752 436 fibril_mutex_unlock(&devices_mutex); 753 437 754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 759 } 760 761 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 438 /* Wait for reply from the driver. */ 439 ipcarg_t rc; 440 async_wait_for(msg, &rc); 441 size_t bytes = IPC_GET_ARG1(answer); 442 443 /* Driver reply is the final result of the whole operation */ 444 ipc_answer_1(rid, rc, bytes); 445 } else { 446 /* Read-only filesystem */ 447 ipc_answer_0(rid, ENOTSUP); 448 } 449 } 450 451 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 452 { 453 ipc_answer_0(rid, ENOTSUP); 454 } 455 456 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 762 457 { 763 458 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 764 459 765 if (index == 0) { 766 async_answer_0(rid, EOK); 767 return; 768 } 769 770 devmap_handle_type_t type = devmap_handle_probe(index); 771 772 if (type == DEV_HANDLE_NAMESPACE) { 773 /* Namespace directory */ 774 async_answer_0(rid, EOK); 775 return; 776 } 777 778 if (type == DEV_HANDLE_DEVICE) { 460 if (index != 0) { 779 461 unsigned long key[] = { 780 462 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 785 467 if (lnk == NULL) { 786 468 fibril_mutex_unlock(&devices_mutex); 787 async_answer_0(rid, ENOENT);469 ipc_answer_0(rid, ENOENT); 788 470 return; 789 471 } 790 472 791 473 device_t *dev = hash_table_get_instance(lnk, device_t, link); 792 assert(dev->phone >= 0); 474 dev->refcount--; 475 476 if (dev->refcount == 0) { 477 ipc_hangup(dev->phone); 478 hash_table_remove(&devices, key, DEVICES_KEYS); 479 } 480 481 fibril_mutex_unlock(&devices_mutex); 482 483 ipc_answer_0(rid, EOK); 484 } else 485 ipc_answer_0(rid, ENOTSUP); 486 } 487 488 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 489 { 490 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 491 492 if (index != 0) { 493 unsigned long key[] = { 494 [DEVICES_KEY_HANDLE] = (unsigned long) index 495 }; 496 497 fibril_mutex_lock(&devices_mutex); 498 link_t *lnk = hash_table_find(&devices, key); 499 if (lnk == NULL) { 500 fibril_mutex_unlock(&devices_mutex); 501 ipc_answer_0(rid, ENOENT); 502 return; 503 } 504 505 device_t *dev = hash_table_get_instance(lnk, device_t, link); 793 506 794 507 /* Make a request at the driver */ 795 508 ipc_call_t answer; 796 aid_t msg = async_send_2(dev->phone, IPC_GET_ IMETHOD(*request),509 aid_t msg = async_send_2(dev->phone, IPC_GET_METHOD(*request), 797 510 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 798 511 … … 800 513 801 514 /* Wait for reply from the driver */ 802 sysarg_t rc;515 ipcarg_t rc; 803 516 async_wait_for(msg, &rc); 804 517 805 518 /* Driver reply is the final result of the whole operation */ 806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 519 ipc_answer_0(rid, rc); 520 } else 521 ipc_answer_0(rid, ENOTSUP); 811 522 } 812 523 813 524 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 814 525 { 815 async_answer_0(rid, ENOTSUP);526 ipc_answer_0(rid, ENOTSUP); 816 527 } 817 528
Note:
See TracChangeset
for help on using the changeset viewer.