Changes in / [4006447:b38dfd8] in mainline
- Files:
-
- 3 added
- 13 deleted
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r4006447 rb38dfd8 545 545 % Line debugging information 546 546 ! [CONFIG_STRIP_BINARIES!=y] CONFIG_LINE_DEBUG (n/y) 547 548 % Launch (devman) test drivers549 ! [CONFIG_DEBUG=y] CONFIG_TEST_DRIVERS (y/n)550 -
boot/Makefile.common
r4006447 rb38dfd8 109 109 110 110 RD_DRVS = \ 111 root \ 112 rootvirt \ 113 test1 \ 114 test2 111 root 115 112 116 113 RD_DRV_CFG = -
boot/arch/amd64/Makefile.inc
r4006447 rb38dfd8 37 37 38 38 RD_DRVS += \ 39 root pc\39 rootia32 \ 40 40 pciintel \ 41 41 isa \ -
uspace/Makefile
r4006447 rb38dfd8 85 85 srv/net/tl/tcp \ 86 86 srv/net/net \ 87 drv/root \ 88 drv/rootvirt \ 89 drv/test1 \ 90 drv/test2 87 drv/root 91 88 92 89 ## Networking … … 111 108 112 109 ifeq ($(UARCH),amd64) 113 DIRS += drv/rootpc114 DIRS += drv/pciintel115 DIRS += drv/isa116 DIRS += drv/ns8250117 110 endif 118 111 119 112 ifeq ($(UARCH),ia32) 120 DIRS += drv/root pc113 DIRS += drv/rootia32 121 114 DIRS += drv/pciintel 122 115 DIRS += drv/isa -
uspace/drv/isa/isa.c
r4006447 rb38dfd8 282 282 283 283 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 "device %s\n", (unsigned int) addr, (unsigned int) len, 285 dev->name); 284 "device %s\n", addr, len, dev->name); 286 285 } 287 286 } … … 490 489 static int isa_add_device(device_t *dev) 491 490 { 492 printf(NAME ": isa_add_device, device handle = %d\n", 493 (int) dev->handle); 491 printf(NAME ": isa_add_device, device handle = %d\n", dev->handle); 494 492 495 493 /* Add child devices. */ -
uspace/drv/ns8250/ns8250.c
r4006447 rb38dfd8 274 274 275 275 /* Gain control over port's registers. */ 276 if (pio_enable((void *) (uintptr_t)data->io_addr, REG_COUNT,276 if (pio_enable((void *) data->io_addr, REG_COUNT, 277 277 (void **) &data->port)) { 278 278 printf(NAME ": error - cannot gain the port %#" PRIx32 " for device " … … 727 727 { 728 728 printf(NAME ": ns8250_add_device %s (handle = %d)\n", 729 dev->name, (int)dev->handle);729 dev->name, dev->handle); 730 730 731 731 int res = ns8250_dev_initialize(dev); -
uspace/drv/pciintel/pci.c
r4006447 rb38dfd8 324 324 printf(NAME ": device %s : ", dev->name); 325 325 printf("address = %" PRIx64, range_addr); 326 printf(", size = %x\n", (unsigned int)range_size);326 printf(", size = %x\n", range_size); 327 327 } 328 328 … … 489 489 (uint32_t) hw_resources.resources[0].res.io_range.address; 490 490 491 if (pio_enable((void *) (uintptr_t)bus_data->conf_io_addr, 8,491 if (pio_enable((void *)bus_data->conf_io_addr, 8, 492 492 &bus_data->conf_addr_port)) { 493 493 printf(NAME ": failed to enable configuration ports.\n"); -
uspace/drv/root/root.c
r4006447 rb38dfd8 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2010 Vojtech Horky4 3 * All rights reserved. 5 4 * … … 54 53 #define NAME "root" 55 54 56 #define PLATFORM_DEVICE_NAME "hw"57 #define PLATFORM_DEVICE_MATCH_ID STRING(UARCH)58 #define PLATFORM_DEVICE_MATCH_SCORE 10059 60 #define VIRTUAL_DEVICE_NAME "virt"61 #define VIRTUAL_DEVICE_MATCH_ID "rootvirt"62 #define VIRTUAL_DEVICE_MATCH_SCORE 10063 64 55 static int root_add_device(device_t *dev); 65 56 … … 75 66 }; 76 67 77 /** Create the device which represents the root of virtual device tree.78 *79 * @param parent Parent of the newly created device.80 * @return Error code.81 */82 static int add_virtual_root_child(device_t *parent)83 {84 printf(NAME ": adding new child for virtual devices.\n");85 printf(NAME ": device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME,86 VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID);87 88 int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME,89 VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE);90 91 return res;92 }93 94 68 /** Create the device which represents the root of HW device tree. 95 69 * … … 100 74 { 101 75 printf(NAME ": adding new child for platform device.\n"); 102 printf(NAME ": device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME,103 PLATFORM_DEVICE_MATCH_SCORE, PLATFORM_DEVICE_MATCH_ID);104 76 105 int res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME, 106 PLATFORM_DEVICE_MATCH_ID, PLATFORM_DEVICE_MATCH_SCORE); 107 77 int res = EOK; 78 device_t *platform = NULL; 79 match_id_t *match_id = NULL; 80 81 /* Create new device. */ 82 platform = create_device(); 83 if (NULL == platform) { 84 res = ENOMEM; 85 goto failure; 86 } 87 88 platform->name = "hw"; 89 printf(NAME ": the new device's name is %s.\n", platform->name); 90 91 /* Initialize match id list. */ 92 match_id = create_match_id(); 93 if (NULL == match_id) { 94 res = ENOMEM; 95 goto failure; 96 } 97 98 /* TODO - replace this with some better solution (sysinfo ?) */ 99 match_id->id = STRING(UARCH); 100 match_id->score = 100; 101 add_match_id(&platform->match_ids, match_id); 102 103 /* Register child device. */ 104 res = child_device_register(platform, parent); 105 if (EOK != res) 106 goto failure; 107 108 return res; 109 110 failure: 111 if (NULL != match_id) 112 match_id->id = NULL; 113 114 if (NULL != platform) { 115 platform->name = NULL; 116 delete_device(platform); 117 } 118 108 119 return res; 109 120 } … … 119 130 dev->handle); 120 131 121 /*122 * Register virtual devices root.123 * We ignore error occurrence because virtual devices shall not be124 * vital for the system.125 */126 add_virtual_root_child(dev);127 128 132 /* Register root device's children. */ 129 133 int res = add_platform_child(dev); -
uspace/lib/c/generic/devman.c
r4006447 rb38dfd8 116 116 { 117 117 ipc_call_t answer; 118 a id_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);118 async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer); 119 119 int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id)); 120 async_wait_for(req, NULL); 121 return retval; 120 return retval; 122 121 } 123 122 -
uspace/lib/drv/generic/driver.c
r4006447 rb38dfd8 165 165 166 166 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 167 devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);168 169 167 device_t *dev = create_device(); 170 168 dev->handle = dev_handle; … … 174 172 175 173 add_to_devices_list(dev); 176 dev->parent = driver_get_device(&devices, parent_dev_handle);177 178 174 res = driver->driver_ops->add_device(dev); 179 175 if (0 == res) { … … 381 377 } 382 378 383 /** Wrapper for child_device_register for devices with single match id.384 *385 * @param parent Parent device.386 * @param child_name Child device name.387 * @param child_match_id Child device match id.388 * @param child_match_score Child device match score.389 * @return Error code.390 */391 int child_device_register_wrapper(device_t *parent, const char *child_name,392 const char *child_match_id, int child_match_score)393 {394 device_t *child = NULL;395 match_id_t *match_id = NULL;396 int rc;397 398 child = create_device();399 if (child == NULL) {400 rc = ENOMEM;401 goto failure;402 }403 404 child->name = child_name;405 406 match_id = create_match_id();407 if (match_id == NULL) {408 rc = ENOMEM;409 goto failure;410 }411 412 match_id->id = child_match_id;413 match_id->score = child_match_score;414 add_match_id(&child->match_ids, match_id);415 416 rc = child_device_register(child, parent);417 if (EOK != rc)418 goto failure;419 420 return EOK;421 422 failure:423 if (match_id != NULL) {424 match_id->id = NULL;425 delete_match_id(match_id);426 }427 428 if (child != NULL) {429 child->name = NULL;430 delete_device(child);431 }432 433 return rc;434 }435 436 379 int driver_main(driver_t *drv) 437 380 { -
uspace/lib/drv/include/driver.h
r4006447 rb38dfd8 199 199 200 200 int child_device_register(device_t *, device_t *); 201 int child_device_register_wrapper(device_t *, const char *, const char *, int);202 201 203 202 -
uspace/srv/devman/devman.c
r4006447 rb38dfd8 508 508 /** Notify driver about the devices to which it was assigned. 509 509 * 510 * The driver's mutex must be locked. 511 * 510 512 * @param driver The driver to which the devices are passed. 511 513 */ … … 516 518 int phone; 517 519 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) { 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 525 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); 537 529 link = link->next; 538 continue;539 530 } 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 */ 571 link = driver->devices.next; 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); 531 532 ipc_hangup(phone); 533 } 589 534 } 590 535 … … 600 545 void initialize_running_driver(driver_t *driver, dev_tree_t *tree) 601 546 { 602 printf(NAME ": initialize_running_driver (`%s')\n", driver->name); 547 printf(NAME ": initialize_running_driver\n"); 548 fibril_mutex_lock(&driver->driver_mutex); 603 549 604 550 /* … … 607 553 */ 608 554 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); 609 560 } 610 561 … … 678 629 } 679 630 680 static FIBRIL_MUTEX_INITIALIZE(add_device_guard);681 631 682 632 /** Pass a device to running driver. … … 687 637 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) 688 638 { 689 fibril_mutex_lock(&add_device_guard); 690 691 /* 692 * We do not expect to have driver's mutex locked as we do not 693 * access any structures that would affect driver_t. 694 */ 695 printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name, 696 node->name); 639 printf(NAME ": add_device\n"); 697 640 698 641 ipcarg_t rc; … … 700 643 701 644 /* Send the device to the driver. */ 702 devman_handle_t parent_handle; 703 if (node->parent) { 704 parent_handle = node->parent->handle; 705 } else { 706 parent_handle = 0; 707 } 708 709 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle, 710 parent_handle, &answer); 645 aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle, 646 &answer); 711 647 712 648 /* Send the device's name to the driver. */ … … 716 652 /* TODO handle error */ 717 653 } 718 654 719 655 /* Wait for answer from the driver. */ 720 656 async_wait_for(req, &rc); 721 722 fibril_mutex_unlock(&add_device_guard);723 724 657 switch(rc) { 725 658 case EOK: … … 734 667 } 735 668 736 node->passed_to_driver = true;737 738 669 return; 739 670 } … … 761 692 attach_driver(node, drv); 762 693 763 fibril_mutex_lock(&drv->driver_mutex);764 694 if (drv->state == DRIVER_NOT_STARTED) { 765 695 /* Start the driver. */ 766 696 start_driver(drv); 767 697 } 768 bool is_running = drv->state == DRIVER_RUNNING; 769 fibril_mutex_unlock(&drv->driver_mutex); 770 771 if (is_running) { 698 699 if (drv->state == DRIVER_RUNNING) { 772 700 /* Notify the driver about the new device. */ 773 int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);701 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 774 702 if (phone > 0) { 775 703 add_device(phone, drv, node, tree); … … 933 861 node->name = dev_name; 934 862 if (!set_dev_path(node, parent)) { 863 fibril_rwlock_write_unlock(&tree->rwlock); 935 864 return false; 936 865 } … … 1154 1083 while (link != &class_list->classes) { 1155 1084 cl = list_get_instance(link, dev_class_t, link); 1156 if (str_cmp(cl->name, class_name) == 0) {1085 if (str_cmp(cl->name, class_name) == 0) 1157 1086 return cl; 1158 }1159 link = link->next;1160 1087 } 1161 1088 -
uspace/srv/devman/devman.h
r4006447 rb38dfd8 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;175 170 }; 176 171 -
uspace/srv/devman/main.c
r4006447 rb38dfd8 197 197 } 198 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 206 199 /** Handle child device registration. 207 200 * … … 244 237 245 238 devman_receive_match_ids(match_count, &node->match_ids); 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 240 /* Return device handle to parent's driver. */ 266 241 ipc_answer_1(callid, EOK, node->handle); 242 243 /* Try to find suitable driver and assign it to the device. */ 244 assign_driver(node, &drivers_list, &device_tree); 267 245 } 268 246 … … 319 297 printf(NAME ": device '%s' added to class '%s', class name '%s' was " 320 298 "asigned to it\n", dev->pathname, class_name, class_info->dev_name); 321 299 322 300 ipc_answer_0(callid, EOK); 323 301 } -
uspace/srv/devman/match.c
r4006447 rb38dfd8 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 59 37 int get_match_score(driver_t *drv, node_t *dev) 60 38 { … … 65 43 return 0; 66 44 67 /* 68 * Go through all pairs, return the highest score obtained. 69 */ 70 int highest_score = 0; 45 link_t *drv_link = drv->match_ids.ids.next; 46 link_t *dev_link = dev->match_ids.ids.next; 71 47 72 link_t *drv_link = drv->match_ids.ids.next; 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; 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; 85 63 } 86 64 87 drv_link = drv_link->next; 88 } 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); 89 102 90 return highest_score;103 return 0; 91 104 } 92 105
Note:
See TracChangeset
for help on using the changeset viewer.