Changeset 7bdcc45 in mainline for uspace/srv/devman
- Timestamp:
- 2010-12-16T16:38:49Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7837101
- Parents:
- 8e58f94 (diff), eb221e5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/srv/devman
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r8e58f94 r7bdcc45 498 498 * @param phone The phone to the driver. 499 499 */ 500 void set_driver_phone(driver_t *driver, ipcarg_t phone)500 void set_driver_phone(driver_t *driver, sysarg_t phone) 501 501 { 502 502 fibril_mutex_lock(&driver->driver_mutex); … … 508 508 /** Notify driver about the devices to which it was assigned. 509 509 * 510 * The driver's mutex must be locked.511 *512 510 * @param driver The driver to which the devices are passed. 513 511 */ … … 518 516 int phone; 519 517 520 printf(NAME ": pass_devices_to_driver\n"); 521 522 phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0); 523 if (phone > 0) { 524 518 printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name); 519 520 fibril_mutex_lock(&driver->driver_mutex); 521 522 phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0); 523 524 if (phone < 0) { 525 fibril_mutex_unlock(&driver->driver_mutex); 526 return; 527 } 528 529 /* 530 * Go through devices list as long as there is some device 531 * that has not been passed to the driver. 532 */ 533 link = driver->devices.next; 534 while (link != &driver->devices) { 535 dev = list_get_instance(link, node_t, driver_devices); 536 if (dev->passed_to_driver) { 537 link = link->next; 538 continue; 539 } 540 541 /* 542 * We remove the device from the list to allow safe adding 543 * of new devices (no one will touch our item this way). 544 */ 545 list_remove(link); 546 547 /* 548 * Unlock to avoid deadlock when adding device 549 * handled by itself. 550 */ 551 fibril_mutex_unlock(&driver->driver_mutex); 552 553 add_device(phone, driver, dev, tree); 554 555 /* 556 * Lock again as we will work with driver's 557 * structure. 558 */ 559 fibril_mutex_lock(&driver->driver_mutex); 560 561 /* 562 * Insert the device back. 563 * The order is not relevant here so no harm is done 564 * (actually, the order would be preserved in most cases). 565 */ 566 list_append(link, &driver->devices); 567 568 /* 569 * Restart the cycle to go through all devices again. 570 */ 525 571 link = driver->devices.next; 526 while (link != &driver->devices) { 527 dev = list_get_instance(link, node_t, driver_devices); 528 add_device(phone, driver, dev, tree); 529 link = link->next; 530 } 531 532 ipc_hangup(phone); 533 } 572 } 573 574 ipc_hangup(phone); 575 576 /* 577 * Once we passed all devices to the driver, we need to mark the 578 * driver as running. 579 * It is vital to do it here and inside critical section. 580 * 581 * If we would change the state earlier, other devices added to 582 * the driver would be added to the device list and started 583 * immediately and possibly started here as well. 584 */ 585 printf(NAME ": driver %s goes into running state.\n", driver->name); 586 driver->state = DRIVER_RUNNING; 587 588 fibril_mutex_unlock(&driver->driver_mutex); 534 589 } 535 590 … … 545 600 void initialize_running_driver(driver_t *driver, dev_tree_t *tree) 546 601 { 547 printf(NAME ": initialize_running_driver\n"); 548 fibril_mutex_lock(&driver->driver_mutex); 602 printf(NAME ": initialize_running_driver (`%s')\n", driver->name); 549 603 550 604 /* … … 553 607 */ 554 608 pass_devices_to_driver(driver, tree); 555 556 /* Change driver's state to running. */557 driver->state = DRIVER_RUNNING;558 559 fibril_mutex_unlock(&driver->driver_mutex);560 609 } 561 610 … … 629 678 } 630 679 631 632 680 /** Pass a device to running driver. 633 681 * … … 637 685 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) 638 686 { 639 printf(NAME ": add_device\n"); 640 641 ipcarg_t rc; 687 /* 688 * We do not expect to have driver's mutex locked as we do not 689 * access any structures that would affect driver_t. 690 */ 691 printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name, 692 node->name); 693 694 sysarg_t rc; 642 695 ipc_call_t answer; 643 696 644 697 /* Send the device to the driver. */ 645 aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle, 646 &answer); 698 devman_handle_t parent_handle; 699 if (node->parent) { 700 parent_handle = node->parent->handle; 701 } else { 702 parent_handle = 0; 703 } 704 705 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle, 706 parent_handle, &answer); 647 707 648 708 /* Send the device's name to the driver. */ … … 652 712 /* TODO handle error */ 653 713 } 654 714 655 715 /* Wait for answer from the driver. */ 656 716 async_wait_for(req, &rc); 717 657 718 switch(rc) { 658 719 case EOK: … … 667 728 } 668 729 730 node->passed_to_driver = true; 731 669 732 return; 670 733 } … … 692 755 attach_driver(node, drv); 693 756 757 fibril_mutex_lock(&drv->driver_mutex); 694 758 if (drv->state == DRIVER_NOT_STARTED) { 695 759 /* Start the driver. */ 696 760 start_driver(drv); 697 761 } 698 699 if (drv->state == DRIVER_RUNNING) { 762 bool is_running = drv->state == DRIVER_RUNNING; 763 fibril_mutex_unlock(&drv->driver_mutex); 764 765 if (is_running) { 700 766 /* Notify the driver about the new device. */ 701 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);767 int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 702 768 if (phone > 0) { 703 769 add_device(phone, drv, node, tree); … … 861 927 node->name = dev_name; 862 928 if (!set_dev_path(node, parent)) { 863 fibril_rwlock_write_unlock(&tree->rwlock);864 929 return false; 865 930 } … … 1014 1079 1015 1080 size_t idx = get_new_class_dev_idx(cl); 1016 asprintf(&dev_name, "%s% d", base_name, idx);1081 asprintf(&dev_name, "%s%zu", base_name, idx); 1017 1082 1018 1083 return dev_name; … … 1083 1148 while (link != &class_list->classes) { 1084 1149 cl = list_get_instance(link, dev_class_t, link); 1085 if (str_cmp(cl->name, class_name) == 0) 1150 if (str_cmp(cl->name, class_name) == 0) { 1086 1151 return cl; 1152 } 1153 link = link->next; 1087 1154 } 1088 1155 -
uspace/srv/devman/devman.h
r8e58f94 r7bdcc45 86 86 87 87 /** Phone asociated with this driver. */ 88 ipcarg_t phone;88 sysarg_t phone; 89 89 /** Name of the device driver. */ 90 90 char *name; … … 168 168 */ 169 169 link_t devmap_link; 170 171 /** 172 * Whether this device was already passed to the driver. 173 */ 174 bool passed_to_driver; 170 175 }; 171 176 … … 297 302 298 303 extern driver_t *find_driver(driver_list_t *, const char *); 299 extern void set_driver_phone(driver_t *, ipcarg_t);304 extern void set_driver_phone(driver_t *, sysarg_t); 300 305 extern void initialize_running_driver(driver_t *, dev_tree_t *); 301 306 -
uspace/srv/devman/main.c
r8e58f94 r7bdcc45 36 36 */ 37 37 38 #include <inttypes.h> 38 39 #include <assert.h> 39 40 #include <ipc/services.h> … … 73 74 74 75 iid = async_get_call(&icall); 75 if (IPC_GET_ METHOD(icall) != DEVMAN_DRIVER_REGISTER) {76 if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) { 76 77 ipc_answer_0(iid, EREFUSED); 77 78 return NULL; … … 108 109 ipc_call_t call; 109 110 ipc_callid_t callid = async_get_call(&call); 110 if (IPC_GET_ METHOD(call) != IPC_M_CONNECT_TO_ME) {111 if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) { 111 112 ipc_answer_0(callid, ENOTSUP); 112 113 ipc_answer_0(iid, ENOTSUP); … … 140 141 141 142 callid = async_get_call(&call); 142 if (DEVMAN_ADD_MATCH_ID != IPC_GET_ METHOD(call)) {143 if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) { 143 144 printf(NAME ": ERROR: devman_receive_match_id - invalid " 144 145 "protocol.\n"); … … 183 184 * @return Zero on success, negative error code otherwise. 184 185 */ 185 static int devman_receive_match_ids( ipcarg_t match_count,186 static int devman_receive_match_ids(sysarg_t match_count, 186 187 match_id_list_t *match_ids) 187 188 { … … 196 197 } 197 198 199 static int assign_driver_fibril(void *arg) 200 { 201 node_t *node = (node_t *) arg; 202 assign_driver(node, &drivers_list, &device_tree); 203 return EOK; 204 } 205 198 206 /** Handle child device registration. 199 207 * … … 203 211 { 204 212 devman_handle_t parent_handle = IPC_GET_ARG1(*call); 205 ipcarg_t match_count = IPC_GET_ARG2(*call);213 sysarg_t match_count = IPC_GET_ARG2(*call); 206 214 dev_tree_t *tree = &device_tree; 207 215 … … 236 244 237 245 devman_receive_match_ids(match_count, &node->match_ids); 238 246 247 /* 248 * Try to find a suitable driver and assign it to the device. We do 249 * not want to block the current fibril that is used for processing 250 * incoming calls: we will launch a separate fibril to handle the 251 * driver assigning. That is because assign_driver can actually include 252 * task spawning which could take some time. 253 */ 254 fid_t assign_fibril = fibril_create(assign_driver_fibril, node); 255 if (assign_fibril == 0) { 256 /* 257 * Fallback in case we are out of memory. 258 * Probably not needed as we will die soon anyway ;-). 259 */ 260 (void) assign_driver_fibril(node); 261 } else { 262 fibril_add_ready(assign_fibril); 263 } 264 239 265 /* Return device handle to parent's driver. */ 240 266 ipc_answer_1(callid, EOK, node->handle); 241 242 /* Try to find suitable driver and assign it to the device. */243 assign_driver(node, &drivers_list, &device_tree);244 267 } 245 268 … … 296 319 printf(NAME ": device '%s' added to class '%s', class name '%s' was " 297 320 "asigned to it\n", dev->pathname, class_name, class_info->dev_name); 298 321 299 322 ipc_answer_0(callid, EOK); 300 323 } … … 344 367 callid = async_get_call(&call); 345 368 346 switch (IPC_GET_ METHOD(call)) {369 switch (IPC_GET_IMETHOD(call)) { 347 370 case IPC_M_PHONE_HUNGUP: 348 371 cont = false; … … 397 420 ipc_callid_t callid = async_get_call(&call); 398 421 399 switch (IPC_GET_ METHOD(call)) {422 switch (IPC_GET_IMETHOD(call)) { 400 423 case IPC_M_PHONE_HUNGUP: 401 424 cont = false; … … 405 428 break; 406 429 default: 407 if (!(callid & IPC_CALLID_NOTIFICATION)) 408 ipc_answer_0(callid, ENOENT); 430 ipc_answer_0(callid, ENOENT); 409 431 } 410 432 } … … 418 440 node_t *dev = find_dev_node(&device_tree, handle); 419 441 if (dev == NULL) { 420 printf(NAME ": devman_forward error - no device with handle % x "421 " was found.\n", handle);442 printf(NAME ": devman_forward error - no device with handle %" PRIun 443 " was found.\n", handle); 422 444 ipc_answer_0(iid, ENOENT); 423 445 return; … … 435 457 436 458 if (driver == NULL) { 437 printf(NAME ": devman_forward error - the device is not in "438 " usable state.\n", handle);459 printf(NAME ": devman_forward error - the device is not in %" PRIun 460 " usable state.\n", handle); 439 461 ipc_answer_0(iid, ENOENT); 440 462 return; … … 450 472 printf(NAME ": devman_forward: cound not forward to driver %s ", 451 473 driver->name); 452 printf("the driver's phone is % x).\n", driver->phone);474 printf("the driver's phone is %" PRIun ").\n", driver->phone); 453 475 ipc_answer_0(iid, EINVAL); 454 476 return; … … 464 486 static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall) 465 487 { 466 devmap_handle_t devmap_handle = IPC_GET_ METHOD(*icall);488 devmap_handle_t devmap_handle = IPC_GET_IMETHOD(*icall); 467 489 node_t *dev; 468 490 … … 499 521 * passes device handle to the driver as an ipc method.) 500 522 */ 501 if (IPC_GET_ METHOD(*icall) != IPC_M_CONNECT_ME_TO)523 if (IPC_GET_IMETHOD(*icall) != IPC_M_CONNECT_ME_TO) 502 524 devman_connection_devmapper(iid, icall); 503 525 … … 509 531 510 532 /* Select interface. */ 511 switch (( ipcarg_t) (IPC_GET_ARG1(*icall))) {533 switch ((sysarg_t) (IPC_GET_ARG1(*icall))) { 512 534 case DEVMAN_DRIVER: 513 535 devman_connection_driver(iid, icall); … … 577 599 578 600 /* Register device manager at naming service. */ 579 ipcarg_t phonead;601 sysarg_t phonead; 580 602 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) 581 603 return -1; -
uspace/srv/devman/match.c
r8e58f94 r7bdcc45 35 35 #include "devman.h" 36 36 37 /** Compute compound score of driver and device. 38 * 39 * @param driver Match id of the driver. 40 * @param device Match id of the device. 41 * @return Compound score. 42 * @retval 0 No match at all. 43 */ 44 static int compute_match_score(match_id_t *driver, match_id_t *device) 45 { 46 if (str_cmp(driver->id, device->id) == 0) { 47 /* 48 * The strings match, return the product of their scores. 49 */ 50 return driver->score * device->score; 51 } else { 52 /* 53 * Different strings, return zero. 54 */ 55 return 0; 56 } 57 } 58 37 59 int get_match_score(driver_t *drv, node_t *dev) 38 60 { … … 43 65 return 0; 44 66 67 /* 68 * Go through all pairs, return the highest score obtained. 69 */ 70 int highest_score = 0; 71 45 72 link_t *drv_link = drv->match_ids.ids.next; 46 link_t *dev_link = dev->match_ids.ids.next; 47 48 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link); 49 match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link); 50 51 int score_next_drv = 0; 52 int score_next_dev = 0; 53 54 do { 55 match_id_t *tmp_ma_id; 56 57 if (str_cmp(drv_id->id, dev_id->id) == 0) { 58 /* 59 * We found a match. 60 * Return the score of the match. 61 */ 62 return drv_id->score * dev_id->score; 73 while (drv_link != drv_head) { 74 link_t *dev_link = dev_head->next; 75 while (dev_link != dev_head) { 76 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link); 77 match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link); 78 79 int score = compute_match_score(drv_id, dev_id); 80 if (score > highest_score) { 81 highest_score = score; 82 } 83 84 dev_link = dev_link->next; 63 85 } 64 86 65 /* 66 * Compute the next score we get, if we advance in the driver's 67 * list of match ids. 68 */ 69 if (drv_link->next != drv_head) { 70 tmp_ma_id = list_get_instance(drv_link->next, 71 match_id_t, link); 72 score_next_drv = dev_id->score * tmp_ma_id->score; 73 } else { 74 score_next_drv = 0; 75 } 76 77 /* 78 * Compute the next score we get, if we advance in the device's 79 * list of match ids. 80 */ 81 if (dev_link->next != dev_head) { 82 tmp_ma_id = list_get_instance(dev_link->next, 83 match_id_t, link); 84 score_next_dev = drv_id->score * tmp_ma_id->score; 85 } else { 86 score_next_dev = 0; 87 } 88 89 /* 90 * Advance in one of the two lists, so we get the next highest 91 * score. 92 */ 93 if (score_next_drv > score_next_dev) { 94 drv_link = drv_link->next; 95 drv_id = list_get_instance(drv_link, match_id_t, link); 96 } else { 97 dev_link = dev_link->next; 98 dev_id = list_get_instance(dev_link, match_id_t, link); 99 } 100 101 } while (drv_link->next != drv_head && dev_link->next != dev_head); 87 drv_link = drv_link->next; 88 } 102 89 103 return 0;90 return highest_score; 104 91 } 105 92
Note:
See TracChangeset
for help on using the changeset viewer.