Changes in uspace/srv/fs/devfs/devfs_ops.c [0143f72:cfd630af] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
r0143f72 rcfd630af 36 36 */ 37 37 38 #include < ipc/ipc.h>38 #include <macros.h> 39 39 #include <bool.h> 40 40 #include <errno.h> 41 41 #include <malloc.h> 42 #include <str ing.h>42 #include <str.h> 43 43 #include <libfs.h> 44 #include <fibril_sync .h>44 #include <fibril_synch.h> 45 45 #include <adt/hash_table.h> 46 #include <ipc/devmap.h> 46 47 #include <sys/stat.h> 48 #include <libfs.h> 49 #include <assert.h> 47 50 #include "devfs.h" 48 51 #include "devfs_ops.h" 49 52 50 #define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE]) 53 typedef struct { 54 devmap_handle_type_t type; 55 devmap_handle_t handle; 56 } devfs_node_t; 51 57 52 58 /** Opened devices structure */ 53 59 typedef struct { 54 dev _handle_t handle;55 int phone; 60 devmap_handle_t handle; 61 int phone; /**< When < 0, the structure is incomplete. */ 56 62 size_t refcount; 57 63 link_t link; 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 58 65 } device_t; 59 66 … … 77 84 { 78 85 device_t *dev = hash_table_get_instance(item, device_t, link); 79 return (dev->handle == (dev _handle_t) key[DEVICES_KEY_HANDLE]);86 return (dev->handle == (devmap_handle_t) key[DEVICES_KEY_HANDLE]); 80 87 } 81 88 … … 91 98 }; 92 99 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->handle 232 }; 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 other 252 * fibrils will not race with us when we drop the mutex 253 * 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 structure 268 * being completed (or destroyed). 269 */ 270 fibril_condvar_broadcast(&dev->cv); 271 272 if (phone < 0) { 273 /* 274 * Connecting failed, need to remove the 275 * 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 completed 291 * and start from the beginning as the device 292 * structure might have entirely disappeared 293 * while we were not holding the mutex in 294 * 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_get 450 }; 451 93 452 bool devfs_init(void) 94 453 { … … 97 456 return false; 98 457 99 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)100 return false;101 102 458 return true; 103 459 } … … 105 461 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 106 462 { 463 char *opts; 464 107 465 /* Accept the mount options */ 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); 466 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 467 0, NULL); 124 468 if (retval != EOK) { 125 ipc_answer_0(rid, retval); 126 free(opts); 469 async_answer_0(rid, retval); 127 470 return; 128 471 } 129 472 130 473 free(opts); 131 132 ipc_answer_3(rid, EOK, 0, 0, 0); 474 async_answer_3(rid, EOK, 0, 0, 0); 133 475 } 134 476 135 477 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 136 478 { 137 ipc_answer_0(rid, ENOTSUP); 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); 138 490 } 139 491 140 492 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 141 493 { 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; 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); 178 550 179 char *name = (char *) malloc(len + 1); 180 if (name == NULL) { 181 ipc_answer_0(rid, ENOMEM); 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); 182 555 return; 183 556 } 184 557 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); 292 return; 293 } 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) { 306 unsigned long key[] = { 307 [DEVICES_KEY_HANDLE] = (unsigned long) index 308 }; 309 310 fibril_mutex_lock(&devices_mutex); 311 link_t *lnk = hash_table_find(&devices, key); 312 if (lnk != NULL) 313 stat.devfs_stat.device = (dev_handle_t)index; 314 fibril_mutex_unlock(&devices_mutex); 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) 322 { 323 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 324 off_t pos = (off_t) IPC_GET_ARG3(*request); 325 326 if (index != 0) { 558 free(desc); 559 } 560 561 async_answer_0(callid, ENOENT); 562 async_answer_1(rid, ENOENT, 0); 563 return; 564 } 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 327 597 unsigned long key[] = { 328 598 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 333 603 if (lnk == NULL) { 334 604 fibril_mutex_unlock(&devices_mutex); 335 ipc_answer_0(rid, ENOENT);605 async_answer_0(rid, ENOENT); 336 606 return; 337 607 } 338 608 339 609 device_t *dev = hash_table_get_instance(lnk, device_t, link); 610 assert(dev->phone >= 0); 340 611 341 612 ipc_callid_t callid; 342 if (! ipc_data_read_receive(&callid, NULL)) {613 if (!async_data_read_receive(&callid, NULL)) { 343 614 fibril_mutex_unlock(&devices_mutex); 344 ipc_answer_0(callid, EINVAL);345 ipc_answer_0(rid, EINVAL);615 async_answer_0(callid, EINVAL); 616 async_answer_0(rid, EINVAL); 346 617 return; 347 618 } … … 349 620 /* Make a request at the driver */ 350 621 ipc_call_t answer; 351 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),622 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 352 623 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 353 624 IPC_GET_ARG3(*request), &answer); 354 625 355 626 /* 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);627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 357 628 fibril_mutex_unlock(&devices_mutex); 358 629 359 630 /* Wait for reply from the driver. */ 360 ipcarg_t rc;631 sysarg_t rc; 361 632 async_wait_for(msg, &rc); 362 633 size_t bytes = IPC_GET_ARG1(answer); 363 634 364 635 /* Driver reply is the final result of the whole operation */ 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 } 636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 397 641 } 398 642 … … 400 644 { 401 645 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 402 off_t pos = (off_t) IPC_GET_ARG3(*request); 403 404 if (index != 0) { 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 */ 405 661 unsigned long key[] = { 406 662 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 411 667 if (lnk == NULL) { 412 668 fibril_mutex_unlock(&devices_mutex); 413 ipc_answer_0(rid, ENOENT);669 async_answer_0(rid, ENOENT); 414 670 return; 415 671 } 416 672 417 673 device_t *dev = hash_table_get_instance(lnk, device_t, link); 674 assert(dev->phone >= 0); 418 675 419 676 ipc_callid_t callid; 420 if (! ipc_data_write_receive(&callid, NULL)) {677 if (!async_data_write_receive(&callid, NULL)) { 421 678 fibril_mutex_unlock(&devices_mutex); 422 ipc_answer_0(callid, EINVAL);423 ipc_answer_0(rid, EINVAL);679 async_answer_0(callid, EINVAL); 680 async_answer_0(rid, EINVAL); 424 681 return; 425 682 } … … 427 684 /* Make a request at the driver */ 428 685 ipc_call_t answer; 429 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),686 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 430 687 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 431 688 IPC_GET_ARG3(*request), &answer); 432 689 433 690 /* 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);691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 435 692 436 693 fibril_mutex_unlock(&devices_mutex); 437 694 438 695 /* Wait for reply from the driver. */ 439 ipcarg_t rc;696 sysarg_t rc; 440 697 async_wait_for(msg, &rc); 441 698 size_t bytes = IPC_GET_ARG1(answer); 442 699 443 700 /* 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 }701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 449 706 } 450 707 451 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 452 709 { 453 ipc_answer_0(rid, ENOTSUP);710 async_answer_0(rid, ENOTSUP); 454 711 } 455 712 … … 458 715 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 459 716 460 if (index != 0) { 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) { 461 731 unsigned long key[] = { 462 732 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 467 737 if (lnk == NULL) { 468 738 fibril_mutex_unlock(&devices_mutex); 469 ipc_answer_0(rid, ENOENT);739 async_answer_0(rid, ENOENT); 470 740 return; 471 741 } 472 742 473 743 device_t *dev = hash_table_get_instance(lnk, device_t, link); 744 assert(dev->phone >= 0); 474 745 dev->refcount--; 475 746 476 747 if (dev->refcount == 0) { 477 ipc_hangup(dev->phone);748 async_hangup(dev->phone); 478 749 hash_table_remove(&devices, key, DEVICES_KEYS); 479 750 } … … 481 752 fibril_mutex_unlock(&devices_mutex); 482 753 483 ipc_answer_0(rid, EOK); 484 } else 485 ipc_answer_0(rid, ENOTSUP); 754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 486 759 } 487 760 … … 490 763 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 491 764 492 if (index != 0) { 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) { 493 779 unsigned long key[] = { 494 780 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 499 785 if (lnk == NULL) { 500 786 fibril_mutex_unlock(&devices_mutex); 501 ipc_answer_0(rid, ENOENT);787 async_answer_0(rid, ENOENT); 502 788 return; 503 789 } 504 790 505 791 device_t *dev = hash_table_get_instance(lnk, device_t, link); 792 assert(dev->phone >= 0); 506 793 507 794 /* Make a request at the driver */ 508 795 ipc_call_t answer; 509 aid_t msg = async_send_2(dev->phone, IPC_GET_ METHOD(*request),796 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request), 510 797 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 511 798 … … 513 800 514 801 /* Wait for reply from the driver */ 515 ipcarg_t rc;802 sysarg_t rc; 516 803 async_wait_for(msg, &rc); 517 804 518 805 /* Driver reply is the final result of the whole operation */ 519 ipc_answer_0(rid, rc); 520 } else 521 ipc_answer_0(rid, ENOTSUP); 806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 522 811 } 523 812 524 813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 525 814 { 526 ipc_answer_0(rid, ENOTSUP);815 async_answer_0(rid, ENOTSUP); 527 816 } 528 817
Note:
See TracChangeset
for help on using the changeset viewer.