Changeset b25970f in mainline for uspace/srv/devman/driver.c


Ignore:
Timestamp:
2018-10-29T14:11:39Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
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)
Message:

Fix ISA-only PC support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/driver.c

    r184f2f8a rb25970f  
    11/*
     2 * Copyright (c) 2018 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    34 * All rights reserved.
     
    4344#include "devman.h"
    4445#include "driver.h"
     46#include "fun.h"
    4547#include "match.h"
     48#include "main.h"
     49
     50static errno_t driver_reassign_fibril(void *);
    4651
    4752/**
     
    194199}
    195200
    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.
    198202 *
    199203 * A match between a device and a driver is found if one of the driver's match
     
    203207 * of the match between the device and the driver.
    204208 *
     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 *
    205214 * @param drivers_list  The list of drivers, where we look for the driver
    206215 *                      suitable for handling the device.
     
    213222        driver_t *best_drv = NULL;
    214223        int best_score = 0, score = 0;
     224        int cur_score;
     225        link_t *link;
     226        driver_t *drv;
    215227
    216228        fibril_mutex_lock(&drivers_list->drivers_mutex);
    217229
     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         */
    218258        list_foreach(drivers_list->drivers, drivers, driver_t, drv) {
    219259                score = get_match_score(drv, node);
    220                 if (score > best_score) {
     260                if (score > best_score && score < cur_score) {
    221261                        best_score = score;
    222262                        best_drv = drv;
     
    225265
    226266        fibril_mutex_unlock(&drivers_list->drivers_mutex);
    227 
    228267        return best_drv;
    229268}
     
    244283
    245284        dev->drv = drv;
     285        dev->passed_to_driver = false;
     286        dev->state = DEVICE_NOT_INITIALIZED;
    246287        list_append(&dev->driver_devices, &drv->devices);
    247288
     
    415456
    416457                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                }
    417471
    418472                dev_del_ref(dev);
     
    519573    dev_tree_t *tree)
    520574{
     575        driver_t *drv;
     576
    521577        assert(dev != NULL);
    522578        assert(drivers_list != NULL);
     
    524580
    525581        /*
    526          * Find the driver which is the most suitable for handling this device.
     582         * Find the next best driver for this device.
    527583         */
    528         driver_t *drv = find_best_match_driver(drivers_list, dev);
     584again:
     585        drv = find_best_match_driver(drivers_list, dev);
    529586        if (drv == NULL) {
    530587                log_msg(LOG_DEFAULT, LVL_ERROR, "No driver found for device `%s'.",
     
    545602
    546603        /* Notify the driver about the new device. */
    547         if (is_running)
     604        if (is_running) {
    548605                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        }
    549611
    550612        fibril_mutex_lock(&drv->driver_mutex);
     
    781843}
    782844
     845/** Try to find next available driver in a separate fibril.
     846 *
     847 * @param arg Device node (dev_node_t)
     848 */
     849static 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
    783859/** @}
    784860 */
Note: See TracChangeset for help on using the changeset viewer.