Changes in uspace/srv/devmap/devmap.c [1313ee9:0da4e41] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devmap/devmap.c
r1313ee9 r0da4e41 42 42 #include <errno.h> 43 43 #include <bool.h> 44 #include <fibril_sync h.h>44 #include <fibril_sync.h> 45 45 #include <stdlib.h> 46 46 #include <string.h> … … 68 68 } devmap_driver_t; 69 69 70 /** Info about registered namespaces71 *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 84 70 /** Info about registered device 85 71 * … … 91 77 owned by one driver */ 92 78 link_t driver_devices; 93 /** Unique device identifier */79 /** Unique device identifier */ 94 80 dev_handle_t handle; 95 /** Device namespace */96 devmap_namespace_t *namespace;97 81 /** Device name */ 98 82 char *name; … … 102 86 103 87 LIST_INITIALIZE(devices_list); 104 LIST_INITIALIZE(namespaces_list);105 88 LIST_INITIALIZE(drivers_list); 106 89 … … 134 117 } 135 118 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; 119 /** Find device with given name. 120 * 121 */ 122 static devmap_device_t *devmap_device_find_name(const char *name) 123 { 124 link_t *item = devices_list.next; 125 devmap_device_t *device = NULL; 126 127 while (item != &devices_list) { 128 device = list_get_instance(item, devmap_device_t, devices); 129 if (str_cmp(device->name, name) == 0) 130 break; 210 131 item = item->next; 211 132 } 212 133 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. 134 if (item == &devices_list) 135 return NULL; 136 137 device = list_get_instance(item, devmap_device_t, devices); 138 return device; 139 } 140 141 /** Find device with given handle. 220 142 * 221 143 * @todo: use hash table 222 144 * 223 145 */ 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 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; 233 157 item = item->next; 234 158 } 235 159 236 return NULL; 237 } 238 239 /** Find device with given name. 240 * 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) 247 { 248 link_t *item = devices_list.next; 249 250 while (item != &devices_list) { 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; 254 item = item->next; 255 } 256 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) 160 if (item == &devices_list) { 161 fibril_mutex_unlock(&devices_list_mutex); 297 162 return NULL; 298 299 namespace->name = str_dup(ns_name); 300 if (namespace->name == NULL) { 301 free(namespace); 302 return NULL; 303 } 304 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); 163 } 164 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 { 366 178 list_remove(&(device->devices)); 367 179 list_remove(&(device->driver_devices)); 368 180 369 free(device->namespace);370 181 free(device->name); 371 182 free(device); 183 184 return EOK; 372 185 } 373 186 … … 376 189 * drivers. 377 190 */ 378 static devmap_driver_t *devmap_driver_register(void) 379 { 191 static void devmap_driver_register(devmap_driver_t **odriver) 192 { 193 *odriver = NULL; 194 380 195 ipc_call_t icall; 381 196 ipc_callid_t iid = async_get_call(&icall); … … 383 198 if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) { 384 199 ipc_answer_0(iid, EREFUSED); 385 return NULL;200 return; 386 201 } 387 202 … … 390 205 if (driver == NULL) { 391 206 ipc_answer_0(iid, ENOMEM); 392 return NULL;207 return; 393 208 } 394 209 … … 396 211 * Get driver name 397 212 */ 398 int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN); 399 if (rc != EOK) { 213 ipc_callid_t callid; 214 size_t name_size; 215 if (!async_data_write_receive(&callid, &name_size)) { 400 216 free(driver); 401 ipc_answer_0(iid, rc); 402 return NULL; 403 } 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; 404 251 405 252 /* Initialize mutex for list of devices owned by this driver */ … … 415 262 */ 416 263 ipc_call_t call; 417 ipc_callid_tcallid = async_get_call(&call);264 callid = async_get_call(&call); 418 265 419 266 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { … … 423 270 free(driver); 424 271 ipc_answer_0(iid, ENOTSUP); 425 return NULL;272 return; 426 273 } 427 274 … … 446 293 ipc_answer_0(iid, EOK); 447 294 448 returndriver;295 *odriver = driver; 449 296 } 450 297 … … 508 355 } 509 356 510 /* Get fqdn*/511 char *fqdn;512 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);513 if ( rc != EOK) {357 /* Get device name */ 358 ipc_callid_t callid; 359 size_t size; 360 if (!async_data_write_receive(&callid, &size)) { 514 361 free(device); 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); 362 ipc_answer_0(iid, EREFUSED); 363 return; 364 } 365 366 if (size > DEVMAP_NAME_MAXLEN) { 522 367 free(device); 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); 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) { 535 377 free(device); 536 ipc_answer_0(iid, ENOMEM); 537 return; 538 } 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; 539 385 540 386 list_initialize(&(device->devices)); 541 387 list_initialize(&(device->driver_devices)); 542 388 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); 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); 547 394 fibril_mutex_unlock(&devices_list_mutex); 548 free(device->namespace);549 395 free(device->name); 550 396 free(device); … … 556 402 device->handle = devmap_create_handle(); 557 403 558 devmap_namespace_addref(namespace, device);559 404 device->driver = driver; 560 405 … … 592 437 static void devmap_forward(ipc_callid_t callid, ipc_call_t *call) 593 438 { 594 fibril_mutex_lock(&devices_list_mutex);595 596 439 /* 597 440 * Get handle from request … … 607 450 ipc_forward_fast(callid, dev->driver->phone, dev->handle, 608 451 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 609 610 fibril_mutex_unlock(&devices_list_mutex);611 452 } 612 453 … … 617 458 * 618 459 */ 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); 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'; 639 500 640 501 fibril_mutex_lock(&devices_list_mutex); 641 502 const devmap_device_t *dev; 642 643 503 recheck: 644 504 645 505 /* 646 506 * Find device name in the list of known devices. 647 507 */ 648 dev = devmap_device_find_name(n s_name, name);508 dev = devmap_device_find_name(name); 649 509 650 510 /* … … 652 512 */ 653 513 if (dev == NULL) { 654 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {655 /* Blocking lookup */656 fibril_condvar_wait(&devices_list_cv,657 &devices_list_mutex);658 goto recheck;659 }660 661 ipc_answer_0(iid, ENOENT);662 free(ns_name);663 free(name);664 fibril_mutex_unlock(&devices_list_mutex);665 return;666 }667 fibril_mutex_unlock(&devices_list_mutex);668 669 ipc_answer_1(iid, EOK, dev->handle);670 free(ns_name);671 free(name);672 }673 674 /** Find handle for namespace identified by name.675 *676 * In answer will be send EOK and device handle in arg1 or a error677 * 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:695 696 /*697 * Find namespace name in the list of known namespaces.698 */699 namespace = devmap_namespace_find_name(name);700 701 /*702 * Namespace was not found.703 */704 if (namespace == NULL) {705 514 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { 706 515 /* Blocking lookup */ … … 717 526 fibril_mutex_unlock(&devices_list_mutex); 718 527 719 ipc_answer_1(iid, EOK, namespace->handle);528 ipc_answer_1(iid, EOK, dev->handle); 720 529 free(name); 721 530 } 722 531 723 static void devmap_handle_probe(ipc_callid_t iid, ipc_call_t *icall) 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)); 538 539 /* 540 * Device not found. 541 */ 542 if (device == NULL) { 543 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) 724 566 { 725 567 fibril_mutex_lock(&devices_list_mutex); 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 568 ipc_answer_1(iid, EOK, list_count(&devices_list)); 737 569 fibril_mutex_unlock(&devices_list_mutex); 738 570 } 739 571 740 static void devmap_get_ namespace_count(ipc_callid_t iid, ipc_call_t *icall)572 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall) 741 573 { 742 574 fibril_mutex_lock(&devices_list_mutex); 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 { 575 762 576 ipc_callid_t callid; 763 577 size_t size; … … 770 584 if ((size % sizeof(dev_desc_t)) != 0) { 771 585 ipc_answer_0(callid, EINVAL); 772 ipc_answer_0(iid, EINVAL); 773 return; 774 } 775 776 fibril_mutex_lock(&devices_list_mutex); 586 ipc_answer_0(iid, EREFUSED); 587 return; 588 } 777 589 778 590 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 591 dev_desc_t *desc = (dev_desc_t *) malloc(size); 786 592 if (desc == NULL) { 787 593 ipc_answer_0(callid, ENOMEM); 788 ipc_answer_0(iid, ENOMEM); 789 return; 790 } 791 792 link_t *item = namespaces_list.next; 594 ipc_answer_0(iid, EREFUSED); 595 return; 596 } 597 793 598 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 use815 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);821 ipc_answer_0(iid, EREFUSED);822 return;823 }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 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 848 dev_desc_t *desc = (dev_desc_t *) malloc(size);849 if (desc == NULL) {850 ipc_answer_0(callid, ENOMEM);851 ipc_answer_0(iid, EREFUSED);852 return;853 }854 855 599 link_t *item = devices_list.next; 856 size_t pos = 0;857 while ( item != &devices_list) {600 601 while ((item != &devices_list) && (pos < count)) { 858 602 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 859 603 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 604 desc[pos].handle = device->handle; 605 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 606 pos++; 866 607 item = item->next; 867 608 } 868 609 869 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 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 } 870 616 871 617 free(desc); 618 872 619 fibril_mutex_unlock(&devices_list_mutex); 873 620 874 ipc_answer_ 0(iid, retval);621 ipc_answer_1(iid, EOK, pos); 875 622 } 876 623 … … 895 642 } 896 643 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 644 /* Create NULL device entry */ 907 645 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); 908 646 if (device == NULL) { … … 912 650 } 913 651 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);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) { 919 657 fibril_mutex_unlock(&null_devices_mutex); 658 free(device); 920 659 ipc_answer_0(iid, ENOMEM); 921 660 return; … … 924 663 list_initialize(&(device->devices)); 925 664 list_initialize(&(device->driver_devices)); 665 666 fibril_mutex_lock(&devices_list_mutex); 926 667 927 668 /* Get unique device handle */ 928 669 device->handle = devmap_create_handle(); 929 670 device->driver = NULL; 930 931 devmap_namespace_addref(namespace, device);932 device->name = dev_name;933 671 934 672 /* Insert device into list of all devices … … 954 692 } 955 693 956 fibril_mutex_lock(&devices_list_mutex);957 694 devmap_device_unregister_core(null_devices[i]); 958 fibril_mutex_unlock(&devices_list_mutex);959 960 695 null_devices[i] = NULL; 961 696 … … 990 725 ipc_answer_0(iid, EOK); 991 726 992 devmap_driver_t *driver = devmap_driver_register(); 993 if (driver == NULL) 727 devmap_driver_t *driver = NULL; 728 devmap_driver_register(&driver); 729 730 if (NULL == driver) 994 731 return; 995 732 … … 1018 755 break; 1019 756 case DEVMAP_DEVICE_GET_HANDLE: 1020 devmap_ device_get_handle(callid, &call);1021 break; 1022 case DEVMAP_ NAMESPACE_GET_HANDLE:1023 devmap_ namespace_get_handle(callid, &call);757 devmap_get_handle(callid, &call); 758 break; 759 case DEVMAP_DEVICE_GET_NAME: 760 devmap_get_name(callid, &call); 1024 761 break; 1025 762 default: … … 1056 793 continue; 1057 794 case DEVMAP_DEVICE_GET_HANDLE: 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: 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: 1067 801 devmap_null_create(callid, &call); 1068 802 break; 1069 case DEVMAP_ NULL_DESTROY:803 case DEVMAP_DEVICE_NULL_DESTROY: 1070 804 devmap_null_destroy(callid, &call); 1071 805 break; 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: 806 case DEVMAP_DEVICE_GET_COUNT: 807 devmap_get_count(callid, &call); 808 break; 809 case DEVMAP_DEVICE_GET_DEVICES: 1082 810 devmap_get_devices(callid, &call); 1083 811 break; … … 1139 867 } 1140 868 1141 /** 869 /** 1142 870 * @} 1143 871 */
Note:
See TracChangeset
for help on using the changeset viewer.