Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b25970f in mainline


Ignore:
Timestamp:
2018-10-29T14:11:39Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
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.

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/isa/isa.c

    r184f2f8a rb25970f  
    11/*
     2 * Copyright (c) 2018 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    3  * Copyright (c) 2011 Jiri Svoboda
    44 * Copyright (c) 2011 Jan Vesely
    55 * All rights reserved.
     
    697697}
    698698
    699 static errno_t isa_dev_add(ddf_dev_t *dev)
    700 {
    701         async_sess_t *sess;
     699static errno_t isa_read_pci_cfg(isa_bus_t *isa, async_sess_t *sess)
     700{
    702701        errno_t rc;
    703 
    704         ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
    705             (int) ddf_dev_get_handle(dev));
    706 
    707         isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
    708         if (isa == NULL)
    709                 return ENOMEM;
    710 
    711         fibril_mutex_initialize(&isa->mutex);
    712         isa->dev = dev;
    713         list_initialize(&isa->functions);
    714 
    715         sess = ddf_dev_parent_sess_get(dev);
    716         if (sess == NULL) {
    717                 ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "
    718                     "parent driver.");
    719                 return ENOENT;
    720         }
    721702
    722703        rc = pci_config_space_read_16(sess, PCI_VENDOR_ID, &isa->pci_vendor_id);
     
    733714                return rc;
    734715
     716        return EOK;
     717}
     718
     719static errno_t isa_dev_add(ddf_dev_t *dev)
     720{
     721        async_sess_t *sess;
     722        errno_t rc;
     723
     724        ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
     725            (int) ddf_dev_get_handle(dev));
     726
     727        isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
     728        if (isa == NULL)
     729                return ENOMEM;
     730
     731        fibril_mutex_initialize(&isa->mutex);
     732        isa->dev = dev;
     733        list_initialize(&isa->functions);
     734
     735        sess = ddf_dev_parent_sess_get(dev);
     736        if (sess == NULL) {
     737                ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "
     738                    "parent driver.");
     739                return ENOENT;
     740        }
     741
     742        rc = isa_read_pci_cfg(isa, sess);
     743        if (rc != EOK) {
     744                ddf_msg(LVL_NOTE, "Cannot read PCI config. Assuming ISA classic.");
     745                isa->pci_vendor_id = 0;
     746                isa->pci_device_id = 0;
     747                isa->pci_class = BASE_CLASS_BRIDGE;
     748                isa->pci_subclass = SUB_CLASS_BRIDGE_ISA;
     749        }
     750
    735751        rc = pio_window_get(sess, &isa->pio_win);
    736752        if (rc != EOK) {
  • uspace/drv/bus/isa/isa.ma

    r184f2f8a rb25970f  
     1# Classic ISA
     210 isa
     3
    14# ISA bridge
    2510 pci/class=06&subclass=01
  • uspace/drv/platform/pc/pc.c

    r184f2f8a rb25970f  
    11/*
     2 * Copyright (c) 2018 Jiri Svoboda
    23 * Copyright (c) 2010 Lenka Trochtova
    34 * All rights reserved.
     
    9394};
    9495
    95 static pc_fun_t pci_data = {
     96static pc_fun_t sys_data = {
    9697        .hw_resources = {
    9798                sizeof(pci_conf_regs) / sizeof(pci_conf_regs[0]),
     
    151152static ddf_dev_ops_t pc_fun_ops;
    152153
    153 static bool
    154 pc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
    155     pc_fun_t *fun_proto)
    156 {
    157         ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
    158 
     154static errno_t pc_add_sysbus(ddf_dev_t *dev)
     155{
    159156        ddf_fun_t *fnode = NULL;
    160157        errno_t rc;
    161158
     159        ddf_msg(LVL_DEBUG, "Adding system bus.");
     160
    162161        /* Create new device. */
    163         fnode = ddf_fun_create(dev, fun_inner, name);
    164         if (fnode == NULL)
    165                 goto failure;
     162        fnode = ddf_fun_create(dev, fun_inner, "sys");
     163        if (fnode == NULL) {
     164                rc = ENOMEM;
     165                goto error;
     166        }
    166167
    167168        pc_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(pc_fun_t));
    168         *fun = *fun_proto;
    169 
    170         /* Add match ID */
    171         rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
     169        *fun = sys_data;
     170
     171        /* Add match IDs */
     172        rc = ddf_fun_add_match_id(fnode, "intel_pci", 100);
    172173        if (rc != EOK)
    173                 goto failure;
     174                goto error;
     175
     176        rc = ddf_fun_add_match_id(fnode, "isa", 10);
     177        if (rc != EOK)
     178                goto error;
    174179
    175180        /* Set provided operations to the device. */
     
    177182
    178183        /* Register function. */
    179         if (ddf_fun_bind(fnode) != EOK) {
    180                 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
    181                 goto failure;
    182         }
    183 
    184         return true;
    185 
    186 failure:
     184        rc = ddf_fun_bind(fnode);
     185        if (rc != EOK) {
     186                ddf_msg(LVL_ERROR, "Failed binding system bus function.");
     187                goto error;
     188        }
     189
     190        return EOK;
     191
     192error:
    187193        if (fnode != NULL)
    188194                ddf_fun_destroy(fnode);
    189195
    190         ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
    191 
    192         return false;
    193 }
    194 
    195 static bool pc_add_functions(ddf_dev_t *dev)
    196 {
    197         return pc_add_fun(dev, "pci0", "intel_pci", &pci_data);
     196        ddf_msg(LVL_ERROR, "Failed adding system bus.");
     197        return rc;
     198}
     199
     200static errno_t pc_add_functions(ddf_dev_t *dev)
     201{
     202        errno_t rc;
     203
     204        rc = pc_add_sysbus(dev);
     205        if (rc != EOK)
     206                return rc;
     207
     208        return EOK;
    198209}
    199210
     
    206217static errno_t pc_dev_add(ddf_dev_t *dev)
    207218{
     219        errno_t rc;
     220
    208221        ddf_msg(LVL_DEBUG, "pc_dev_add, device handle = %d",
    209222            (int)ddf_dev_get_handle(dev));
    210223
    211224        /* Register functions. */
    212         if (!pc_add_functions(dev)) {
     225        rc = pc_add_functions(dev);
     226        if (rc != EOK) {
    213227                ddf_msg(LVL_ERROR, "Failed to add functions for PC platform.");
     228                return rc;
    214229        }
    215230
  • 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.