Changeset b25970f in mainline for uspace/srv/devman/driver.c
- Timestamp:
- 2018-10-29T14:11:39Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 94ab1fe
- Parents:
- 184f2f8a
- git-author:
- Jiri Svoboda <jiri@…> (2018-10-28 22:10:25)
- git-committer:
- Jiri Svoboda <jiri@…> (2018-10-29 14:11:39)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/driver.c
r184f2f8a rb25970f 1 1 /* 2 * Copyright (c) 2018 Jiri Svoboda 2 3 * Copyright (c) 2010 Lenka Trochtova 3 4 * All rights reserved. … … 43 44 #include "devman.h" 44 45 #include "driver.h" 46 #include "fun.h" 45 47 #include "match.h" 48 #include "main.h" 49 50 static errno_t driver_reassign_fibril(void *); 46 51 47 52 /** … … 194 199 } 195 200 196 /** Lookup the best matching driver for the specified device in the list of 197 * drivers. 201 /** Lookup the next best matching driver for a device. 198 202 * 199 203 * A match between a device and a driver is found if one of the driver's match … … 203 207 * of the match between the device and the driver. 204 208 * 209 * If a driver is already assigned to the device (node->drv != NULL), 210 * we look for the next best driver. That is either the next driver with the 211 * same score in the list of drivers, or a driver with the next best score 212 * (greater than zero). 213 * 205 214 * @param drivers_list The list of drivers, where we look for the driver 206 215 * suitable for handling the device. … … 213 222 driver_t *best_drv = NULL; 214 223 int best_score = 0, score = 0; 224 int cur_score; 225 link_t *link; 226 driver_t *drv; 215 227 216 228 fibril_mutex_lock(&drivers_list->drivers_mutex); 217 229 230 if (node->drv != NULL) { 231 cur_score = get_match_score(node->drv, node); 232 233 link = list_next(&drv->drivers, &drivers_list->drivers); 234 235 /* 236 * Find next driver with score equal to the current. 237 */ 238 while (link != NULL) { 239 drv = list_get_instance(link, driver_t, drivers); 240 score = get_match_score(drv, node); 241 if (score == cur_score) { 242 /* Found it */ 243 fibril_mutex_unlock(&drivers_list->drivers_mutex); 244 return drv; 245 } 246 247 link = list_next(link, &drivers_list->drivers); 248 } 249 250 /* There is no driver with the same score */ 251 } else { 252 cur_score = INT_MAX; 253 } 254 255 /* 256 * Find driver with the next best score 257 */ 218 258 list_foreach(drivers_list->drivers, drivers, driver_t, drv) { 219 259 score = get_match_score(drv, node); 220 if (score > best_score ) {260 if (score > best_score && score < cur_score) { 221 261 best_score = score; 222 262 best_drv = drv; … … 225 265 226 266 fibril_mutex_unlock(&drivers_list->drivers_mutex); 227 228 267 return best_drv; 229 268 } … … 244 283 245 284 dev->drv = drv; 285 dev->passed_to_driver = false; 286 dev->state = DEVICE_NOT_INITIALIZED; 246 287 list_append(&dev->driver_devices, &drv->devices); 247 288 … … 415 456 416 457 add_device(driver, dev, tree); 458 459 /* Device probe failed, need to try next best driver */ 460 if (dev->state == DEVICE_NOT_PRESENT) { 461 fibril_mutex_lock(&driver->driver_mutex); 462 list_remove(&dev->driver_devices); 463 fibril_mutex_unlock(&driver->driver_mutex); 464 fid_t fid = fibril_create(driver_reassign_fibril, dev); 465 if (fid == 0) { 466 log_msg(LOG_DEFAULT, LVL_ERROR, 467 "Error creating fibril to assign driver."); 468 } 469 fibril_add_ready(fid); 470 } 417 471 418 472 dev_del_ref(dev); … … 519 573 dev_tree_t *tree) 520 574 { 575 driver_t *drv; 576 521 577 assert(dev != NULL); 522 578 assert(drivers_list != NULL); … … 524 580 525 581 /* 526 * Find the driver which is the most suitable for handlingthis device.582 * Find the next best driver for this device. 527 583 */ 528 driver_t *drv = find_best_match_driver(drivers_list, dev); 584 again: 585 drv = find_best_match_driver(drivers_list, dev); 529 586 if (drv == NULL) { 530 587 log_msg(LOG_DEFAULT, LVL_ERROR, "No driver found for device `%s'.", … … 545 602 546 603 /* Notify the driver about the new device. */ 547 if (is_running) 604 if (is_running) { 548 605 add_device(drv, dev, tree); 606 607 /* If the device probe failed, need to try next available driver */ 608 if (dev->state == DEVICE_NOT_PRESENT) 609 goto again; 610 } 549 611 550 612 fibril_mutex_lock(&drv->driver_mutex); … … 781 843 } 782 844 845 /** Try to find next available driver in a separate fibril. 846 * 847 * @param arg Device node (dev_node_t) 848 */ 849 static errno_t driver_reassign_fibril(void *arg) 850 { 851 dev_node_t *dev_node = (dev_node_t *) arg; 852 assign_driver(dev_node, &drivers_list, &device_tree); 853 854 /* Delete one reference we got from the caller. */ 855 dev_del_ref(dev_node); 856 return EOK; 857 } 858 783 859 /** @} 784 860 */
Note:
See TracChangeset
for help on using the changeset viewer.