Changes in uspace/srv/devmap/devmap.c [0da4e41:19f857a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devmap/devmap.c
r0da4e41 r19f857a 42 42 #include <errno.h> 43 43 #include <bool.h> 44 #include <fibril_sync .h>44 #include <fibril_synch.h> 45 45 #include <stdlib.h> 46 #include <str ing.h>46 #include <str.h> 47 47 #include <ipc/devmap.h> 48 48 … … 68 68 } devmap_driver_t; 69 69 70 /** Info about registered namespaces 71 * 72 */ 73 typedef struct { 74 /** Pointer to the previous and next device in the list of all namespaces */ 75 link_t namespaces; 76 /** Unique namespace identifier */ 77 dev_handle_t handle; 78 /** Namespace name */ 79 char *name; 80 /** Reference count */ 81 size_t refcnt; 82 } devmap_namespace_t; 83 70 84 /** Info about registered device 71 85 * … … 77 91 owned by one driver */ 78 92 link_t driver_devices; 79 /** Unique device identifier 93 /** Unique device identifier */ 80 94 dev_handle_t handle; 95 /** Device namespace */ 96 devmap_namespace_t *namespace; 81 97 /** Device name */ 82 98 char *name; … … 86 102 87 103 LIST_INITIALIZE(devices_list); 104 LIST_INITIALIZE(namespaces_list); 88 105 LIST_INITIALIZE(drivers_list); 89 106 … … 117 134 } 118 135 136 /** Convert fully qualified device name to namespace and device name. 137 * 138 * A fully qualified device name can be either a plain device name 139 * (then the namespace is considered to be an empty string) or consist 140 * of two components separated by a slash. No more than one slash 141 * is allowed. 142 * 143 */ 144 static bool devmap_fqdn_split(const char *fqdn, char **ns_name, char **name) 145 { 146 size_t cnt = 0; 147 size_t slash_offset = 0; 148 size_t slash_after = 0; 149 150 size_t offset = 0; 151 size_t offset_prev = 0; 152 wchar_t c; 153 154 while ((c = str_decode(fqdn, &offset, STR_NO_LIMIT)) != 0) { 155 if (c == '/') { 156 cnt++; 157 slash_offset = offset_prev; 158 slash_after = offset; 159 } 160 offset_prev = offset; 161 } 162 163 /* More than one slash */ 164 if (cnt > 1) 165 return false; 166 167 /* No slash -> namespace is empty */ 168 if (cnt == 0) { 169 *ns_name = str_dup(""); 170 if (*ns_name == NULL) 171 return false; 172 173 *name = str_dup(fqdn); 174 if ((*name == NULL) || (str_cmp(*name, "") == 0)) { 175 free(*ns_name); 176 return false; 177 } 178 179 return true; 180 } 181 182 /* Exactly one slash */ 183 *ns_name = str_ndup(fqdn, slash_offset); 184 if (*ns_name == NULL) 185 return false; 186 187 *name = str_dup(fqdn + slash_after); 188 if ((*name == NULL) || (str_cmp(*name, "") == 0)) { 189 free(*ns_name); 190 return false; 191 } 192 193 return true; 194 } 195 196 /** Find namespace with given name. 197 * 198 * The devices_list_mutex should be already held when 199 * calling this function. 200 * 201 */ 202 static devmap_namespace_t *devmap_namespace_find_name(const char *name) 203 { 204 link_t *item = namespaces_list.next; 205 206 while (item != &namespaces_list) { 207 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 208 if (str_cmp(namespace->name, name) == 0) 209 return namespace; 210 item = item->next; 211 } 212 213 return NULL; 214 } 215 216 /** Find namespace with given handle. 217 * 218 * The devices_list_mutex should be already held when 219 * calling this function. 220 * 221 * @todo: use hash table 222 * 223 */ 224 static devmap_namespace_t *devmap_namespace_find_handle(dev_handle_t handle) 225 { 226 link_t *item = namespaces_list.next; 227 228 while (item != &namespaces_list) { 229 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 230 if (namespace->handle == handle) 231 return namespace; 232 233 item = item->next; 234 } 235 236 return NULL; 237 } 238 119 239 /** Find device with given name. 120 240 * 121 */ 122 static devmap_device_t *devmap_device_find_name(const char *name) 241 * The devices_list_mutex should be already held when 242 * calling this function. 243 * 244 */ 245 static devmap_device_t *devmap_device_find_name(const char *ns_name, 246 const char *name) 123 247 { 124 248 link_t *item = devices_list.next; 125 devmap_device_t *device = NULL;126 249 127 250 while (item != &devices_list) { 128 dev ice = list_get_instance(item, devmap_device_t, devices);129 if ( str_cmp(device->name, name) == 0)130 break;251 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 252 if ((str_cmp(device->namespace->name, ns_name) == 0) && (str_cmp(device->name, name) == 0)) 253 return device; 131 254 item = item->next; 132 255 } 133 256 134 if (item == &devices_list) 257 return NULL; 258 } 259 260 /** Find device with given handle. 261 * 262 * The devices_list_mutex should be already held when 263 * calling this function. 264 * 265 * @todo: use hash table 266 * 267 */ 268 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle) 269 { 270 link_t *item = devices_list.next; 271 272 while (item != &devices_list) { 273 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 274 if (device->handle == handle) 275 return device; 276 277 item = item->next; 278 } 279 280 return NULL; 281 } 282 283 /** Create a namespace (if not already present) 284 * 285 * The devices_list_mutex should be already held when 286 * calling this function. 287 * 288 */ 289 static devmap_namespace_t *devmap_namespace_create(const char *ns_name) 290 { 291 devmap_namespace_t *namespace = devmap_namespace_find_name(ns_name); 292 if (namespace != NULL) 293 return namespace; 294 295 namespace = (devmap_namespace_t *) malloc(sizeof(devmap_namespace_t)); 296 if (namespace == NULL) 135 297 return NULL; 136 298 137 device = list_get_instance(item, devmap_device_t, devices); 138 return device; 139 } 140 141 /** Find device with given handle. 142 * 143 * @todo: use hash table 144 * 145 */ 146 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle) 147 { 148 fibril_mutex_lock(&devices_list_mutex); 149 150 link_t *item = (&devices_list)->next; 151 devmap_device_t *device = NULL; 152 153 while (item != &devices_list) { 154 device = list_get_instance(item, devmap_device_t, devices); 155 if (device->handle == handle) 156 break; 157 item = item->next; 158 } 159 160 if (item == &devices_list) { 161 fibril_mutex_unlock(&devices_list_mutex); 299 namespace->name = str_dup(ns_name); 300 if (namespace->name == NULL) { 301 free(namespace); 162 302 return NULL; 163 303 } 164 304 165 device = list_get_instance(item, devmap_device_t, devices); 166 167 fibril_mutex_unlock(&devices_list_mutex); 168 169 return device; 170 } 171 172 /** 173 * Unregister device and free it. It's assumed that driver's device list is 174 * already locked. 175 */ 176 static int devmap_device_unregister_core(devmap_device_t *device) 177 { 305 namespace->handle = devmap_create_handle(); 306 namespace->refcnt = 0; 307 308 /* 309 * Insert new namespace into list of registered namespaces 310 */ 311 list_append(&(namespace->namespaces), &namespaces_list); 312 313 return namespace; 314 } 315 316 /** Destroy a namespace (if it is no longer needed) 317 * 318 * The devices_list_mutex should be already held when 319 * calling this function. 320 * 321 */ 322 static void devmap_namespace_destroy(devmap_namespace_t *namespace) 323 { 324 if (namespace->refcnt == 0) { 325 list_remove(&(namespace->namespaces)); 326 327 free(namespace->name); 328 free(namespace); 329 } 330 } 331 332 /** Increase namespace reference count by including device 333 * 334 * The devices_list_mutex should be already held when 335 * calling this function. 336 * 337 */ 338 static void devmap_namespace_addref(devmap_namespace_t *namespace, 339 devmap_device_t *device) 340 { 341 device->namespace = namespace; 342 namespace->refcnt++; 343 } 344 345 /** Decrease namespace reference count 346 * 347 * The devices_list_mutex should be already held when 348 * calling this function. 349 * 350 */ 351 static void devmap_namespace_delref(devmap_namespace_t *namespace) 352 { 353 namespace->refcnt--; 354 devmap_namespace_destroy(namespace); 355 } 356 357 /** Unregister device and free it 358 * 359 * The devices_list_mutex should be already held when 360 * calling this function. 361 * 362 */ 363 static void devmap_device_unregister_core(devmap_device_t *device) 364 { 365 devmap_namespace_delref(device->namespace); 178 366 list_remove(&(device->devices)); 179 367 list_remove(&(device->driver_devices)); 180 368 369 free(device->namespace); 181 370 free(device->name); 182 371 free(device); 183 184 return EOK;185 372 } 186 373 … … 189 376 * drivers. 190 377 */ 191 static void devmap_driver_register(devmap_driver_t **odriver) 192 { 193 *odriver = NULL; 194 378 static devmap_driver_t *devmap_driver_register(void) 379 { 195 380 ipc_call_t icall; 196 381 ipc_callid_t iid = async_get_call(&icall); … … 198 383 if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) { 199 384 ipc_answer_0(iid, EREFUSED); 200 return ;385 return NULL; 201 386 } 202 387 … … 205 390 if (driver == NULL) { 206 391 ipc_answer_0(iid, ENOMEM); 207 return ;392 return NULL; 208 393 } 209 394 … … 211 396 * Get driver name 212 397 */ 213 i pc_callid_t callid;214 size_t name_size;215 if ( !async_data_write_receive(&callid, &name_size)) {398 int rc = async_data_write_accept((void **) &driver->name, true, 0, 399 DEVMAP_NAME_MAXLEN, 0, NULL); 400 if (rc != EOK) { 216 401 free(driver); 217 ipc_answer_0(callid, EREFUSED); 218 ipc_answer_0(iid, EREFUSED); 219 return; 220 } 221 222 if (name_size > DEVMAP_NAME_MAXLEN) { 223 free(driver); 224 ipc_answer_0(callid, EINVAL); 225 ipc_answer_0(iid, EREFUSED); 226 return; 227 } 228 229 /* 230 * Allocate buffer for device name. 231 */ 232 driver->name = (char *) malloc(name_size + 1); 233 if (driver->name == NULL) { 234 free(driver); 235 ipc_answer_0(callid, ENOMEM); 236 ipc_answer_0(iid, EREFUSED); 237 return; 238 } 239 240 /* 241 * Send confirmation to sender and get data into buffer. 242 */ 243 if (async_data_write_finalize(callid, driver->name, name_size) != EOK) { 244 free(driver->name); 245 free(driver); 246 ipc_answer_0(iid, EREFUSED); 247 return; 248 } 249 250 driver->name[name_size] = 0; 402 ipc_answer_0(iid, rc); 403 return NULL; 404 } 251 405 252 406 /* Initialize mutex for list of devices owned by this driver */ … … 262 416 */ 263 417 ipc_call_t call; 264 callid = async_get_call(&call);418 ipc_callid_t callid = async_get_call(&call); 265 419 266 420 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { … … 270 424 free(driver); 271 425 ipc_answer_0(iid, ENOTSUP); 272 return ;426 return NULL; 273 427 } 274 428 … … 293 447 ipc_answer_0(iid, EOK); 294 448 295 *odriver =driver;449 return driver; 296 450 } 297 451 … … 355 509 } 356 510 357 /* Get device name */ 358 ipc_callid_t callid; 359 size_t size; 360 if (!async_data_write_receive(&callid, &size)) { 511 /* Get fqdn */ 512 char *fqdn; 513 int rc = async_data_write_accept((void **) &fqdn, true, 0, 514 DEVMAP_NAME_MAXLEN, 0, NULL); 515 if (rc != EOK) { 361 516 free(device); 362 ipc_answer_0(iid, EREFUSED); 363 return; 364 } 365 366 if (size > DEVMAP_NAME_MAXLEN) { 517 ipc_answer_0(iid, rc); 518 return; 519 } 520 521 char *ns_name; 522 if (!devmap_fqdn_split(fqdn, &ns_name, &device->name)) { 523 free(fqdn); 367 524 free(device); 368 ipc_answer_0(callid, EINVAL); 369 ipc_answer_0(iid, EREFUSED); 370 return; 371 } 372 373 /* +1 for terminating \0 */ 374 device->name = (char *) malloc(size + 1); 375 376 if (device->name == NULL) { 525 ipc_answer_0(iid, EINVAL); 526 return; 527 } 528 529 free(fqdn); 530 531 fibril_mutex_lock(&devices_list_mutex); 532 533 devmap_namespace_t *namespace = devmap_namespace_create(ns_name); 534 free(ns_name); 535 if (!namespace) { 536 fibril_mutex_unlock(&devices_list_mutex); 377 537 free(device); 378 ipc_answer_0(callid, ENOMEM); 379 ipc_answer_0(iid, EREFUSED); 380 return; 381 } 382 383 async_data_write_finalize(callid, device->name, size); 384 device->name[size] = 0; 538 ipc_answer_0(iid, ENOMEM); 539 return; 540 } 385 541 386 542 list_initialize(&(device->devices)); 387 543 list_initialize(&(device->driver_devices)); 388 544 389 fibril_mutex_lock(&devices_list_mutex); 390 391 /* Check that device with such name is not already registered */ 392 if (NULL != devmap_device_find_name(device->name)) { 393 printf(NAME ": Device '%s' already registered\n", device->name); 545 /* Check that device is not already registered */ 546 if (devmap_device_find_name(namespace->name, device->name) != NULL) { 547 printf(NAME ": Device '%s/%s' already registered\n", device->namespace, device->name); 548 devmap_namespace_destroy(namespace); 394 549 fibril_mutex_unlock(&devices_list_mutex); 550 free(device->namespace); 395 551 free(device->name); 396 552 free(device); … … 402 558 device->handle = devmap_create_handle(); 403 559 560 devmap_namespace_addref(namespace, device); 404 561 device->driver = driver; 405 562 … … 437 594 static void devmap_forward(ipc_callid_t callid, ipc_call_t *call) 438 595 { 596 fibril_mutex_lock(&devices_list_mutex); 597 439 598 /* 440 599 * Get handle from request … … 450 609 ipc_forward_fast(callid, dev->driver->phone, dev->handle, 451 610 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 611 612 fibril_mutex_unlock(&devices_list_mutex); 452 613 } 453 614 … … 458 619 * 459 620 */ 460 static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall) 461 { 462 /* 463 * Wait for incoming message with device name (but do not 464 * read the name itself until the buffer is allocated). 465 */ 466 ipc_callid_t callid; 467 size_t size; 468 if (!async_data_write_receive(&callid, &size)) { 469 ipc_answer_0(callid, EREFUSED); 470 ipc_answer_0(iid, EREFUSED); 471 return; 472 } 473 474 if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) { 475 ipc_answer_0(callid, EINVAL); 476 ipc_answer_0(iid, EREFUSED); 477 return; 478 } 479 480 /* 481 * Allocate buffer for device name. 482 */ 483 char *name = (char *) malloc(size + 1); 484 if (name == NULL) { 485 ipc_answer_0(callid, ENOMEM); 486 ipc_answer_0(iid, EREFUSED); 487 return; 488 } 489 490 /* 491 * Send confirmation to sender and get data into buffer. 492 */ 493 ipcarg_t retval = async_data_write_finalize(callid, name, size); 494 if (retval != EOK) { 495 ipc_answer_0(iid, EREFUSED); 496 free(name); 497 return; 498 } 499 name[size] = '\0'; 621 static void devmap_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 622 { 623 char *fqdn; 624 625 /* Get fqdn */ 626 int rc = async_data_write_accept((void **) &fqdn, true, 0, 627 DEVMAP_NAME_MAXLEN, 0, NULL); 628 if (rc != EOK) { 629 ipc_answer_0(iid, rc); 630 return; 631 } 632 633 char *ns_name; 634 char *name; 635 if (!devmap_fqdn_split(fqdn, &ns_name, &name)) { 636 free(fqdn); 637 ipc_answer_0(iid, EINVAL); 638 return; 639 } 640 641 free(fqdn); 500 642 501 643 fibril_mutex_lock(&devices_list_mutex); 502 644 const devmap_device_t *dev; 645 503 646 recheck: 504 647 505 648 /* 506 649 * Find device name in the list of known devices. 507 650 */ 508 dev = devmap_device_find_name(n ame);651 dev = devmap_device_find_name(ns_name, name); 509 652 510 653 /* … … 520 663 521 664 ipc_answer_0(iid, ENOENT); 665 free(ns_name); 522 666 free(name); 523 667 fibril_mutex_unlock(&devices_list_mutex); … … 527 671 528 672 ipc_answer_1(iid, EOK, dev->handle); 673 free(ns_name); 529 674 free(name); 530 675 } 531 676 532 /** Find name of device identified by id and send it to caller. 533 * 534 */ 535 static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) 536 { 537 const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall)); 677 /** Find handle for namespace identified by name. 678 * 679 * In answer will be send EOK and device handle in arg1 or a error 680 * code from errno.h. 681 * 682 */ 683 static void devmap_namespace_get_handle(ipc_callid_t iid, ipc_call_t *icall) 684 { 685 char *name; 686 687 /* Get device name */ 688 int rc = async_data_write_accept((void **) &name, true, 0, 689 DEVMAP_NAME_MAXLEN, 0, NULL); 690 if (rc != EOK) { 691 ipc_answer_0(iid, rc); 692 return; 693 } 694 695 fibril_mutex_lock(&devices_list_mutex); 696 const devmap_namespace_t *namespace; 697 698 recheck: 538 699 539 700 /* 540 * Device not found.701 * Find namespace name in the list of known namespaces. 541 702 */ 542 if (device == NULL) { 703 namespace = devmap_namespace_find_name(name); 704 705 /* 706 * Namespace was not found. 707 */ 708 if (namespace == NULL) { 709 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { 710 /* Blocking lookup */ 711 fibril_condvar_wait(&devices_list_cv, 712 &devices_list_mutex); 713 goto recheck; 714 } 715 543 716 ipc_answer_0(iid, ENOENT); 544 return; 545 } 546 547 ipc_answer_0(iid, EOK); 548 549 /* FIXME: 550 * We have no channel from DEVMAP to client, therefore 551 * sending must be initiated by client. 552 * 553 * size_t name_size = str_size(device->name); 554 * 555 * int rc = async_data_write_send(phone, device->name, name_size); 556 * if (rc != EOK) { 557 * async_wait_for(req, NULL); 558 * return rc; 559 * } 560 */ 561 562 /* TODO: send name in response */ 563 } 564 565 static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall) 717 free(name); 718 fibril_mutex_unlock(&devices_list_mutex); 719 return; 720 } 721 fibril_mutex_unlock(&devices_list_mutex); 722 723 ipc_answer_1(iid, EOK, namespace->handle); 724 free(name); 725 } 726 727 static void devmap_handle_probe(ipc_callid_t iid, ipc_call_t *icall) 566 728 { 567 729 fibril_mutex_lock(&devices_list_mutex); 568 ipc_answer_1(iid, EOK, list_count(&devices_list)); 730 731 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 732 if (namespace == NULL) { 733 devmap_device_t *dev = devmap_device_find_handle(IPC_GET_ARG1(*icall)); 734 if (dev == NULL) 735 ipc_answer_1(iid, EOK, DEV_HANDLE_NONE); 736 else 737 ipc_answer_1(iid, EOK, DEV_HANDLE_DEVICE); 738 } else 739 ipc_answer_1(iid, EOK, DEV_HANDLE_NAMESPACE); 740 569 741 fibril_mutex_unlock(&devices_list_mutex); 570 742 } 571 743 572 static void devmap_get_ devices(ipc_callid_t iid, ipc_call_t *icall)744 static void devmap_get_namespace_count(ipc_callid_t iid, ipc_call_t *icall) 573 745 { 574 746 fibril_mutex_lock(&devices_list_mutex); 575 747 ipc_answer_1(iid, EOK, list_count(&namespaces_list)); 748 fibril_mutex_unlock(&devices_list_mutex); 749 } 750 751 static void devmap_get_device_count(ipc_callid_t iid, ipc_call_t *icall) 752 { 753 fibril_mutex_lock(&devices_list_mutex); 754 755 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 756 if (namespace == NULL) 757 ipc_answer_0(iid, EEXISTS); 758 else 759 ipc_answer_1(iid, EOK, namespace->refcnt); 760 761 fibril_mutex_unlock(&devices_list_mutex); 762 } 763 764 static void devmap_get_namespaces(ipc_callid_t iid, ipc_call_t *icall) 765 { 576 766 ipc_callid_t callid; 577 767 size_t size; … … 584 774 if ((size % sizeof(dev_desc_t)) != 0) { 585 775 ipc_answer_0(callid, EINVAL); 776 ipc_answer_0(iid, EINVAL); 777 return; 778 } 779 780 fibril_mutex_lock(&devices_list_mutex); 781 782 size_t count = size / sizeof(dev_desc_t); 783 if (count != list_count(&namespaces_list)) { 784 ipc_answer_0(callid, EOVERFLOW); 785 ipc_answer_0(iid, EOVERFLOW); 786 return; 787 } 788 789 dev_desc_t *desc = (dev_desc_t *) malloc(size); 790 if (desc == NULL) { 791 ipc_answer_0(callid, ENOMEM); 792 ipc_answer_0(iid, ENOMEM); 793 return; 794 } 795 796 link_t *item = namespaces_list.next; 797 size_t pos = 0; 798 while (item != &namespaces_list) { 799 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 800 801 desc[pos].handle = namespace->handle; 802 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, namespace->name); 803 pos++; 804 805 item = item->next; 806 } 807 808 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 809 810 free(desc); 811 fibril_mutex_unlock(&devices_list_mutex); 812 813 ipc_answer_0(iid, retval); 814 } 815 816 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall) 817 { 818 /* FIXME: Use faster algorithm which can make better use 819 of namespaces */ 820 821 ipc_callid_t callid; 822 size_t size; 823 if (!async_data_read_receive(&callid, &size)) { 824 ipc_answer_0(callid, EREFUSED); 586 825 ipc_answer_0(iid, EREFUSED); 587 826 return; 588 827 } 589 828 829 if ((size % sizeof(dev_desc_t)) != 0) { 830 ipc_answer_0(callid, EINVAL); 831 ipc_answer_0(iid, EINVAL); 832 return; 833 } 834 835 fibril_mutex_lock(&devices_list_mutex); 836 837 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 838 if (namespace == NULL) { 839 fibril_mutex_unlock(&devices_list_mutex); 840 ipc_answer_0(callid, ENOENT); 841 ipc_answer_0(iid, ENOENT); 842 return; 843 } 844 590 845 size_t count = size / sizeof(dev_desc_t); 846 if (count != namespace->refcnt) { 847 ipc_answer_0(callid, EOVERFLOW); 848 ipc_answer_0(iid, EOVERFLOW); 849 return; 850 } 851 591 852 dev_desc_t *desc = (dev_desc_t *) malloc(size); 592 853 if (desc == NULL) { … … 596 857 } 597 858 859 link_t *item = devices_list.next; 598 860 size_t pos = 0; 599 link_t *item = devices_list.next; 600 601 while ((item != &devices_list) && (pos < count)) { 861 while (item != &devices_list) { 602 862 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 603 863 604 desc[pos].handle = device->handle; 605 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 606 pos++; 864 if (device->namespace == namespace) { 865 desc[pos].handle = device->handle; 866 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 867 pos++; 868 } 869 607 870 item = item->next; 608 871 } 609 872 610 ipcarg_t retval = async_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t)); 611 if (retval != EOK) { 612 ipc_answer_0(iid, EREFUSED); 613 free(desc); 614 return; 615 } 873 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 616 874 617 875 free(desc); 618 619 876 fibril_mutex_unlock(&devices_list_mutex); 620 877 621 ipc_answer_ 1(iid, EOK, pos);878 ipc_answer_0(iid, retval); 622 879 } 623 880 … … 642 899 } 643 900 644 /* Create NULL device entry */ 901 char null[DEVMAP_NAME_MAXLEN]; 902 snprintf(null, DEVMAP_NAME_MAXLEN, "%u", i); 903 904 char *dev_name = str_dup(null); 905 if (dev_name == NULL) { 906 fibril_mutex_unlock(&null_devices_mutex); 907 ipc_answer_0(iid, ENOMEM); 908 return; 909 } 910 645 911 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); 646 912 if (device == NULL) { … … 650 916 } 651 917 652 char null[DEVMAP_NAME_MAXLEN];653 snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);654 655 device->name = str_dup(null);656 if (device->name == NULL) {918 fibril_mutex_lock(&devices_list_mutex); 919 920 devmap_namespace_t *namespace = devmap_namespace_create("null"); 921 if (!namespace) { 922 fibril_mutex_lock(&devices_list_mutex); 657 923 fibril_mutex_unlock(&null_devices_mutex); 658 free(device);659 924 ipc_answer_0(iid, ENOMEM); 660 925 return; … … 663 928 list_initialize(&(device->devices)); 664 929 list_initialize(&(device->driver_devices)); 665 666 fibril_mutex_lock(&devices_list_mutex);667 930 668 931 /* Get unique device handle */ 669 932 device->handle = devmap_create_handle(); 670 933 device->driver = NULL; 934 935 devmap_namespace_addref(namespace, device); 936 device->name = dev_name; 671 937 672 938 /* Insert device into list of all devices … … 692 958 } 693 959 960 fibril_mutex_lock(&devices_list_mutex); 694 961 devmap_device_unregister_core(null_devices[i]); 962 fibril_mutex_unlock(&devices_list_mutex); 963 695 964 null_devices[i] = NULL; 696 965 … … 725 994 ipc_answer_0(iid, EOK); 726 995 727 devmap_driver_t *driver = NULL; 728 devmap_driver_register(&driver); 729 730 if (NULL == driver) 996 devmap_driver_t *driver = devmap_driver_register(); 997 if (driver == NULL) 731 998 return; 732 999 … … 755 1022 break; 756 1023 case DEVMAP_DEVICE_GET_HANDLE: 757 devmap_ get_handle(callid, &call);758 break; 759 case DEVMAP_ DEVICE_GET_NAME:760 devmap_ get_name(callid, &call);1024 devmap_device_get_handle(callid, &call); 1025 break; 1026 case DEVMAP_NAMESPACE_GET_HANDLE: 1027 devmap_namespace_get_handle(callid, &call); 761 1028 break; 762 1029 default: … … 793 1060 continue; 794 1061 case DEVMAP_DEVICE_GET_HANDLE: 795 devmap_get_handle(callid, &call); 796 break; 797 case DEVMAP_DEVICE_GET_NAME: 798 devmap_get_name(callid, &call); 799 break; 800 case DEVMAP_DEVICE_NULL_CREATE: 1062 devmap_device_get_handle(callid, &call); 1063 break; 1064 case DEVMAP_NAMESPACE_GET_HANDLE: 1065 devmap_namespace_get_handle(callid, &call); 1066 break; 1067 case DEVMAP_HANDLE_PROBE: 1068 devmap_handle_probe(callid, &call); 1069 break; 1070 case DEVMAP_NULL_CREATE: 801 1071 devmap_null_create(callid, &call); 802 1072 break; 803 case DEVMAP_ DEVICE_NULL_DESTROY:1073 case DEVMAP_NULL_DESTROY: 804 1074 devmap_null_destroy(callid, &call); 805 1075 break; 806 case DEVMAP_DEVICE_GET_COUNT: 807 devmap_get_count(callid, &call); 808 break; 809 case DEVMAP_DEVICE_GET_DEVICES: 1076 case DEVMAP_GET_NAMESPACE_COUNT: 1077 devmap_get_namespace_count(callid, &call); 1078 break; 1079 case DEVMAP_GET_DEVICE_COUNT: 1080 devmap_get_device_count(callid, &call); 1081 break; 1082 case DEVMAP_GET_NAMESPACES: 1083 devmap_get_namespaces(callid, &call); 1084 break; 1085 case DEVMAP_GET_DEVICES: 810 1086 devmap_get_devices(callid, &call); 811 1087 break; … … 867 1143 } 868 1144 869 /** 1145 /** 870 1146 * @} 871 1147 */
Note:
See TracChangeset
for help on using the changeset viewer.