Changeset 38b3baf in mainline
- Timestamp:
- 2010-10-23T07:16:14Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7e66a5ec
- Parents:
- 032e0bb
- Location:
- uspace/srv/devman
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r032e0bb r38b3baf 40 40 #include "devman.h" 41 41 42 / / hash table operations42 /* hash table operations */ 43 43 44 44 static hash_index_t devices_hash(unsigned long key[]) … … 47 47 } 48 48 49 static int devman_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 49 static int 50 devman_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 50 51 { 51 52 node_t *dev = hash_table_get_instance(item, node_t, devman_link); … … 53 54 } 54 55 55 static int devmap_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 56 static int 57 devmap_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 56 58 { 57 59 node_t *dev = hash_table_get_instance(item, node_t, devmap_link); … … 76 78 77 79 /** Allocate and initialize a new driver structure. 78 * 79 * @return driver structure.80 */ 81 driver_t * create_driver()80 * 81 * @return Driver structure. 82 */ 83 driver_t *create_driver(void) 82 84 { 83 85 driver_t *res = malloc(sizeof(driver_t)); 84 if (res != NULL) {86 if (res != NULL) 85 87 init_driver(res); 86 }87 88 return res; 88 89 } 89 90 90 91 /** Add a driver to the list of drivers. 91 * 92 * 92 93 * @param drivers_list the list of drivers. 93 94 * @param drv the driver's structure. … … 99 100 fibril_mutex_unlock(&drivers_list->drivers_mutex); 100 101 101 printf(NAME": the '%s' driver was added to the list of available drivers.\n", drv->name);102 } 103 104 /** Read match id at the specified position of a string and set 105 * the position in the string to the first character following the id. 106 * 107 * @param buf the position in the input string.108 * 109 * @return the match id.110 */ 111 char * read_match_id(char **buf)102 printf(NAME": the '%s' driver was added to the list of available " 103 "drivers.\n", drv->name); 104 } 105 106 /** Read match id at the specified position of a string and set the position in 107 * the string to the first character following the id. 108 * 109 * @param buf The position in the input string. 110 * @return The match id. 111 */ 112 char *read_match_id(char **buf) 112 113 { 113 114 char *res = NULL; 114 115 size_t len = get_nonspace_len(*buf); 116 115 117 if (len > 0) { 116 118 res = malloc(len + 1); 117 119 if (res != NULL) { 118 str_ncpy(res, len + 1, *buf, len); 120 str_ncpy(res, len + 1, *buf, len); 119 121 *buf += len; 120 122 } 121 123 } 124 122 125 return res; 123 126 } … … 125 128 /** 126 129 * Read match ids and associated match scores from a string. 127 * 128 * Each match score in the string is followed by its match id. 129 * The match ids and match scores are separated by whitespaces. 130 * Neither match ids nor match scores can contain whitespaces. 131 * 132 * @param buf the string from which the match ids are read. 133 * @param ids the list of match ids into which the match ids and scores are added. 134 * 135 * @return true if at least one match id and associated match score was successfully read, false otherwise. 130 * 131 * Each match score in the string is followed by its match id. 132 * The match ids and match scores are separated by whitespaces. 133 * Neither match ids nor match scores can contain whitespaces. 134 * 135 * @param buf The string from which the match ids are read. 136 * @param ids The list of match ids into which the match ids and 137 * scores are added. 138 * @return True if at least one match id and associated match score 139 * was successfully read, false otherwise. 136 140 */ 137 141 bool parse_match_ids(char *buf, match_id_list_t *ids) … … 142 146 143 147 while (true) { 144 / / skip spaces145 if (!skip_spaces(&buf)) {148 /* skip spaces */ 149 if (!skip_spaces(&buf)) 146 150 break; 147 }148 / / read score151 152 /* read score */ 149 153 score = strtoul(buf, &buf, 10); 150 154 151 / / skip spaces152 if (!skip_spaces(&buf)) {155 /* skip spaces */ 156 if (!skip_spaces(&buf)) 153 157 break; 154 } 155 156 // read id 157 if (NULL == (id = read_match_id(&buf))) { 158 break; 159 } 160 161 // create new match_id structure 158 159 /* read id */ 160 id = read_match_id(&buf); 161 if (NULL == id) 162 break; 163 164 /* create new match_id structure */ 162 165 match_id_t *mid = create_match_id(); 163 166 mid->id = id; 164 167 mid->score = score; 165 168 166 / // add it to the list169 /* add it to the list */ 167 170 add_match_id(ids, mid); 168 171 169 ids_read++; 170 } 172 ids_read++; 173 } 171 174 172 175 return ids_read > 0; … … 175 178 /** 176 179 * Read match ids and associated match scores from a file. 177 * 178 * Each match score in the file is followed by its match id. 179 * The match ids and match scores are separated by whitespaces. 180 * Neither match ids nor match scores can contain whitespaces. 181 * 182 * @param buf the path to the file from which the match ids are read. 183 * @param ids the list of match ids into which the match ids and scores are added. 184 * 185 * @return true if at least one match id and associated match score was successfully read, false otherwise. 186 */ 187 bool read_match_ids(const char *conf_path, match_id_list_t *ids) 188 { 180 * 181 * Each match score in the file is followed by its match id. 182 * The match ids and match scores are separated by whitespaces. 183 * Neither match ids nor match scores can contain whitespaces. 184 * 185 * @param buf The path to the file from which the match ids are read. 186 * @param ids The list of match ids into which the match ids and 187 * scores are added. 188 * @return True if at least one match id and associated match score 189 * was successfully read, false otherwise. 190 */ 191 bool read_match_ids(const char *conf_path, match_id_list_t *ids) 192 { 189 193 printf(NAME ": read_match_ids conf_path = %s.\n", conf_path); 190 194 191 bool suc = false; 195 bool suc = false; 192 196 char *buf = NULL; 193 197 bool opened = false; 194 int fd; 198 int fd; 195 199 size_t len = 0; 196 200 … … 199 203 printf(NAME ": unable to open %s\n", conf_path); 200 204 goto cleanup; 201 } 202 opened = true; 205 } 206 opened = true; 203 207 204 208 len = lseek(fd, 0, SEEK_END); 205 lseek(fd, 0, SEEK_SET); 209 lseek(fd, 0, SEEK_SET); 206 210 if (len == 0) { 207 211 printf(NAME ": configuration file '%s' is empty.\n", conf_path); 208 goto cleanup; 212 goto cleanup; 209 213 } 210 214 211 215 buf = malloc(len + 1); 212 216 if (buf == NULL) { 213 printf(NAME ": memory allocation failed when parsing file '%s'.\n", conf_path); 217 printf(NAME ": memory allocation failed when parsing file " 218 "'%s'.\n", conf_path); 214 219 goto cleanup; 215 220 } … … 224 229 225 230 cleanup: 226 227 231 free(buf); 228 232 229 if(opened) { 230 close(fd); 231 } 233 if(opened) 234 close(fd); 232 235 233 236 return suc; … … 236 239 /** 237 240 * Get information about a driver. 238 * 239 * Each driver has its own directory in the base directory. 241 * 242 * Each driver has its own directory in the base directory. 240 243 * The name of the driver's directory is the same as the name of the driver. 241 * The driver's directory contains driver's binary (named as the driver without extension) 242 * and the configuration file with match ids for device-to-driver matching 243 * (named as the driver with a special extension). 244 * 245 * This function searches for the driver's directory and containing configuration files. 246 * If all the files needed are found, they are parsed and 247 * the information about the driver is stored to the driver's structure. 248 * 249 * @param base_path the base directory, in which we look for driver's subdirectory. 250 * @param name the name of the driver. 251 * @param drv the driver structure to fill information in. 252 * 253 * @return true on success, false otherwise. 244 * The driver's directory contains driver's binary (named as the driver without 245 * extension) and the configuration file with match ids for device-to-driver 246 * matching (named as the driver with a special extension). 247 * 248 * This function searches for the driver's directory and containing 249 * configuration files. If all the files needed are found, they are parsed and 250 * the information about the driver is stored in the driver's structure. 251 * 252 * @param base_path The base directory, in which we look for driver's 253 * subdirectory. 254 * @param name The name of the driver. 255 * @param drv The driver structure to fill information in. 256 * 257 * @return True on success, false otherwise. 254 258 */ 255 259 bool get_driver_info(const char *base_path, const char *name, driver_t *drv) 256 260 { 257 printf(NAME ": get_driver_info base_path = %s, name = %s.\n", base_path, name); 261 printf(NAME ": get_driver_info base_path = %s, name = %s.\n", 262 base_path, name); 258 263 259 264 assert(base_path != NULL && name != NULL && drv != NULL); 260 265 261 266 bool suc = false; 262 char *match_path = NULL; 267 char *match_path = NULL; 263 268 size_t name_size = 0; 264 269 265 // read the list of match ids from the driver's configuration file 266 if (NULL == (match_path = get_abs_path(base_path, name, MATCH_EXT))) { 270 /* Read the list of match ids from the driver's configuration file. */ 271 match_path = get_abs_path(base_path, name, MATCH_EXT); 272 if (NULL == match_path) 267 273 goto cleanup; 268 } 269 270 if (!read_match_ids(match_path, &drv->match_ids)) { 274 275 if (!read_match_ids(match_path, &drv->match_ids)) 271 276 goto cleanup; 272 } 273 274 // allocate and fill driver's name 275 name_size = str_size(name)+1; 277 278 /* Allocate and fill driver's name. */ 279 name_size = str_size(name) + 1; 276 280 drv->name = malloc(name_size); 277 if (!drv->name) {281 if (!drv->name) 278 282 goto cleanup; 279 }280 283 str_cpy(drv->name, name_size, name); 281 284 282 // initialize path with driver's binary 283 if (NULL == (drv->binary_path = get_abs_path(base_path, name, ""))) { 285 /* Initialize path with driver's binary. */ 286 drv->binary_path = get_abs_path(base_path, name, ""); 287 if (NULL == drv->binary_path) 284 288 goto cleanup; 285 } 286 287 // check whether the driver's binary exists 289 290 /* Check whether the driver's binary exists. */ 288 291 struct stat s; 289 292 if (stat(drv->binary_path, &s) == ENOENT) { … … 295 298 296 299 cleanup: 297 298 300 if (!suc) { 299 301 free(drv->binary_path); 300 302 free(drv->name); 301 / / set the driver structure to the default state302 init_driver(drv); 303 /* Set the driver structure to the default state. */ 304 init_driver(drv); 303 305 } 304 306 … … 309 311 310 312 /** Lookup drivers in the directory. 311 * 312 * @param drivers_list the list of available drivers. 313 * @param dir_path the path to the directory where we search for drivers. 314 * 315 * @return number of drivers which were found. 316 */ 313 * 314 * @param drivers_list The list of available drivers. 315 * @param dir_path The path to the directory where we search for drivers. 316 * @return Number of drivers which were found. 317 */ 317 318 int lookup_available_drivers(driver_list_t *drivers_list, const char *dir_path) 318 319 { … … 327 328 if (dir != NULL) { 328 329 driver_t *drv = create_driver(); 329 while ((diren = readdir(dir))) { 330 while ((diren = readdir(dir))) { 330 331 if (get_driver_info(dir_path, diren->d_name, drv)) { 331 332 add_driver(drivers_list, drv); 332 333 drv_cnt++; 333 334 drv = create_driver(); 334 } 335 } 335 336 } 336 337 delete_driver(drv); … … 342 343 343 344 /** Create root device node in the device tree. 344 * 345 * @param tree the device tree.346 * @return true on success, false otherwise.345 * 346 * @param tree The device tree. 347 * @return True on success, false otherwise. 347 348 */ 348 349 bool create_root_node(dev_tree_t *tree) … … 350 351 printf(NAME ": create_root_node\n"); 351 352 node_t *node = create_dev_node(); 352 if (node) { 353 if (node) { 353 354 insert_dev_node(tree, node, clone_string(""), NULL); 354 355 match_id_t *id = create_match_id(); … … 358 359 tree->root_node = node; 359 360 } 360 return node != NULL; 361 } 362 363 /** Lookup the best matching driver for the specified device in the list of drivers. 364 * 365 * A match between a device and a driver is found 366 * if one of the driver's match ids match one of the device's match ids. 367 * The score of the match is the product of the driver's and device's score associated with the matching id. 368 * The best matching driver for a device is the driver 369 * with the highest score of the match between the device and the driver. 370 * 371 * @param drivers_list the list of drivers, where we look for the driver suitable for handling the device. 372 * @param node the device node structure of the device. 373 * 374 * @return the best matching driver or NULL if no matching driver is found. 375 */ 376 driver_t * find_best_match_driver(driver_list_t *drivers_list, node_t *node) 377 { 378 //printf(NAME ": find_best_match_driver for device '%s' \n", node->pathname); 361 return node != NULL; 362 } 363 364 /** Lookup the best matching driver for the specified device in the list of 365 * drivers. 366 * 367 * A match between a device and a driver is found if one of the driver's match 368 * ids match one of the device's match ids. The score of the match is the 369 * product of the driver's and device's score associated with the matching id. 370 * The best matching driver for a device is the driver with the highest score 371 * of the match between the device and the driver. 372 * 373 * @param drivers_list The list of drivers, where we look for the driver 374 * suitable for handling the device. 375 * @param node The device node structure of the device. 376 * @return The best matching driver or NULL if no matching driver 377 * is found. 378 */ 379 driver_t *find_best_match_driver(driver_list_t *drivers_list, node_t *node) 380 { 379 381 driver_t *best_drv = NULL, *drv = NULL; 380 382 int best_score = 0, score = 0; … … 382 384 fibril_mutex_lock(&drivers_list->drivers_mutex); 383 385 384 link_t *link = drivers_list->drivers.next; 386 link_t *link = drivers_list->drivers.next; 385 387 while (link != &drivers_list->drivers) { 386 388 drv = list_get_instance(link, driver_t, drivers); … … 395 397 fibril_mutex_unlock(&drivers_list->drivers_mutex); 396 398 397 return best_drv; 398 } 399 400 /** 401 * Assign a driver to a device.402 * 403 * @param node the device's node in the device tree.404 * @param drv the driver.405 */ 406 void attach_driver(node_t *node, driver_t *drv) 407 { 408 printf(NAME ": attach_driver %s to device %s\n",drv->name, node->pathname);399 return best_drv; 400 } 401 402 /** Assign a driver to a device. 403 * 404 * @param node The device's node in the device tree. 405 * @param drv The driver. 406 */ 407 void attach_driver(node_t *node, driver_t *drv) 408 { 409 printf(NAME ": attach_driver %s to device %s\n", 410 drv->name, node->pathname); 409 411 410 412 fibril_mutex_lock(&drv->driver_mutex); … … 416 418 } 417 419 418 /** Start a driver .419 * 420 /** Start a driver 421 * 420 422 * The driver's mutex is assumed to be locked. 421 * 422 * @param drv the driver's structure. 423 * @return true if the driver's task is successfully spawned, false otherwise. 423 * 424 * @param drv The driver's structure. 425 * @return True if the driver's task is successfully spawned, false 426 * otherwise. 424 427 */ 425 428 bool start_driver(driver_t *drv) … … 434 437 int err; 435 438 if (!task_spawn(drv->binary_path, argv, &err)) { 436 printf(NAME ": error spawning %s, errno = %d\n", drv->name, err); 439 printf(NAME ": error spawning %s, errno = %d\n", 440 drv->name, err); 437 441 return false; 438 442 } … … 443 447 444 448 /** Find device driver in the list of device drivers. 445 * 446 * @param drv_list the list of device drivers. 447 * @param drv_name the name of the device driver which is searched. 448 * @return the device driver of the specified name, if it is in the list, NULL otherwise. 449 */ 450 driver_t * find_driver(driver_list_t *drv_list, const char *drv_name) 451 { 449 * 450 * @param drv_list The list of device drivers. 451 * @param drv_name The name of the device driver which is searched. 452 * @return The device driver of the specified name, if it is in the 453 * list, NULL otherwise. 454 */ 455 driver_t *find_driver(driver_list_t *drv_list, const char *drv_name) 456 { 452 457 driver_t *res = NULL; 453 458 454 fibril_mutex_lock(&drv_list->drivers_mutex); 459 fibril_mutex_lock(&drv_list->drivers_mutex); 455 460 456 461 driver_t *drv = NULL; 457 link_t *link = drv_list->drivers.next; 462 link_t *link = drv_list->drivers.next; 458 463 while (link != &drv_list->drivers) { 459 464 drv = list_get_instance(link, driver_t, drivers); … … 471 476 472 477 /** Remember the driver's phone. 473 * @param driver the driver. 474 * @param phone the phone to the driver. 478 * 479 * @param driver The driver. 480 * @param phone The phone to the driver. 475 481 */ 476 482 void set_driver_phone(driver_t *driver, ipcarg_t phone) 477 { 478 fibril_mutex_lock(&driver->driver_mutex); 483 { 484 fibril_mutex_lock(&driver->driver_mutex); 479 485 assert(DRIVER_STARTING == driver->state); 480 driver->phone = phone; 481 fibril_mutex_unlock(&driver->driver_mutex); 482 } 483 484 /** 485 * Notify driver about the devices to which it was assigned. 486 * 486 driver->phone = phone; 487 fibril_mutex_unlock(&driver->driver_mutex); 488 } 489 490 /** Notify driver about the devices to which it was assigned. 491 * 487 492 * The driver's mutex must be locked. 488 * 489 * @param driver the driver to which the devices are passed.493 * 494 * @param driver The driver to which the devices are passed. 490 495 */ 491 496 static void pass_devices_to_driver(driver_t *driver, dev_tree_t *tree) 492 { 497 { 493 498 printf(NAME ": pass_devices_to_driver\n"); 494 499 node_t *dev; … … 510 515 } 511 516 512 /** Finish the initialization of a driver after it has succesfully started 517 /** Finish the initialization of a driver after it has succesfully started 513 518 * and after it has registered itself by the device manager. 514 * 515 * Pass devices formerly matched to the driver to the driver and remember the driver is running and fully functional now. 516 * 517 * @param driver the driver which registered itself as running by the device manager. 518 */ 519 void initialize_running_driver(driver_t *driver, dev_tree_t *tree) 520 { 519 * 520 * Pass devices formerly matched to the driver to the driver and remember the 521 * driver is running and fully functional now. 522 * 523 * @param driver The driver which registered itself as running by the 524 * device manager. 525 */ 526 void initialize_running_driver(driver_t *driver, dev_tree_t *tree) 527 { 521 528 printf(NAME ": initialize_running_driver\n"); 522 529 fibril_mutex_lock(&driver->driver_mutex); 523 530 524 // pass devices which have been already assigned to the driver to the driver 525 pass_devices_to_driver(driver, tree); 526 527 // change driver's state to running 528 driver->state = DRIVER_RUNNING; 531 /* 532 * Pass devices which have been already assigned to the driver to the 533 * driver. 534 */ 535 pass_devices_to_driver(driver, tree); 536 537 /* Change driver's state to running. */ 538 driver->state = DRIVER_RUNNING; 529 539 530 540 fibril_mutex_unlock(&driver->driver_mutex); … … 532 542 533 543 544 /** Create devmap path and name for the device. */ 534 545 static void devmap_register_tree_device(node_t *node, dev_tree_t *tree) 535 546 { 536 // create devmap path and name for the device537 547 char *devmap_pathname = NULL; 538 548 char *devmap_name = NULL; 539 549 540 550 asprintf(&devmap_name, "%s", node->pathname); 541 if (NULL == devmap_name) {551 if (NULL == devmap_name) 542 552 return; 543 }544 553 545 554 replace_char(devmap_name, '/', DEVMAP_SEPARATOR); 546 555 547 asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE, devmap_name); 556 asprintf(&devmap_pathname, "%s/%s", DEVMAP_DEVICE_NAMESPACE, 557 devmap_name); 548 558 if (NULL == devmap_pathname) { 549 559 free(devmap_name); 550 560 return; 551 } 561 } 552 562 553 563 devmap_device_register(devmap_pathname, &node->devmap_handle); … … 556 566 557 567 free(devmap_name); 558 free(devmap_pathname); 568 free(devmap_pathname); 559 569 } 560 570 561 571 562 572 /** Pass a device to running driver. 563 * 564 * @param drv the driver's structure.565 * @param node the device's node in the device tree.573 * 574 * @param drv The driver's structure. 575 * @param node The device's node in the device tree. 566 576 */ 567 577 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) … … 572 582 ipc_call_t answer; 573 583 574 // send the device to the driver 575 aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle, &answer); 576 577 // send the device's name to the driver 578 rc = async_data_write_start(phone, node->name, str_size(node->name) + 1); 579 if (rc != EOK) { 580 // TODO handle error 581 } 582 583 // wait for answer from the driver 584 /* Send the device to the driver. */ 585 aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle, 586 &answer); 587 588 /* Send the device's name to the driver. */ 589 rc = async_data_write_start(phone, node->name, 590 str_size(node->name) + 1); 591 if (rc != EOK) { 592 /* TODO handle error */ 593 } 594 595 /* Wait for answer from the driver. */ 584 596 async_wait_for(req, &rc); 585 597 switch(rc) { … … 592 604 break; 593 605 default: 594 node->state = DEVICE_INVALID; 606 node->state = DEVICE_INVALID; 595 607 } 596 608 … … 598 610 } 599 611 600 /** 601 * Find suitable driver for a device and assign the driver to it. 602 * 603 * @param node the device node of the device in the device tree. 604 * @param drivers_list the list of available drivers. 605 * 606 * @return true if the suitable driver is found and successfully assigned to the device, false otherwise. 607 */ 608 bool assign_driver(node_t *node, driver_list_t *drivers_list, dev_tree_t *tree) 609 { 610 //printf(NAME ": assign_driver\n"); 611 612 // find the driver which is the most suitable for handling this device 612 /** Find suitable driver for a device and assign the driver to it. 613 * 614 * @param node The device node of the device in the device tree. 615 * @param drivers_list The list of available drivers. 616 * @return True if the suitable driver is found and 617 * successfully assigned to the device, false otherwise. 618 */ 619 bool assign_driver(node_t *node, driver_list_t *drivers_list, dev_tree_t *tree) 620 { 621 /* 622 * Find the driver which is the most suitable for handling this device. 623 */ 613 624 driver_t *drv = find_best_match_driver(drivers_list, node); 614 625 if (NULL == drv) { 615 printf(NAME ": no driver found for device '%s'.\n", node->pathname); 616 return false; 617 } 618 619 // attach the driver to the device 626 printf(NAME ": no driver found for device '%s'.\n", 627 node->pathname); 628 return false; 629 } 630 631 /* Attach the driver to the device. */ 620 632 attach_driver(node, drv); 621 633 622 634 if (DRIVER_NOT_STARTED == drv->state) { 623 / / start driver635 /* Start the driver. */ 624 636 start_driver(drv); 625 } 637 } 626 638 627 639 if (DRIVER_RUNNING == drv->state) { 628 / / notify driver about new device640 /* Notify the driver about the new device. */ 629 641 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 630 642 if (phone > 0) { 631 add_device(phone, drv, node, tree); 643 add_device(phone, drv, node, tree); 632 644 ipc_hangup(phone); 633 645 } … … 637 649 } 638 650 639 /** 640 * Initialize the device tree. 641 * 651 /** Initialize the device tree. 652 * 642 653 * Create root device node of the tree and assign driver to it. 643 * 644 * @param tree the device tree.645 * @param the list of available drivers.646 * @return true on success, false otherwise.654 * 655 * @param tree The device tree. 656 * @param drivers_list the list of available drivers. 657 * @return True on success, false otherwise. 647 658 */ 648 659 bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list) … … 652 663 tree->current_handle = 0; 653 664 654 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, &devman_devices_ops); 655 hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops); 665 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, 666 &devman_devices_ops); 667 hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, 668 &devmap_devices_ops); 656 669 657 670 fibril_rwlock_initialize(&tree->rwlock); 658 671 659 / / create root node and add it to the device tree660 if (!create_root_node(tree)) {672 /* Create root node and add it to the device tree. */ 673 if (!create_root_node(tree)) 661 674 return false; 662 } 663 664 // find suitable driver and start it 675 676 /* Find suitable driver and start it. */ 665 677 return assign_driver(tree->root_node, drivers_list, tree); 666 678 } 667 679 668 680 /** Create and set device's full path in device tree. 669 * 670 * @param node the device's device node. 671 * @param parent the parent device node. 672 * @return true on success, false otherwise (insufficient resources etc.). 681 * 682 * @param node The device's device node. 683 * @param parent The parent device node. 684 * @return True on success, false otherwise (insufficient 685 * resources etc.). 673 686 */ 674 687 static bool set_dev_path(node_t *node, node_t *parent) 675 { 688 { 676 689 assert(NULL != node->name); 677 690 678 size_t pathsize = (str_size(node->name) + 1); 679 if (NULL != parent) {680 pathsize += str_size(parent->pathname) + 1; 681 }682 683 if (NULL == (node->pathname = (char *)malloc(pathsize))) {691 size_t pathsize = (str_size(node->name) + 1); 692 if (NULL != parent) 693 pathsize += str_size(parent->pathname) + 1; 694 695 node->pathname = (char *) malloc(pathsize); 696 if (NULL == node->pathname) { 684 697 printf(NAME ": failed to allocate device path.\n"); 685 698 return false; … … 698 711 699 712 /** Insert new device into device tree. 700 * 701 * The device tree's rwlock should be already held exclusively when calling this function. 702 * 703 * @param tree the device tree. 704 * @param node the newly added device node. 705 * @param dev_name the name of the newly added device. 706 * @param parent the parent device node. 707 * @return true on success, false otherwise (insufficient resources etc.). 708 */ 709 bool insert_dev_node(dev_tree_t *tree, node_t *node, char *dev_name, node_t *parent) 710 { 711 // printf(NAME ": insert_dev_node\n"); 712 713 * 714 * The device tree's rwlock should be already held exclusively when calling this 715 * function. 716 * 717 * @param tree The device tree. 718 * @param node The newly added device node. 719 * @param dev_name The name of the newly added device. 720 * @param parent The parent device node. 721 * @return True on success, false otherwise (insufficient resources 722 * etc.). 723 */ 724 bool 725 insert_dev_node(dev_tree_t *tree, node_t *node, char *dev_name, node_t *parent) 726 { 713 727 assert(NULL != node && NULL != tree && NULL != dev_name); 714 728 … … 716 730 if (!set_dev_path(node, parent)) { 717 731 fibril_rwlock_write_unlock(&tree->rwlock); 718 return false; 719 } 720 721 / / add the node to the handle-to-node map732 return false; 733 } 734 735 /* Add the node to the handle-to-node map. */ 722 736 node->handle = ++tree->current_handle; 723 737 unsigned long key = node->handle; 724 738 hash_table_insert(&tree->devman_devices, &key, &node->devman_link); 725 739 726 / / add the node to the list of its parent's children740 /* Add the node to the list of its parent's children. */ 727 741 node->parent = parent; 728 if (NULL != parent) {729 list_append(&node->sibling, &parent->children); 730 }742 if (NULL != parent) 743 list_append(&node->sibling, &parent->children); 744 731 745 return true; 732 746 } 733 747 734 /** 735 * Find device node with a specified path in the device tree. 748 /** Find device node with a specified path in the device tree. 736 749 * 737 * @param path the path of the device node in the device tree.738 * @param tree the device tree.739 * 740 * @return the device node if it is present in the tree, NULLotherwise.741 */ 742 node_t * 750 * @param path The path of the device node in the device tree. 751 * @param tree The device tree. 752 * @return The device node if it is present in the tree, NULL 753 * otherwise. 754 */ 755 node_t *find_dev_node_by_path(dev_tree_t *tree, char *path) 743 756 { 744 757 fibril_rwlock_read_lock(&tree->rwlock); 745 758 746 759 node_t *dev = tree->root_node; 747 // relative path to the device from its parent (but with '/' at the beginning) 760 /* 761 * Relative path to the device from its parent (but with '/' at the 762 * beginning) 763 */ 748 764 char *rel_path = path; 749 765 char *next_path_elem = NULL; 750 766 bool cont = '/' == rel_path[0]; 751 767 752 while (cont && NULL != dev) { 753 next_path_elem = get_path_elem_end(rel_path + 1); 768 while (cont && NULL != dev) { 769 next_path_elem = get_path_elem_end(rel_path + 1); 754 770 if ('/' == next_path_elem[0]) { 755 771 cont = true; … … 759 775 } 760 776 761 dev = find_node_child(dev, rel_path + 1); 777 dev = find_node_child(dev, rel_path + 1); 762 778 763 779 if (cont) { 764 / / restore the original path780 /* Restore the original path. */ 765 781 next_path_elem[0] = '/'; 766 782 } 767 rel_path = next_path_elem; 783 rel_path = next_path_elem; 768 784 } 769 785 … … 773 789 } 774 790 775 /** 776 * Find child device node with a specified name. 777 * 778 * Device tree rwlock should be held at least for reading. 779 * 780 * @param parent the parent device node. 781 * @param name the name of the child device node. 782 * 783 * @return the child device node. 791 /** Find child device node with a specified name. 792 * 793 * Device tree rwlock should be held at least for reading. 794 * 795 * @param parent The parent device node. 796 * @param name The name of the child device node. 797 * @return The child device node. 784 798 */ 785 799 node_t *find_node_child(node_t *parent, const char *name) … … 787 801 node_t *dev; 788 802 link_t *link; 789 803 790 804 link = parent->children.next; 791 805 … … 793 807 dev = list_get_instance(link, node_t, sibling); 794 808 795 if (0 == str_cmp(name, dev->name)) { 796 return dev; 797 } 809 if (0 == str_cmp(name, dev->name)) 810 return dev; 798 811 799 812 link = link->next; 800 } 801 813 } 814 802 815 return NULL; 803 816 } 804 817 805 /** Create unique device name within the class. 806 * 807 * @param cl the class.808 * @param base_dev_name contains base name for the device809 * if it was specified by the driver when it registered the device by the class;810 * NULL if driver specified no base name.811 * @return the unique name for the device within the class.812 */ 813 char * 818 /** Create unique device name within the class. 819 * 820 * @param cl The class. 821 * @param base_dev_name Contains the base name for the device if it was 822 * specified by the driver when it registered the device by 823 * the class; NULL if driver specified no base name. 824 * @return The unique name for the device within the class. 825 */ 826 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name) 814 827 { 815 828 char *dev_name; 816 829 const char *base_name; 817 if (NULL != base_dev_name) { 830 831 if (NULL != base_dev_name) 818 832 base_name = base_dev_name; 819 } else {833 else 820 834 base_name = cl->base_dev_name; 821 }822 835 823 836 size_t idx = get_new_class_dev_idx(cl); 824 837 asprintf(&dev_name, "%s%d", base_name, idx); 825 return dev_name; 838 839 return dev_name; 826 840 } 827 841 828 842 /** Add the device to the class. 829 * 830 * The device may be added to multiple classes and a class may contain multiple devices. 831 * The class and the device are associated with each other by the dev_class_info_t structure. 832 * 833 * @param dev the device. 834 * @param class the class. 835 * @param base_dev_name the base name of the device within the class if specified by the driver, 836 * NULL otherwise. 837 * @return dev_class_info_t structure which associates the device with the class. 838 */ 839 dev_class_info_t * add_device_to_class(node_t *dev, dev_class_t *cl, const char *base_dev_name) 840 { 843 * 844 * The device may be added to multiple classes and a class may contain multiple 845 * devices. The class and the device are associated with each other by the 846 * dev_class_info_t structure. 847 * 848 * @param dev The device. 849 * @param class The class. 850 * @param base_dev_name The base name of the device within the class if 851 * specified by the driver, NULL otherwise. 852 * @return dev_class_info_t structure which associates the device 853 * with the class. 854 */ 855 dev_class_info_t * 856 add_device_to_class(node_t *dev, dev_class_t *cl, const char *base_dev_name) 857 { 841 858 dev_class_info_t *info = create_dev_class_info(); 859 842 860 if (NULL != info) { 843 861 info->dev_class = cl; 844 862 info->dev = dev; 845 863 846 / / add the device to the class864 /* Add the device to the class. */ 847 865 fibril_mutex_lock(&cl->mutex); 848 866 list_append(&info->link, &cl->devices); 849 867 fibril_mutex_unlock(&cl->mutex); 850 868 851 / / add the class to the device869 /* Add the class to the device. */ 852 870 list_append(&info->dev_classes, &dev->classes); 853 871 854 / / create unique name for the device within the class855 info->dev_name = create_dev_name_for_class(cl, base_dev_name); 872 /* Create unique name for the device within the class. */ 873 info->dev_name = create_dev_name_for_class(cl, base_dev_name); 856 874 } 857 875 … … 859 877 } 860 878 861 dev_class_t * 879 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name) 862 880 { 863 881 dev_class_t *cl; 864 fibril_rwlock_write_lock(&class_list->rwlock); 882 883 fibril_rwlock_write_lock(&class_list->rwlock); 865 884 cl = find_dev_class_no_lock(class_list, class_name); 866 885 if (NULL == cl) { 867 886 cl = create_dev_class(); 868 887 if (NULL != cl) { 869 cl->name = class_name; 888 cl->name = class_name; 870 889 cl->base_dev_name = ""; 871 890 add_dev_class_no_lock(class_list, cl); 872 } 873 } 891 } 892 } 874 893 fibril_rwlock_write_unlock(&class_list->rwlock); 875 894 return cl; 876 895 } 877 896 878 dev_class_t * find_dev_class_no_lock(class_list_t *class_list, const char *class_name) 897 dev_class_t * 898 find_dev_class_no_lock(class_list_t *class_list, const char *class_name) 879 899 { 880 900 dev_class_t *cl; 881 901 link_t *link = class_list->classes.next; 902 882 903 while (link != &class_list->classes) { 883 904 cl = list_get_instance(link, dev_class_t, link); 884 if (0 == str_cmp(cl->name, class_name)) {905 if (0 == str_cmp(cl->name, class_name)) 885 906 return cl; 886 } 887 } 888 889 return NULL; 907 } 908 909 return NULL; 890 910 } 891 911 … … 894 914 list_initialize(&class_list->classes); 895 915 fibril_rwlock_initialize(&class_list->rwlock); 896 hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops); 897 } 898 899 900 // devmap devices 916 hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1, 917 &devmap_devices_ops); 918 } 919 920 921 /* devmap devices */ 901 922 902 923 node_t *find_devmap_tree_device(dev_tree_t *tree, dev_handle_t devmap_handle) … … 904 925 node_t *dev = NULL; 905 926 link_t *link; 906 unsigned long key = (unsigned long) devmap_handle;927 unsigned long key = (unsigned long) devmap_handle; 907 928 908 929 fibril_rwlock_read_lock(&tree->rwlock); 909 link = hash_table_find(&tree->devmap_devices, &key); 910 if (NULL != link) {930 link = hash_table_find(&tree->devmap_devices, &key); 931 if (NULL != link) 911 932 dev = hash_table_get_instance(link, node_t, devmap_link); 912 }913 933 fibril_rwlock_read_unlock(&tree->rwlock); 914 934 … … 916 936 } 917 937 918 node_t *find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle) 938 node_t * 939 find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle) 919 940 { 920 941 node_t *dev = NULL; … … 924 945 925 946 fibril_rwlock_read_lock(&classes->rwlock); 926 link = hash_table_find(&classes->devmap_devices, &key); 947 link = hash_table_find(&classes->devmap_devices, &key); 927 948 if (NULL != link) { 928 cli = hash_table_get_instance(link, dev_class_info_t, devmap_link); 949 cli = hash_table_get_instance(link, dev_class_info_t, 950 devmap_link); 929 951 dev = cli->dev; 930 952 } 931 953 fibril_rwlock_read_unlock(&classes->rwlock); 932 954 933 return dev; 934 } 935 955 return dev; 956 } 936 957 937 958 /** @} -
uspace/srv/devman/devman.h
r032e0bb r38b3baf 61 61 62 62 typedef enum { 63 /** driver has not been started*/63 /** Driver has not been started. */ 64 64 DRIVER_NOT_STARTED = 0, 65 /** driver has been started, but has not registered as running and ready to receive requests */ 65 66 /** 67 * Driver has been started, but has not registered as running and ready 68 * to receive requests. 69 */ 66 70 DRIVER_STARTING, 67 /** driver is running and prepared to serve incomming requests */ 71 72 /** Driver is running and prepared to serve incomming requests. */ 68 73 DRIVER_RUNNING 69 74 } driver_state_t; 70 75 71 /** Representation of device driver. 72 */ 76 /** Representation of device driver. */ 73 77 typedef struct driver { 74 /** Pointers to previous and next drivers in a linked list */78 /** Pointers to previous and next drivers in a linked list. */ 75 79 link_t drivers; 76 /** Specifies whether the driver has been started and wheter is running and prepared to receive requests.*/ 80 81 /** 82 * Specifies whether the driver has been started and wheter is running 83 * and prepared to receive requests. 84 */ 77 85 int state; 78 /** Phone asociated with this driver */ 86 87 /** Phone asociated with this driver. */ 79 88 ipcarg_t phone; 80 /** Name of the device driver */89 /** Name of the device driver. */ 81 90 char *name; 82 /** Path to the driver's binary */91 /** Path to the driver's binary. */ 83 92 const char *binary_path; 84 /** List of device ids for device-to-driver matching. */93 /** List of device ids for device-to-driver matching. */ 85 94 match_id_list_t match_ids; 86 /** Pointer to the linked list of devices controlled by this driver */95 /** Pointer to the linked list of devices controlled by this driver. */ 87 96 link_t devices; 88 /** Fibril mutex for this driver - driver state, list of devices, phone.*/ 97 98 /** 99 * Fibril mutex for this driver - driver state, list of devices, phone. 100 */ 89 101 fibril_mutex_t driver_mutex; 90 102 } driver_t; … … 95 107 link_t drivers; 96 108 /** Fibril mutex for list of drivers. */ 97 fibril_mutex_t drivers_mutex; 109 fibril_mutex_t drivers_mutex; 98 110 } driver_list_t; 99 111 … … 106 118 } device_state_t; 107 119 108 /** Representation of a node in the device tree. */120 /** Representation of a node in the device tree. */ 109 121 struct node { 110 /** The global unique identifier of the device. */122 /** The global unique identifier of the device. */ 111 123 device_handle_t handle; 112 124 /** The name of the device specified by its parent. */ 113 125 char *name; 114 /** Full path and name of the device in device hierarchi (i. e. in full path in device tree).*/ 115 char *pathname; 126 127 /** 128 * Full path and name of the device in device hierarchi (i. e. in full 129 * path in device tree). 130 */ 131 char *pathname; 132 116 133 /** The node of the parent device. */ 117 134 node_t *parent; 118 /** Pointers to previous and next child devices in the linked list of parent device's node.*/ 135 136 /** 137 * Pointers to previous and next child devices in the linked list of 138 * parent device's node. 139 */ 119 140 link_t sibling; 141 120 142 /** List of child device nodes. */ 121 143 link_t children; 122 /** List of device ids for device-to-driver matching. */144 /** List of device ids for device-to-driver matching. */ 123 145 match_id_list_t match_ids; 124 /** Driver of this device. */146 /** Driver of this device. */ 125 147 driver_t *drv; 126 148 /** The state of the device. */ 127 149 device_state_t state; 128 /** Pointer to the previous and next device in the list of devices 129 owned by one driver */ 150 /** 151 * Pointer to the previous and next device in the list of devices 152 * owned by one driver. 153 */ 130 154 link_t driver_devices; 131 /** The list of device classes to which this device belongs.*/ 155 156 /** The list of device classes to which this device belongs. */ 132 157 link_t classes; 133 158 /** Devmap handle if the device is registered by devmapper. */ 134 159 dev_handle_t devmap_handle; 135 /** Used by the hash table of devices indexed by devman device handles.*/ 160 161 /** 162 * Used by the hash table of devices indexed by devman device handles. 163 */ 136 164 link_t devman_link; 137 /** Used by the hash table of devices indexed by devmap device handles.*/ 165 166 /** 167 * Used by the hash table of devices indexed by devmap device handles. 168 */ 138 169 link_t devmap_link; 139 170 }; 140 171 141 142 /** Represents device tree. 143 */ 172 /** Represents device tree. */ 144 173 typedef struct dev_tree { 145 174 /** Root device node. */ 146 175 node_t *root_node; 147 /** The next available handle - handles are assigned in a sequential manner.*/ 176 177 /** 178 * The next available handle - handles are assigned in a sequential 179 * manner. 180 */ 148 181 device_handle_t current_handle; 149 /** Synchronize access to the device tree.*/ 182 183 /** Synchronize access to the device tree. */ 150 184 fibril_rwlock_t rwlock; 151 /** Hash table of all devices indexed by devman handles.*/ 185 186 /** Hash table of all devices indexed by devman handles. */ 152 187 hash_table_t devman_devices; 153 /** Hash table of devices registered by devmapper, indexed by devmap handles.*/ 188 189 /** 190 * Hash table of devices registered by devmapper, indexed by devmap 191 * handles. 192 */ 154 193 hash_table_t devmap_devices; 155 194 } dev_tree_t; 156 195 157 typedef struct dev_class { 158 /** The name of the class. */196 typedef struct dev_class { 197 /** The name of the class. */ 159 198 const char *name; 160 /** Pointer to the previous and next class in the list of registered classes.*/ 161 link_t link; 162 /** List of dev_class_info structures - one for each device registered by this class.*/ 199 200 /** 201 * Pointer to the previous and next class in the list of registered 202 * classes. 203 */ 204 link_t link; 205 206 /** 207 * List of dev_class_info structures - one for each device registered by 208 * this class. 209 */ 163 210 link_t devices; 164 /** Default base name for the device within the class, might be overrided by the driver.*/ 211 212 /** 213 * Default base name for the device within the class, might be overrided 214 * by the driver. 215 */ 165 216 const char *base_dev_name; 166 /** Unique numerical identifier of the newly added device.*/ 217 218 /** Unique numerical identifier of the newly added device. */ 167 219 size_t curr_dev_idx; 168 220 /** Synchronize access to the list of devices in this class. */ … … 170 222 } dev_class_t; 171 223 172 /** Provides n-to-m mapping between device nodes and classes 173 * - each device may be register to the arbitrary number of classes 174 * and each class may contain the arbitrary number of devices. */ 224 /** Provides n-to-m mapping between device nodes and classes - each device may 225 * be register to the arbitrary number of classes and each class may contain 226 * the arbitrary number of devices. 227 */ 175 228 typedef struct dev_class_info { 176 /** The class. */229 /** The class. */ 177 230 dev_class_t *dev_class; 178 /** The device. */231 /** The device. */ 179 232 node_t *dev; 180 /** Pointer to the previous and next class info in the list of devices registered by the class.*/ 233 234 /** 235 * Pointer to the previous and next class info in the list of devices 236 * registered by the class. 237 */ 181 238 link_t link; 182 /** Pointer to the previous and next class info in the list of classes by which the device is registered.*/ 239 240 /** 241 * Pointer to the previous and next class info in the list of classes 242 * by which the device is registered. 243 */ 183 244 link_t dev_classes; 184 /** The name of the device within the class.*/ 185 char *dev_name; 186 /** The handle of the device by device mapper in the class namespace.*/ 245 246 /** The name of the device within the class. */ 247 char *dev_name; 248 /** The handle of the device by device mapper in the class namespace. */ 187 249 dev_handle_t devmap_handle; 188 /** Link in the hash table of devices registered by the devmapper using their class names.*/ 250 251 /** 252 * Link in the hash table of devices registered by the devmapper using 253 * their class names. 254 */ 189 255 link_t devmap_link; 190 256 } dev_class_info_t; … … 192 258 /** The list of device classes. */ 193 259 typedef struct class_list { 194 /** List of classes */260 /** List of classes. */ 195 261 link_t classes; 196 /** Hash table of devices registered by devmapper using their class name, indexed by devmap handles.*/ 262 263 /** 264 * Hash table of devices registered by devmapper using their class name, 265 * indexed by devmap handles. 266 */ 197 267 hash_table_t devmap_devices; 268 198 269 /** Fibril mutex for list of classes. */ 199 fibril_rwlock_t rwlock; 270 fibril_rwlock_t rwlock; 200 271 } class_list_t; 201 272 202 / / Match ids and scores203 204 int get_match_score(driver_t *drv, node_t *dev);205 206 bool parse_match_ids(char *buf, match_id_list_t *ids);207 bool read_match_ids(const char *conf_path, match_id_list_t *ids);208 char * read_match_id(char **buf);209 char * read_id(const char **buf);210 211 / / Drivers212 213 /** 273 /* Match ids and scores */ 274 275 extern int get_match_score(driver_t *, node_t *); 276 277 extern bool parse_match_ids(char *, match_id_list_t *); 278 extern bool read_match_ids(const char *, match_id_list_t *); 279 extern char *read_match_id(char **); 280 extern char *read_id(const char **); 281 282 /* Drivers */ 283 284 /** 214 285 * Initialize the list of device driver's. 215 * 286 * 216 287 * @param drv_list the list of device driver's. 217 * 218 */ 219 static inline void init_driver_list(driver_list_t *drv_list) 288 * 289 */ 290 static inline void init_driver_list(driver_list_t *drv_list) 220 291 { 221 292 assert(NULL != drv_list); 222 293 223 294 list_initialize(&drv_list->drivers); 224 fibril_mutex_initialize(&drv_list->drivers_mutex); 225 } 226 227 driver_t * create_driver(void); 228 bool get_driver_info(const char *base_path, const char *name, driver_t *drv); 229 int lookup_available_drivers(driver_list_t *drivers_list, const char *dir_path); 230 231 driver_t * find_best_match_driver(driver_list_t *drivers_list, node_t *node); 232 bool assign_driver(node_t *node, driver_list_t *drivers_list, dev_tree_t *tree); 233 234 void add_driver(driver_list_t *drivers_list, driver_t *drv); 235 void attach_driver(node_t *node, driver_t *drv); 236 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree); 237 bool start_driver(driver_t *drv); 238 239 driver_t * find_driver(driver_list_t *drv_list, const char *drv_name); 240 void set_driver_phone(driver_t *driver, ipcarg_t phone); 241 void initialize_running_driver(driver_t *driver, dev_tree_t *tree); 242 243 /** 244 * Initialize device driver structure. 245 * 246 * @param drv the device driver structure. 247 * 295 fibril_mutex_initialize(&drv_list->drivers_mutex); 296 } 297 298 extern driver_t *create_driver(void); 299 extern bool get_driver_info(const char *, const char *, driver_t *); 300 extern int lookup_available_drivers(driver_list_t *, const char *); 301 302 extern driver_t *find_best_match_driver(driver_list_t *, node_t *); 303 extern bool assign_driver(node_t *, driver_list_t *, dev_tree_t *); 304 305 extern void add_driver(driver_list_t *, driver_t *); 306 extern void attach_driver(node_t *, driver_t *); 307 extern void add_device(int, driver_t *, node_t *, dev_tree_t *); 308 extern bool start_driver(driver_t *); 309 310 extern driver_t *find_driver(driver_list_t *, const char *); 311 extern void set_driver_phone(driver_t *, ipcarg_t); 312 void initialize_running_driver(driver_t *, dev_tree_t *); 313 314 /** Initialize device driver structure. 315 * 316 * @param drv The device driver structure. 248 317 */ 249 318 static inline void init_driver(driver_t *drv) … … 254 323 list_initialize(&drv->match_ids.ids); 255 324 list_initialize(&drv->devices); 256 fibril_mutex_initialize(&drv->driver_mutex); 257 } 258 259 /** 260 * Device driver structure clean-up. 261 * 262 * @param drv the device driver structure. 325 fibril_mutex_initialize(&drv->driver_mutex); 326 } 327 328 /** Device driver structure clean-up. 329 * 330 * @param drv The device driver structure. 263 331 */ 264 332 static inline void clean_driver(driver_t *drv) … … 267 335 268 336 free_not_null(drv->name); 269 free_not_null(drv->binary_path); 337 free_not_null(drv->binary_path); 270 338 271 339 clean_match_ids(&drv->match_ids); … … 274 342 } 275 343 276 /** 277 * Delete device driver structure. 278 * 279 * @param drv the device driver structure.* 344 /** Delete device driver structure. 345 * 346 * @param drv The device driver structure. 280 347 */ 281 348 static inline void delete_driver(driver_t *drv) … … 287 354 } 288 355 289 // Device nodes 290 /* *291 * Create a new device node. 292 * 293 * @return a device node structure.294 * 295 */ 296 static inline node_t * create_dev_node()356 357 /* Device nodes */ 358 359 /** Create a new device node. 360 * 361 * @return A device node structure. 362 */ 363 static inline node_t *create_dev_node(void) 297 364 { 298 365 node_t *res = malloc(sizeof(node_t)); … … 308 375 } 309 376 310 /** 311 * Delete a device node. 312 * 313 * @param node a device node structure. 314 * 377 /** Delete a device node. 378 * 379 * @param node The device node structure. 315 380 */ 316 381 static inline void delete_dev_node(node_t *node) 317 382 { 318 assert(list_empty(&node->children) && NULL == node->parent && NULL == node->drv); 383 assert(list_empty(&node->children)); 384 assert(NULL == node->parent); 385 assert(NULL == node->drv); 319 386 320 387 clean_match_ids(&node->match_ids); 321 388 free_not_null(node->name); 322 389 free_not_null(node->pathname); 323 free(node); 324 } 325 326 /** 327 * Find the device node structure of the device witch has the specified handle. 328 * 390 free(node); 391 } 392 393 /** Find the device node structure of the device witch has the specified handle. 394 * 329 395 * Device tree's rwlock should be held at least for reading. 330 * 331 * @param tree the device tree where we look for the device node. 332 * @param handle the handle of the device. 333 * @return the device node. 334 */ 335 static inline node_t * find_dev_node_no_lock(dev_tree_t *tree, device_handle_t handle) 396 * 397 * @param tree The device tree where we look for the device node. 398 * @param handle The handle of the device. 399 * @return The device node. 400 */ 401 static inline node_t * 402 find_dev_node_no_lock(dev_tree_t *tree, device_handle_t handle) 336 403 { 337 404 unsigned long key = handle; … … 340 407 } 341 408 342 /** 343 * Find the device node structure of the device witch has the specified handle.344 * 345 * @param tree the device tree where we look for the device node.346 * @ param handle the handle of the device.347 * @return the device node.348 */ 349 static inline node_t *find_dev_node(dev_tree_t *tree, device_handle_t handle)409 /** Find the device node structure of the device witch has the specified handle. 410 * 411 * @param tree The device tree where we look for the device node. 412 * @param handle The handle of the device. 413 * @return The device node. 414 */ 415 static inline node_t * 416 find_dev_node(dev_tree_t *tree, device_handle_t handle) 350 417 { 351 418 node_t *node = NULL; 352 419 353 420 fibril_rwlock_read_lock(&tree->rwlock); 354 355 421 node = find_dev_node_no_lock(tree, handle); 356 357 422 fibril_rwlock_read_unlock(&tree->rwlock); 358 423 … … 360 425 } 361 426 362 node_t * find_dev_node_by_path(dev_tree_t *tree, char *path); 363 node_t *find_node_child(node_t *parent, const char *name); 364 365 // Device tree 366 367 bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list); 368 bool create_root_node(dev_tree_t *tree); 369 bool insert_dev_node(dev_tree_t *tree, node_t *node, char *dev_name, node_t *parent); 370 371 // Device classes 372 373 /** Create device class. 374 * 375 * @return device class. 376 */ 377 static inline dev_class_t * create_dev_class() 378 { 379 dev_class_t *cl = (dev_class_t *)malloc(sizeof(dev_class_t)); 427 extern node_t *find_dev_node_by_path(dev_tree_t *, char *); 428 extern node_t *find_node_child(node_t *, const char *); 429 430 431 /* Device tree */ 432 433 extern bool init_device_tree(dev_tree_t *, driver_list_t *); 434 extern bool create_root_node(dev_tree_t *); 435 extern bool insert_dev_node(dev_tree_t *, node_t *, char *, node_t *); 436 437 438 /* Device classes */ 439 440 /** Create device class. 441 * 442 * @return Device class. 443 */ 444 static inline dev_class_t *create_dev_class(void) 445 { 446 dev_class_t *cl; 447 448 cl = (dev_class_t *) malloc(sizeof(dev_class_t)); 380 449 if (NULL != cl) { 381 450 memset(cl, 0, sizeof(dev_class_t)); … … 383 452 fibril_mutex_initialize(&cl->mutex); 384 453 } 385 return cl; 386 } 387 388 /** Create device class info. 389 * 390 * @return device class info. 391 */ 392 static inline dev_class_info_t * create_dev_class_info() 393 { 394 dev_class_info_t *info = (dev_class_info_t *)malloc(sizeof(dev_class_info_t)); 395 if (NULL != info) { 454 455 return cl; 456 } 457 458 /** Create device class info. 459 * 460 * @return Device class info. 461 */ 462 static inline dev_class_info_t *create_dev_class_info(void) 463 { 464 dev_class_info_t *info; 465 466 info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t)); 467 if (NULL != info) 396 468 memset(info, 0, sizeof(dev_class_info_t)); 397 }398 return info; 469 470 return info; 399 471 } 400 472 … … 402 474 { 403 475 size_t dev_idx; 476 404 477 fibril_mutex_lock(&cl->mutex); 405 478 dev_idx = ++cl->curr_dev_idx; 406 479 fibril_mutex_unlock(&cl->mutex); 480 407 481 return dev_idx; 408 482 } 409 483 410 char * create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name); 411 dev_class_info_t * add_device_to_class(node_t *dev, dev_class_t *cl, const char *base_dev_name); 412 413 void init_class_list(class_list_t *class_list); 414 415 dev_class_t * get_dev_class(class_list_t *class_list, char *class_name); 416 dev_class_t * find_dev_class_no_lock(class_list_t *class_list, const char *class_name); 417 418 static inline void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl) 484 extern char *create_dev_name_for_class(dev_class_t *, const char *); 485 extern dev_class_info_t *add_device_to_class(node_t *, dev_class_t *, 486 const char *); 487 488 extern void init_class_list(class_list_t *); 489 490 extern dev_class_t *get_dev_class(class_list_t *, char *); 491 extern dev_class_t *find_dev_class_no_lock(class_list_t *, const char *); 492 493 static inline void 494 add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl) 419 495 { 420 496 list_append(&cl->link, &class_list->classes); … … 422 498 423 499 424 // devmap devices 425 426 node_t *find_devmap_tree_device(dev_tree_t *tree, dev_handle_t devmap_handle); 427 node_t *find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle); 428 429 430 static inline void class_add_devmap_device(class_list_t *class_list, dev_class_info_t *cli) 431 { 432 unsigned long key = (unsigned long)cli->devmap_handle; 500 /* Devmap devices */ 501 502 extern node_t *find_devmap_tree_device(dev_tree_t *, dev_handle_t); 503 extern node_t *find_devmap_class_device(class_list_t *, dev_handle_t); 504 505 static inline void 506 class_add_devmap_device(class_list_t *class_list, dev_class_info_t *cli) 507 { 508 unsigned long key = (unsigned long) cli->devmap_handle; 509 433 510 fibril_rwlock_write_lock(&class_list->rwlock); 434 511 hash_table_insert(&class_list->devmap_devices, &key, &cli->devmap_link); … … 438 515 static inline void tree_add_devmap_device(dev_tree_t *tree, node_t *node) 439 516 { 440 unsigned long key = (unsigned long) node->devmap_handle;517 unsigned long key = (unsigned long) node->devmap_handle; 441 518 fibril_rwlock_write_lock(&tree->rwlock); 442 519 hash_table_insert(&tree->devmap_devices, &key, &node->devmap_link); 443 fibril_rwlock_write_unlock(&tree->rwlock); 520 fibril_rwlock_write_unlock(&tree->rwlock); 444 521 } 445 522 -
uspace/srv/devman/main.c
r032e0bb r38b3baf 63 63 static class_list_t class_list; 64 64 65 /** 66 * Register running driver. 67 */ 68 static driver_t * devman_driver_register(void) 69 { 65 /** Register running driver. */ 66 static driver_t *devman_driver_register(void) 67 { 70 68 printf(NAME ": devman_driver_register \n"); 71 69 … … 81 79 char *drv_name = NULL; 82 80 83 / / Get driver name84 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);81 /* Get driver name. */ 82 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); 85 83 if (rc != EOK) { 86 84 ipc_answer_0(iid, rc); 87 85 return NULL; 88 86 } 89 printf(NAME ": the %s driver is trying to register by the service.\n", drv_name); 90 91 // Find driver structure 87 printf(NAME ": the %s driver is trying to register by the service.\n", 88 drv_name); 89 90 /* Find driver structure. */ 92 91 driver = find_driver(&drivers_list, drv_name); 93 92 … … 103 102 drv_name = NULL; 104 103 105 / / Create connection to the driver106 printf(NAME ": creating connection to the %s driver.\n", driver->name); 104 /* Create connection to the driver. */ 105 printf(NAME ": creating connection to the %s driver.\n", driver->name); 107 106 ipc_call_t call; 108 ipc_callid_t callid = async_get_call(&call); 107 ipc_callid_t callid = async_get_call(&call); 109 108 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { 110 109 ipc_answer_0(callid, ENOTSUP); … … 113 112 } 114 113 115 / / remember driver's phone114 /* Remember driver's phone. */ 116 115 set_driver_phone(driver, IPC_GET_ARG5(call)); 117 116 118 printf(NAME ": the %s driver was successfully registered as running.\n", driver->name);119 120 ipc_answer_0(callid, EOK);121 117 printf(NAME ": the %s driver was successfully registered as running.\n", 118 driver->name); 119 120 ipc_answer_0(callid, EOK); 122 121 ipc_answer_0(iid, EOK); 123 122 … … 125 124 } 126 125 127 /** 128 * Receive device match ID from the device's parent driver and add it to the list of devices match ids. 129 * 130 * @param match_ids the list of the device's match ids. 131 * 132 * @return 0 on success, negative error code otherwise. 133 */ 134 static int devman_receive_match_id(match_id_list_t *match_ids) { 135 126 /** Receive device match ID from the device's parent driver and add it to the 127 * list of devices match ids. 128 * 129 * @param match_ids The list of the device's match ids. 130 * @return Zero on success, negative error code otherwise. 131 */ 132 static int devman_receive_match_id(match_id_list_t *match_ids) 133 { 136 134 match_id_t *match_id = create_match_id(); 137 135 ipc_callid_t callid; … … 141 139 callid = async_get_call(&call); 142 140 if (DEVMAN_ADD_MATCH_ID != IPC_GET_METHOD(call)) { 143 printf(NAME ": ERROR: devman_receive_match_id - invalid protocol.\n"); 141 printf(NAME ": ERROR: devman_receive_match_id - invalid " 142 "protocol.\n"); 144 143 ipc_answer_0(callid, EINVAL); 145 144 delete_match_id(match_id); … … 148 147 149 148 if (NULL == match_id) { 150 printf(NAME ": ERROR: devman_receive_match_id - failed to allocate match id.\n"); 149 printf(NAME ": ERROR: devman_receive_match_id - failed to " 150 "allocate match id.\n"); 151 151 ipc_answer_0(callid, ENOMEM); 152 152 return ENOMEM; … … 158 158 159 159 char *match_id_str; 160 rc = async_data_write_accept((void **) &match_id_str, true, 0, 0, 0, 0);160 rc = async_data_write_accept((void **) &match_id_str, true, 0, 0, 0, 0); 161 161 match_id->id = match_id_str; 162 162 if (EOK != rc) { 163 163 delete_match_id(match_id); 164 printf(NAME ": devman_receive_match_id - failed to receive match id string.\n"); 164 printf(NAME ": devman_receive_match_id - failed to receive " 165 "match id string.\n"); 165 166 return rc; 166 167 } … … 168 169 list_append(&match_id->link, &match_ids->ids); 169 170 170 printf(NAME ": received match id '%s', score = %d \n", match_id->id, match_id->score); 171 printf(NAME ": received match id '%s', score = %d \n", 172 match_id->id, match_id->score); 171 173 return rc; 172 174 } 173 175 174 /** 175 * Receive device match IDs from the device's parent driver 176 * and add them to the list of devices match ids. 177 * 178 * @param match_count the number of device's match ids to be received. 179 * @param match_ids the list of the device's match ids. 180 * 181 * @return 0 on success, negative error code otherwise. 182 */ 183 static int devman_receive_match_ids(ipcarg_t match_count, match_id_list_t *match_ids) 184 { 176 /** Receive device match IDs from the device's parent driver and add them to the 177 * list of devices match ids. 178 * 179 * @param match_count The number of device's match ids to be received. 180 * @param match_ids The list of the device's match ids. 181 * @return Zero on success, negative error code otherwise. 182 */ 183 static int 184 devman_receive_match_ids(ipcarg_t match_count, match_id_list_t *match_ids) 185 { 185 186 int ret = EOK; 186 187 size_t i; 188 187 189 for (i = 0; i < match_count; i++) { 188 if (EOK != (ret = devman_receive_match_id(match_ids))) {190 if (EOK != (ret = devman_receive_match_id(match_ids))) 189 191 return ret; 190 }191 192 } 192 193 return ret; 193 194 } 194 195 195 /** Handle child device registration. 196 * 196 /** Handle child device registration. 197 * 197 198 * Child devices are registered by their parent's device driver. 198 199 */ 199 200 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call) 200 201 { 201 //printf(NAME ": devman_add_child\n");202 203 202 device_handle_t parent_handle = IPC_GET_ARG1(*call); 204 203 ipcarg_t match_count = IPC_GET_ARG2(*call); … … 215 214 216 215 char *dev_name = NULL; 217 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 216 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 218 217 if (EOK != rc) { 219 218 fibril_rwlock_write_unlock(&tree->rwlock); … … 221 220 return; 222 221 } 223 //printf(NAME ": newly added child device's name is '%s'.\n", dev_name);224 222 225 223 node_t *node = create_dev_node(); … … 236 234 devman_receive_match_ids(match_count, &node->match_ids); 237 235 238 / / return device handle to parent's driver236 /* Return device handle to parent's driver. */ 239 237 ipc_answer_1(callid, EOK, node->handle); 240 238 241 / / try to find suitable driver and assign it to the device242 assign_driver(node, &drivers_list, &device_tree); 239 /* Try to find suitable driver and assign it to the device. */ 240 assign_driver(node, &drivers_list, &device_tree); 243 241 } 244 242 245 243 static void devmap_register_class_dev(dev_class_info_t *cli) 246 244 { 247 / / create devmap path and name for the device245 /* Create devmap path and name for the device. */ 248 246 char *devmap_pathname = NULL; 249 asprintf(&devmap_pathname, "%s/%s%c%s", DEVMAP_CLASS_NAMESPACE, cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name); 250 if (NULL == devmap_pathname) { 251 return; 252 } 253 254 // register the device by the device mapper and remember its devmap handle 255 devmap_device_register(devmap_pathname, &cli->devmap_handle); 256 257 // add device to the hash map of class devices registered by device mapper 247 asprintf(&devmap_pathname, "%s/%s%c%s", DEVMAP_CLASS_NAMESPACE, 248 cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name); 249 if (NULL == devmap_pathname) 250 return; 251 252 /* 253 * Register the device by the device mapper and remember its devmap 254 * handle. 255 */ 256 devmap_device_register(devmap_pathname, &cli->devmap_handle); 257 258 /* 259 * Add device to the hash map of class devices registered by device 260 * mapper. 261 */ 258 262 class_add_devmap_device(&class_list, cli); 259 263 260 free(devmap_pathname); 264 free(devmap_pathname); 261 265 } 262 266 … … 265 269 device_handle_t handle = IPC_GET_ARG1(*call); 266 270 267 / / Get class name271 /* Get class name. */ 268 272 char *class_name; 269 int rc = async_data_write_accept((void **)&class_name, true, 0, 0, 0, 0); 273 int rc = async_data_write_accept((void **) &class_name, true, 274 0, 0, 0, 0); 270 275 if (rc != EOK) { 271 276 ipc_answer_0(callid, rc); … … 280 285 281 286 dev_class_t *cl = get_dev_class(&class_list, class_name); 282 283 287 dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL); 284 288 285 / / register the device's class alias by devmapper289 /* Register the device's class alias by devmapper. */ 286 290 devmap_register_class_dev(class_info); 287 291 288 printf(NAME ": device '%s' added to class '%s', class name '%s' was asigned to it\n", dev->pathname, class_name, class_info->dev_name);289 290 ipc_answer_0(callid, EOK);291 } 292 293 /** 294 295 * 296 * The initialization is done in a separate fibril to avoid deadlocks 297 * (if the driver needed to be served by devman during the driver's initialization).292 printf(NAME ": device '%s' added to class '%s', class name '%s' was " 293 "asigned to it\n", dev->pathname, class_name, class_info->dev_name); 294 295 ipc_answer_0(callid, EOK); 296 } 297 298 /** Initialize driver which has registered itself as running and ready. 299 * 300 * The initialization is done in a separate fibril to avoid deadlocks (if the 301 * driver needed to be served by devman during the driver's initialization). 298 302 */ 299 303 static int init_running_drv(void *drv) 300 304 { 301 driver_t *driver = (driver_t *)drv; 302 initialize_running_driver(driver, &device_tree); 303 printf(NAME ": the %s driver was successfully initialized. \n", driver->name); 305 driver_t *driver = (driver_t *) drv; 306 307 initialize_running_driver(driver, &device_tree); 308 printf(NAME ": the %s driver was successfully initialized. \n", 309 driver->name); 304 310 return 0; 305 311 } 306 312 307 /** Function for handling connections from a driver to the device manager. 308 */ 313 /** Function for handling connections from a driver to the device manager. */ 309 314 static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 310 { 311 /* Accept the connection */315 { 316 /* Accept the connection. */ 312 317 ipc_answer_0(iid, EOK); 313 318 … … 316 321 return; 317 322 318 // Initialize the driver as running (e.g. pass assigned devices to it) in a separate fibril; 319 // the separate fibril is used to enable the driver 320 // to use devman service during the driver's initialization. 323 /* 324 * Initialize the driver as running (e.g. pass assigned devices to it) 325 * in a separate fibril; the separate fibril is used to enable the 326 * driver to use devman service during the driver's initialization. 327 */ 321 328 fid_t fid = fibril_create(init_running_drv, driver); 322 329 if (fid == 0) { 323 printf(NAME ": Error creating fibril for the initialization of the newly registered running driver.\n"); 330 printf(NAME ": Error creating fibril for the initialization of " 331 "the newly registered running driver.\n"); 324 332 return; 325 333 } 326 334 fibril_add_ready(fid); 327 328 /*thread_id_t tid;329 if (0 != thread_create(init_running_drv, driver, "init_running_drv", &tid)) {330 printf(NAME ": failed to start the initialization of the newly registered running driver.\n");331 }*/332 335 333 336 ipc_callid_t callid; … … 354 357 } 355 358 356 /** Find handle for the device instance identified by the device's path in the device tree.357 * /359 /** Find handle for the device instance identified by the device's path in the 360 * device tree. */ 358 361 static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 359 362 { 360 char *pathname; 361 int rc = async_data_write_accept((void **)&pathname, true, 0, 0, 0, 0); 363 char *pathname; 364 365 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); 362 366 if (rc != EOK) { 363 367 ipc_answer_0(iid, rc); … … 365 369 } 366 370 367 node_t * dev = find_dev_node_by_path(&device_tree, pathname); 371 node_t * dev = find_dev_node_by_path(&device_tree, pathname); 368 372 369 373 free(pathname); … … 378 382 379 383 380 /** Function for handling connections from a client to the device manager. 381 */ 384 /** Function for handling connections from a client to the device manager. */ 382 385 static void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall) 383 386 { 384 /* Accept connection */387 /* Accept connection. */ 385 388 ipc_answer_0(iid, EOK); 386 389 … … 404 407 } 405 408 406 static void devman_forward(ipc_callid_t iid, ipc_call_t *icall, bool drv_to_parent) { 407 409 static void 410 devman_forward(ipc_callid_t iid, ipc_call_t *icall, bool drv_to_parent) 411 { 408 412 device_handle_t handle = IPC_GET_ARG2(*icall); 409 // printf(NAME ": devman_forward - trying to forward connection to device with handle %x.\n", handle);410 413 411 414 node_t *dev = find_dev_node(&device_tree, handle); 412 415 if (NULL == dev) { 413 printf(NAME ": devman_forward error - no device with handle %x was found.\n", handle); 416 printf(NAME ": devman_forward error - no device with handle %x " 417 "was found.\n", handle); 414 418 ipc_answer_0(iid, ENOENT); 415 419 return; … … 419 423 420 424 if (drv_to_parent) { 421 if (NULL != dev->parent) { 422 driver = dev->parent->drv; 423 } 425 if (NULL != dev->parent) 426 driver = dev->parent->drv; 424 427 } else if (DEVICE_USABLE == dev->state) { 425 driver = dev->drv; 428 driver = dev->drv; 426 429 assert(NULL != driver); 427 430 } 428 431 429 if (NULL == driver) { 430 printf(NAME ": devman_forward error - the device is not in usable state.\n", handle); 432 if (NULL == driver) { 433 printf(NAME ": devman_forward error - the device is not in " 434 "usable state.\n", handle); 431 435 ipc_answer_0(iid, ENOENT); 432 return; 433 } 434 435 int method; 436 if (drv_to_parent) {436 return; 437 } 438 439 int method; 440 if (drv_to_parent) 437 441 method = DRIVER_DRIVER; 438 } else {442 else 439 443 method = DRIVER_CLIENT; 440 }441 444 442 445 if (driver->phone <= 0) { 443 printf(NAME ": devman_forward: cound not forward to driver %s ", driver->name); 446 printf(NAME ": devman_forward: cound not forward to driver %s ", 447 driver->name); 444 448 printf("the driver's phone is %x).\n", driver->phone); 445 449 ipc_answer_0(iid, EINVAL); 446 450 return; 447 451 } 448 printf(NAME ": devman_forward: forward connection to device %s to driver %s.\n",449 450 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 451 } 452 453 /** Function for handling connections from a client forwarded by the device mapper to the device manager.454 * /452 printf(NAME ": devman_forward: forward connection to device %s to " 453 "driver %s.\n", dev->pathname, driver->name); 454 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 455 } 456 457 /** Function for handling connections from a client forwarded by the device 458 * mapper to the device manager. */ 455 459 static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall) 456 460 { 457 461 dev_handle_t devmap_handle = IPC_GET_METHOD(*icall); 462 458 463 node_t *dev = find_devmap_tree_device(&device_tree, devmap_handle); 459 if (NULL == dev) {464 if (NULL == dev) 460 465 dev = find_devmap_class_device(&class_list, devmap_handle); 461 }462 466 463 467 if (NULL == dev || NULL == dev->drv) { … … 471 475 } 472 476 473 printf(NAME ": devman_connection_devmapper: forward connection to device %s to driver %s.\n", 474 dev->pathname, dev->drv->name); 475 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, IPC_FF_NONE); 476 } 477 478 /** Function for handling connections to device manager. 479 * 480 */ 477 printf(NAME ": devman_connection_devmapper: forward connection to " 478 "device %s to driver %s.\n", dev->pathname, dev->drv->name); 479 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, 480 IPC_FF_NONE); 481 } 482 483 /** Function for handling connections to device manager. */ 481 484 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall) 482 { 483 // Silly hack to enable the device manager to register as a driver by the device mapper. 484 // If the ipc method is not IPC_M_CONNECT_ME_TO, this is not the forwarded connection from naming service, 485 // so it must be a connection from the devmapper which thinks this is a devmapper-style driver. 486 // So pretend this is a devmapper-style driver. 487 // (This does not work for device with handle == IPC_M_CONNECT_ME_TO, 488 // because devmapper passes device handle to the driver as an ipc method.) 489 if (IPC_M_CONNECT_ME_TO != IPC_GET_METHOD(*icall)) { 485 { 486 /* 487 * Silly hack to enable the device manager to register as a driver by 488 * the device mapper. If the ipc method is not IPC_M_CONNECT_ME_TO, this 489 * is not the forwarded connection from naming service, so it must be a 490 * connection from the devmapper which thinks this is a devmapper-style 491 * driver. So pretend this is a devmapper-style driver. (This does not 492 * work for device with handle == IPC_M_CONNECT_ME_TO, because devmapper 493 * passes device handle to the driver as an ipc method.) 494 */ 495 if (IPC_M_CONNECT_ME_TO != IPC_GET_METHOD(*icall)) 490 496 devman_connection_devmapper(iid, icall); 491 } 492 493 // ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection from naming service 494 // by which we registered as device manager, so be device manager 495 496 // Select interface 497 498 /* 499 * ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection 500 * from naming service by which we registered as device manager, so be 501 * device manager. 502 */ 503 504 /* Select interface. */ 497 505 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { 498 506 case DEVMAN_DRIVER: … … 503 511 break; 504 512 case DEVMAN_CONNECT_TO_DEVICE: 505 / / Connect client to selected device513 /* Connect client to selected device. */ 506 514 devman_forward(iid, icall, false); 507 515 break; 508 516 case DEVMAN_CONNECT_TO_PARENTS_DEVICE: 509 / / Connect client to selected device517 /* Connect client to selected device. */ 510 518 devman_forward(iid, icall, true); 511 break; 519 break; 512 520 default: 513 521 /* No such interface */ … … 516 524 } 517 525 518 /** Initialize device manager internal structures. 519 */ 520 static bool devman_init() 521 { 522 printf(NAME ": devman_init - looking for available drivers. \n"); 523 524 // initialize list of available drivers 526 /** Initialize device manager internal structures. */ 527 static bool devman_init(void) 528 { 529 printf(NAME ": devman_init - looking for available drivers.\n"); 530 531 /* Initialize list of available drivers. */ 525 532 init_driver_list(&drivers_list); 526 if (0 == lookup_available_drivers(&drivers_list, DRIVER_DEFAULT_STORE)) { 533 if (0 == lookup_available_drivers(&drivers_list, 534 DRIVER_DEFAULT_STORE)) { 527 535 printf(NAME " no drivers found."); 528 536 return false; 529 537 } 530 printf(NAME ": devman_init - list of drivers has been initialized. 531 532 / / create root device node538 printf(NAME ": devman_init - list of drivers has been initialized.\n"); 539 540 /* Create root device node. */ 533 541 if (!init_device_tree(&device_tree, &drivers_list)) { 534 542 printf(NAME " failed to initialize device tree."); 535 return false; 543 return false; 536 544 } 537 545 538 546 init_class_list(&class_list); 539 547 540 // !!! devman_connection ... as the device manager is not a real devmap driver 541 // (it uses a completely different ipc protocol than an ordinary devmap driver) 542 // forwarding a connection from client to the devman by devmapper would not work 543 devmap_driver_register(NAME, devman_connection); 548 /* 549 * !!! devman_connection ... as the device manager is not a real devmap 550 * driver (it uses a completely different ipc protocol than an ordinary 551 * devmap driver) forwarding a connection from client to the devman by 552 * devmapper would not work. 553 */ 554 devmap_driver_register(NAME, devman_connection); 544 555 545 556 return true; … … 555 566 } 556 567 557 / / Set a handler of incomming connections568 /* Set a handler of incomming connections. */ 558 569 async_set_client_connection(devman_connection); 559 570 560 / / Register device manager at naming service571 /* Register device manager at naming service. */ 561 572 ipcarg_t phonead; 562 573 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) … … 566 577 async_manager(); 567 578 568 / / Never reached579 /* Never reached. */ 569 580 return 0; 570 581 } -
uspace/srv/devman/match.c
r032e0bb r38b3baf 30 30 * @{ 31 31 */ 32 33 32 34 33 #include <str.h> 35 34 36 35 #include "devman.h" 37 36 38 39 37 int get_match_score(driver_t *drv, node_t *dev) 40 { 41 link_t * drv_head = &drv->match_ids.ids;42 link_t *dev_head = &dev->match_ids.ids;38 { 39 link_t *drv_head = &drv->match_ids.ids; 40 link_t *dev_head = &dev->match_ids.ids; 43 41 44 if (list_empty(drv_head) || list_empty(dev_head)) {42 if (list_empty(drv_head) || list_empty(dev_head)) 45 43 return 0; 46 }47 44 48 link_t *drv_link = drv->match_ids.ids.next;49 link_t *dev_link = dev->match_ids.ids.next;45 link_t *drv_link = drv->match_ids.ids.next; 46 link_t *dev_link = dev->match_ids.ids.next; 50 47 51 48 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link); … … 56 53 57 54 do { 58 if (0 == str_cmp(drv_id->id, dev_id->id)) { // we found a match 59 // return the score of the match 55 match_id_t *tmp_ma_id; 56 57 if (0 == str_cmp(drv_id->id, dev_id->id)) { 58 /* 59 * We found a match. 60 * Return the score of the match. 61 */ 60 62 return drv_id->score * dev_id->score; 61 63 } 62 64 63 // compute the next score we get, if we advance in the driver's list of match ids 65 /* 66 * Compute the next score we get, if we advance in the driver's 67 * list of match ids. 68 */ 64 69 if (drv_head != drv_link->next) { 65 score_next_drv = dev_id->score * list_get_instance(drv_link->next, match_id_t, link)->score; 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; 66 73 } else { 67 74 score_next_drv = 0; 68 75 } 69 76 70 // compute the next score we get, if we advance in the device's list of match ids 77 /* 78 * Compute the next score we get, if we advance in the device's 79 * list of match ids. 80 */ 71 81 if (dev_head != dev_link->next) { 72 score_next_dev = drv_id->score * list_get_instance(dev_link->next, match_id_t, link)->score; 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; 73 85 } else { 74 86 score_next_dev = 0; 75 87 } 76 88 77 // advance in one of the two lists, so we get the next highest score 89 /* 90 * Advance in one of the two lists, so we get the next highest 91 * score. 92 */ 78 93 if (score_next_drv > score_next_dev) { 79 94 drv_link = drv_link->next; … … 89 104 } 90 105 91 92 106 /** @} 107 */ -
uspace/srv/devman/util.c
r032e0bb r38b3baf 32 32 33 33 #include <stdlib.h> 34 #include <str.h> 35 34 #include <str.h> 35 36 36 #include "util.h" 37 38 37 39 char * get_abs_path(const char *base_path, const char *name, const char *ext)38 char *get_abs_path(const char *base_path, const char *name, const char *ext) 40 39 { 41 40 char *res; 42 41 int base_len = str_size(base_path); 43 int size = base_len + 2 *str_size(name) + str_size(ext) + 3;42 int size = base_len + 2 * str_size(name) + str_size(ext) + 3; 44 43 45 44 res = malloc(size); … … 47 46 if (res) { 48 47 str_cpy(res, size, base_path); 49 if(base_path[base_len - 1] != '/') { 50 str_append(res, size, "/"); 51 } 48 if (base_path[base_len - 1] != '/') 49 str_append(res, size, "/"); 52 50 str_append(res, size, name); 53 51 str_append(res, size, "/"); 54 52 str_append(res, size, name); 55 if (ext[0] != '.') {53 if (ext[0] != '.') 56 54 str_append(res, size, "."); 57 } 58 str_append(res, size, ext); 55 str_append(res, size, ext); 59 56 } 60 57 … … 62 59 } 63 60 64 char * 61 char *get_path_elem_end(char *path) 65 62 { 66 while (0 != *path && '/' != *path) {63 while (0 != *path && '/' != *path) 67 64 path++; 68 }69 65 return path; 70 66 } 67 68 /** @} 69 */ -
uspace/srv/devman/util.h
r032e0bb r38b3baf 30 30 * @{ 31 31 */ 32 32 33 33 #ifndef DEVMAN_UTIL_H_ 34 34 #define DEVMAN_UTIL_H_ … … 38 38 #include <malloc.h> 39 39 40 extern char *get_abs_path(const char *, const char *, const char *); 41 extern char *get_path_elem_end(char *); 40 42 41 char * get_abs_path(const char *base_path, const char *name, const char *ext); 42 char * get_path_elem_end(char *path); 43 44 static inline bool skip_spaces(char **buf) 43 static inline bool skip_spaces(char **buf) 45 44 { 46 while (isspace(**buf)) { 47 (*buf)++; 48 } 49 return *buf != 0; 45 while (isspace(**buf)) 46 (*buf)++; 47 return *buf != 0; 50 48 } 51 49 52 static inline size_t get_nonspace_len(const char *str) 50 static inline size_t get_nonspace_len(const char *str) 53 51 { 54 52 size_t len = 0; 53 55 54 while(*str != 0 && !isspace(*str)) { 56 55 len++; … … 62 61 static inline void free_not_null(const void *ptr) 63 62 { 64 if (NULL != ptr) {63 if (NULL != ptr) 65 64 free(ptr); 66 }67 65 } 68 66 69 static inline char * clone_string(const char *s)67 static inline char *clone_string(const char *s) 70 68 { 71 69 size_t size = str_size(s) + 1; 72 char *str = (char *)malloc(size); 73 if (NULL != str) { 70 char *str; 71 72 str = (char *) malloc(size); 73 if (NULL != str) 74 74 str_cpy(str, size, s); 75 }76 75 return str; 77 76 } … … 80 79 { 81 80 while (*str) { 82 if (orig == *str) {81 if (orig == *str) 83 82 *str = repl; 84 }85 83 str++; 86 84 } … … 88 86 89 87 #endif 88 89 /** @} 90 */
Note:
See TracChangeset
for help on using the changeset viewer.