Changes in uspace/srv/devmap/devmap.c [a405563:1313ee9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devmap/devmap.c
ra405563 r1313ee9 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 46 #include <string.h> … … 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 ipc_callid_t callid; 214 size_t name_size; 215 if (!ipc_data_write_receive(&callid, &name_size)) { 398 int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN); 399 if (rc != EOK) { 216 400 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 (ipc_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; 401 ipc_answer_0(iid, rc); 402 return NULL; 403 } 251 404 252 405 /* Initialize mutex for list of devices owned by this driver */ … … 262 415 */ 263 416 ipc_call_t call; 264 callid = async_get_call(&call);417 ipc_callid_t callid = async_get_call(&call); 265 418 266 419 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { … … 270 423 free(driver); 271 424 ipc_answer_0(iid, ENOTSUP); 272 return ;425 return NULL; 273 426 } 274 427 … … 293 446 ipc_answer_0(iid, EOK); 294 447 295 *odriver =driver;448 return driver; 296 449 } 297 450 … … 355 508 } 356 509 357 /* Get device name*/358 ipc_callid_t callid;359 size_t size;360 if ( !ipc_data_write_receive(&callid, &size)) {510 /* Get fqdn */ 511 char *fqdn; 512 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 513 if (rc != EOK) { 361 514 free(device); 362 ipc_answer_0(iid, EREFUSED); 363 return; 364 } 365 366 if (size > DEVMAP_NAME_MAXLEN) { 515 ipc_answer_0(iid, rc); 516 return; 517 } 518 519 char *ns_name; 520 if (!devmap_fqdn_split(fqdn, &ns_name, &device->name)) { 521 free(fqdn); 367 522 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) { 523 ipc_answer_0(iid, EINVAL); 524 return; 525 } 526 527 free(fqdn); 528 529 fibril_mutex_lock(&devices_list_mutex); 530 531 devmap_namespace_t *namespace = devmap_namespace_create(ns_name); 532 free(ns_name); 533 if (!namespace) { 534 fibril_mutex_unlock(&devices_list_mutex); 377 535 free(device); 378 ipc_answer_0(callid, ENOMEM); 379 ipc_answer_0(iid, EREFUSED); 380 return; 381 } 382 383 ipc_data_write_finalize(callid, device->name, size); 384 device->name[size] = 0; 536 ipc_answer_0(iid, ENOMEM); 537 return; 538 } 385 539 386 540 list_initialize(&(device->devices)); 387 541 list_initialize(&(device->driver_devices)); 388 542 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); 543 /* Check that device is not already registered */ 544 if (devmap_device_find_name(namespace->name, device->name) != NULL) { 545 printf(NAME ": Device '%s/%s' already registered\n", device->namespace, device->name); 546 devmap_namespace_destroy(namespace); 394 547 fibril_mutex_unlock(&devices_list_mutex); 548 free(device->namespace); 395 549 free(device->name); 396 550 free(device); … … 402 556 device->handle = devmap_create_handle(); 403 557 558 devmap_namespace_addref(namespace, device); 404 559 device->driver = driver; 405 560 … … 437 592 static void devmap_forward(ipc_callid_t callid, ipc_call_t *call) 438 593 { 594 fibril_mutex_lock(&devices_list_mutex); 595 439 596 /* 440 597 * Get handle from request … … 450 607 ipc_forward_fast(callid, dev->driver->phone, dev->handle, 451 608 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 609 610 fibril_mutex_unlock(&devices_list_mutex); 452 611 } 453 612 … … 458 617 * 459 618 */ 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 (!ipc_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 = ipc_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'; 619 static void devmap_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 620 { 621 char *fqdn; 622 623 /* Get fqdn */ 624 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 625 if (rc != EOK) { 626 ipc_answer_0(iid, rc); 627 return; 628 } 629 630 char *ns_name; 631 char *name; 632 if (!devmap_fqdn_split(fqdn, &ns_name, &name)) { 633 free(fqdn); 634 ipc_answer_0(iid, EINVAL); 635 return; 636 } 637 638 free(fqdn); 500 639 501 640 fibril_mutex_lock(&devices_list_mutex); 502 641 const devmap_device_t *dev; 642 503 643 recheck: 504 644 505 645 /* 506 646 * Find device name in the list of known devices. 507 647 */ 508 dev = devmap_device_find_name(n ame);648 dev = devmap_device_find_name(ns_name, name); 509 649 510 650 /* … … 520 660 521 661 ipc_answer_0(iid, ENOENT); 662 free(ns_name); 522 663 free(name); 523 664 fibril_mutex_unlock(&devices_list_mutex); … … 527 668 528 669 ipc_answer_1(iid, EOK, dev->handle); 670 free(ns_name); 529 671 free(name); 530 672 } 531 673 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)); 674 /** Find handle for namespace identified by name. 675 * 676 * In answer will be send EOK and device handle in arg1 or a error 677 * code from errno.h. 678 * 679 */ 680 static void devmap_namespace_get_handle(ipc_callid_t iid, ipc_call_t *icall) 681 { 682 char *name; 683 684 /* Get device name */ 685 int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN); 686 if (rc != EOK) { 687 ipc_answer_0(iid, rc); 688 return; 689 } 690 691 fibril_mutex_lock(&devices_list_mutex); 692 const devmap_namespace_t *namespace; 693 694 recheck: 538 695 539 696 /* 540 * Device not found.697 * Find namespace name in the list of known namespaces. 541 698 */ 542 if (device == NULL) { 699 namespace = devmap_namespace_find_name(name); 700 701 /* 702 * Namespace was not found. 703 */ 704 if (namespace == NULL) { 705 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { 706 /* Blocking lookup */ 707 fibril_condvar_wait(&devices_list_cv, 708 &devices_list_mutex); 709 goto recheck; 710 } 711 543 712 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 = ipc_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) 713 free(name); 714 fibril_mutex_unlock(&devices_list_mutex); 715 return; 716 } 717 fibril_mutex_unlock(&devices_list_mutex); 718 719 ipc_answer_1(iid, EOK, namespace->handle); 720 free(name); 721 } 722 723 static void devmap_handle_probe(ipc_callid_t iid, ipc_call_t *icall) 566 724 { 567 725 fibril_mutex_lock(&devices_list_mutex); 568 ipc_answer_1(iid, EOK, list_count(&devices_list)); 726 727 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 728 if (namespace == NULL) { 729 devmap_device_t *dev = devmap_device_find_handle(IPC_GET_ARG1(*icall)); 730 if (dev == NULL) 731 ipc_answer_1(iid, EOK, DEV_HANDLE_NONE); 732 else 733 ipc_answer_1(iid, EOK, DEV_HANDLE_DEVICE); 734 } else 735 ipc_answer_1(iid, EOK, DEV_HANDLE_NAMESPACE); 736 569 737 fibril_mutex_unlock(&devices_list_mutex); 570 738 } 571 739 572 static void devmap_get_ devices(ipc_callid_t iid, ipc_call_t *icall)740 static void devmap_get_namespace_count(ipc_callid_t iid, ipc_call_t *icall) 573 741 { 574 742 fibril_mutex_lock(&devices_list_mutex); 575 743 ipc_answer_1(iid, EOK, list_count(&namespaces_list)); 744 fibril_mutex_unlock(&devices_list_mutex); 745 } 746 747 static void devmap_get_device_count(ipc_callid_t iid, ipc_call_t *icall) 748 { 749 fibril_mutex_lock(&devices_list_mutex); 750 751 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 752 if (namespace == NULL) 753 ipc_answer_0(iid, EEXISTS); 754 else 755 ipc_answer_1(iid, EOK, namespace->refcnt); 756 757 fibril_mutex_unlock(&devices_list_mutex); 758 } 759 760 static void devmap_get_namespaces(ipc_callid_t iid, ipc_call_t *icall) 761 { 576 762 ipc_callid_t callid; 577 763 size_t size; 578 if (! ipc_data_read_receive(&callid, &size)) {764 if (!async_data_read_receive(&callid, &size)) { 579 765 ipc_answer_0(callid, EREFUSED); 580 766 ipc_answer_0(iid, EREFUSED); … … 584 770 if ((size % sizeof(dev_desc_t)) != 0) { 585 771 ipc_answer_0(callid, EINVAL); 772 ipc_answer_0(iid, EINVAL); 773 return; 774 } 775 776 fibril_mutex_lock(&devices_list_mutex); 777 778 size_t count = size / sizeof(dev_desc_t); 779 if (count != list_count(&namespaces_list)) { 780 ipc_answer_0(callid, EOVERFLOW); 781 ipc_answer_0(iid, EOVERFLOW); 782 return; 783 } 784 785 dev_desc_t *desc = (dev_desc_t *) malloc(size); 786 if (desc == NULL) { 787 ipc_answer_0(callid, ENOMEM); 788 ipc_answer_0(iid, ENOMEM); 789 return; 790 } 791 792 link_t *item = namespaces_list.next; 793 size_t pos = 0; 794 while (item != &namespaces_list) { 795 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 796 797 desc[pos].handle = namespace->handle; 798 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, namespace->name); 799 pos++; 800 801 item = item->next; 802 } 803 804 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 805 806 free(desc); 807 fibril_mutex_unlock(&devices_list_mutex); 808 809 ipc_answer_0(iid, retval); 810 } 811 812 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall) 813 { 814 /* FIXME: Use faster algorithm which can make better use 815 of namespaces */ 816 817 ipc_callid_t callid; 818 size_t size; 819 if (!async_data_read_receive(&callid, &size)) { 820 ipc_answer_0(callid, EREFUSED); 586 821 ipc_answer_0(iid, EREFUSED); 587 822 return; 588 823 } 589 824 825 if ((size % sizeof(dev_desc_t)) != 0) { 826 ipc_answer_0(callid, EINVAL); 827 ipc_answer_0(iid, EINVAL); 828 return; 829 } 830 831 fibril_mutex_lock(&devices_list_mutex); 832 833 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 834 if (namespace == NULL) { 835 fibril_mutex_unlock(&devices_list_mutex); 836 ipc_answer_0(callid, ENOENT); 837 ipc_answer_0(iid, ENOENT); 838 return; 839 } 840 590 841 size_t count = size / sizeof(dev_desc_t); 842 if (count != namespace->refcnt) { 843 ipc_answer_0(callid, EOVERFLOW); 844 ipc_answer_0(iid, EOVERFLOW); 845 return; 846 } 847 591 848 dev_desc_t *desc = (dev_desc_t *) malloc(size); 592 849 if (desc == NULL) { … … 596 853 } 597 854 855 link_t *item = devices_list.next; 598 856 size_t pos = 0; 599 link_t *item = devices_list.next; 600 601 while ((item != &devices_list) && (pos < count)) { 857 while (item != &devices_list) { 602 858 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 603 859 604 desc[pos].handle = device->handle; 605 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 606 pos++; 860 if (device->namespace == namespace) { 861 desc[pos].handle = device->handle; 862 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 863 pos++; 864 } 865 607 866 item = item->next; 608 867 } 609 868 610 ipcarg_t retval = ipc_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 } 869 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 616 870 617 871 free(desc); 618 619 872 fibril_mutex_unlock(&devices_list_mutex); 620 873 621 ipc_answer_ 1(iid, EOK, pos);874 ipc_answer_0(iid, retval); 622 875 } 623 876 … … 642 895 } 643 896 644 /* Create NULL device entry */ 897 char null[DEVMAP_NAME_MAXLEN]; 898 snprintf(null, DEVMAP_NAME_MAXLEN, "%u", i); 899 900 char *dev_name = str_dup(null); 901 if (dev_name == NULL) { 902 fibril_mutex_unlock(&null_devices_mutex); 903 ipc_answer_0(iid, ENOMEM); 904 return; 905 } 906 645 907 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); 646 908 if (device == NULL) { … … 650 912 } 651 913 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) {914 fibril_mutex_lock(&devices_list_mutex); 915 916 devmap_namespace_t *namespace = devmap_namespace_create("null"); 917 if (!namespace) { 918 fibril_mutex_lock(&devices_list_mutex); 657 919 fibril_mutex_unlock(&null_devices_mutex); 658 free(device);659 920 ipc_answer_0(iid, ENOMEM); 660 921 return; … … 663 924 list_initialize(&(device->devices)); 664 925 list_initialize(&(device->driver_devices)); 665 666 fibril_mutex_lock(&devices_list_mutex);667 926 668 927 /* Get unique device handle */ 669 928 device->handle = devmap_create_handle(); 670 929 device->driver = NULL; 930 931 devmap_namespace_addref(namespace, device); 932 device->name = dev_name; 671 933 672 934 /* Insert device into list of all devices … … 692 954 } 693 955 956 fibril_mutex_lock(&devices_list_mutex); 694 957 devmap_device_unregister_core(null_devices[i]); 958 fibril_mutex_unlock(&devices_list_mutex); 959 695 960 null_devices[i] = NULL; 696 961 … … 725 990 ipc_answer_0(iid, EOK); 726 991 727 devmap_driver_t *driver = NULL; 728 devmap_driver_register(&driver); 729 730 if (NULL == driver) 992 devmap_driver_t *driver = devmap_driver_register(); 993 if (driver == NULL) 731 994 return; 732 995 … … 755 1018 break; 756 1019 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);1020 devmap_device_get_handle(callid, &call); 1021 break; 1022 case DEVMAP_NAMESPACE_GET_HANDLE: 1023 devmap_namespace_get_handle(callid, &call); 761 1024 break; 762 1025 default: … … 793 1056 continue; 794 1057 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: 1058 devmap_device_get_handle(callid, &call); 1059 break; 1060 case DEVMAP_NAMESPACE_GET_HANDLE: 1061 devmap_namespace_get_handle(callid, &call); 1062 break; 1063 case DEVMAP_HANDLE_PROBE: 1064 devmap_handle_probe(callid, &call); 1065 break; 1066 case DEVMAP_NULL_CREATE: 801 1067 devmap_null_create(callid, &call); 802 1068 break; 803 case DEVMAP_ DEVICE_NULL_DESTROY:1069 case DEVMAP_NULL_DESTROY: 804 1070 devmap_null_destroy(callid, &call); 805 1071 break; 806 case DEVMAP_DEVICE_GET_COUNT: 807 devmap_get_count(callid, &call); 808 break; 809 case DEVMAP_DEVICE_GET_DEVICES: 1072 case DEVMAP_GET_NAMESPACE_COUNT: 1073 devmap_get_namespace_count(callid, &call); 1074 break; 1075 case DEVMAP_GET_DEVICE_COUNT: 1076 devmap_get_device_count(callid, &call); 1077 break; 1078 case DEVMAP_GET_NAMESPACES: 1079 devmap_get_namespaces(callid, &call); 1080 break; 1081 case DEVMAP_GET_DEVICES: 810 1082 devmap_get_devices(callid, &call); 811 1083 break; … … 867 1139 } 868 1140 869 /** 1141 /** 870 1142 * @} 871 1143 */
Note:
See TracChangeset
for help on using the changeset viewer.