Changes in / [b38dfd8:4006447] in mainline


Ignore:
Files:
13 added
3 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    rb38dfd8 r4006447  
    545545% Line debugging information
    546546! [CONFIG_STRIP_BINARIES!=y] CONFIG_LINE_DEBUG (n/y)
     547
     548% Launch (devman) test drivers
     549! [CONFIG_DEBUG=y] CONFIG_TEST_DRIVERS (y/n)
     550
  • boot/Makefile.common

    rb38dfd8 r4006447  
    109109       
    110110RD_DRVS = \
    111         root
     111        root \
     112        rootvirt \
     113        test1 \
     114        test2
    112115
    113116RD_DRV_CFG =
  • boot/arch/amd64/Makefile.inc

    rb38dfd8 r4006447  
    3737
    3838RD_DRVS += \
    39         rootia32 \
     39        rootpc \
    4040        pciintel \
    4141        isa \
  • uspace/Makefile

    rb38dfd8 r4006447  
    8585        srv/net/tl/tcp \
    8686        srv/net/net \
    87         drv/root
     87        drv/root \
     88        drv/rootvirt \
     89        drv/test1 \
     90        drv/test2
    8891
    8992## Networking
     
    108111
    109112ifeq ($(UARCH),amd64)
     113        DIRS += drv/rootpc
     114        DIRS += drv/pciintel
     115        DIRS += drv/isa
     116        DIRS += drv/ns8250
    110117endif
    111118
    112119ifeq ($(UARCH),ia32)
    113         DIRS += drv/rootia32
     120        DIRS += drv/rootpc
    114121        DIRS += drv/pciintel
    115122        DIRS += drv/isa
  • uspace/drv/isa/isa.c

    rb38dfd8 r4006447  
    282282
    283283                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284                     "device %s\n", addr, len, dev->name);
     284                    "device %s\n", (unsigned int) addr, (unsigned int) len,
     285                    dev->name);
    285286        }
    286287}
     
    489490static int isa_add_device(device_t *dev)
    490491{
    491         printf(NAME ": isa_add_device, device handle = %d\n", dev->handle);
     492        printf(NAME ": isa_add_device, device handle = %d\n",
     493            (int) dev->handle);
    492494
    493495        /* Add child devices. */
  • uspace/drv/ns8250/ns8250.c

    rb38dfd8 r4006447  
    274274       
    275275        /* Gain control over port's registers. */
    276         if (pio_enable((void *) data->io_addr, REG_COUNT,
     276        if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,
    277277            (void **) &data->port)) {
    278278                printf(NAME ": error - cannot gain the port %#" PRIx32 " for device "
     
    727727{
    728728        printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    729             dev->name, dev->handle);
     729            dev->name, (int) dev->handle);
    730730       
    731731        int res = ns8250_dev_initialize(dev);
  • uspace/drv/pciintel/pci.c

    rb38dfd8 r4006447  
    324324                printf(NAME ": device %s : ", dev->name);
    325325                printf("address = %" PRIx64, range_addr);
    326                 printf(", size = %x\n", range_size);
     326                printf(", size = %x\n", (unsigned int) range_size);
    327327        }
    328328       
     
    489489            (uint32_t) hw_resources.resources[0].res.io_range.address;
    490490       
    491         if (pio_enable((void *)bus_data->conf_io_addr, 8,
     491        if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    492492            &bus_data->conf_addr_port)) {
    493493                printf(NAME ": failed to enable configuration ports.\n");
  • uspace/drv/root/root.c

    rb38dfd8 r4006447  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2010 Vojtech Horky
    34 * All rights reserved.
    45 *
     
    5354#define NAME "root"
    5455
     56#define PLATFORM_DEVICE_NAME "hw"
     57#define PLATFORM_DEVICE_MATCH_ID STRING(UARCH)
     58#define PLATFORM_DEVICE_MATCH_SCORE 100
     59
     60#define VIRTUAL_DEVICE_NAME "virt"
     61#define VIRTUAL_DEVICE_MATCH_ID "rootvirt"
     62#define VIRTUAL_DEVICE_MATCH_SCORE 100
     63
    5564static int root_add_device(device_t *dev);
    5665
     
    6675};
    6776
     77/** Create the device which represents the root of virtual device tree.
     78 *
     79 * @param parent Parent of the newly created device.
     80 * @return Error code.
     81 */
     82static int add_virtual_root_child(device_t *parent)
     83{
     84        printf(NAME ": adding new child for virtual devices.\n");
     85        printf(NAME ":   device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME,
     86            VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID);
     87
     88        int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME,
     89            VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE);
     90
     91        return res;
     92}
     93
    6894/** Create the device which represents the root of HW device tree.
    6995 *
     
    74100{
    75101        printf(NAME ": adding new child for platform device.\n");
     102        printf(NAME ":   device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME,
     103            PLATFORM_DEVICE_MATCH_SCORE, PLATFORM_DEVICE_MATCH_ID);
    76104       
    77         int res = EOK;
    78         device_t *platform = NULL;
    79         match_id_t *match_id = NULL;
    80        
    81         /* Create new device. */
    82         platform = create_device();
    83         if (NULL == platform) {
    84                 res = ENOMEM;
    85                 goto failure;
    86         }       
    87        
    88         platform->name = "hw";
    89         printf(NAME ": the new device's name is %s.\n", platform->name);
    90        
    91         /* Initialize match id list. */
    92         match_id = create_match_id();
    93         if (NULL == match_id) {
    94                 res = ENOMEM;
    95                 goto failure;
    96         }
    97        
    98         /* TODO - replace this with some better solution (sysinfo ?) */
    99         match_id->id = STRING(UARCH);
    100         match_id->score = 100;
    101         add_match_id(&platform->match_ids, match_id);
    102        
    103         /* Register child device. */
    104         res = child_device_register(platform, parent);
    105         if (EOK != res)
    106                 goto failure;
    107        
    108         return res;
    109        
    110 failure:
    111         if (NULL != match_id)
    112                 match_id->id = NULL;
    113        
    114         if (NULL != platform) {
    115                 platform->name = NULL;
    116                 delete_device(platform);
    117         }
    118        
     105        int res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME,
     106            PLATFORM_DEVICE_MATCH_ID, PLATFORM_DEVICE_MATCH_SCORE);
     107
    119108        return res;
    120109}
     
    130119            dev->handle);
    131120       
     121        /*
     122         * Register virtual devices root.
     123         * We ignore error occurrence because virtual devices shall not be
     124         * vital for the system.
     125         */
     126        add_virtual_root_child(dev);
     127
    132128        /* Register root device's children. */
    133129        int res = add_platform_child(dev);
  • uspace/lib/c/generic/devman.c

    rb38dfd8 r4006447  
    116116{
    117117        ipc_call_t answer;
    118         async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
     118        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    119119        int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
    120         return retval; 
     120        async_wait_for(req, NULL);
     121        return retval;
    121122}
    122123
  • uspace/lib/drv/generic/driver.c

    rb38dfd8 r4006447  
    165165       
    166166        devman_handle_t dev_handle =  IPC_GET_ARG1(*icall);
     167        devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
     168   
    167169        device_t *dev = create_device();
    168170        dev->handle = dev_handle;
     
    172174       
    173175        add_to_devices_list(dev);
     176        dev->parent = driver_get_device(&devices, parent_dev_handle);
     177       
    174178        res = driver->driver_ops->add_device(dev);
    175179        if (0 == res) {
     
    377381}
    378382
     383/** Wrapper for child_device_register for devices with single match id.
     384 *
     385 * @param parent Parent device.
     386 * @param child_name Child device name.
     387 * @param child_match_id Child device match id.
     388 * @param child_match_score Child device match score.
     389 * @return Error code.
     390 */
     391int child_device_register_wrapper(device_t *parent, const char *child_name,
     392    const char *child_match_id, int child_match_score)
     393{
     394        device_t *child = NULL;
     395        match_id_t *match_id = NULL;
     396        int rc;
     397
     398        child = create_device();
     399        if (child == NULL) {
     400                rc = ENOMEM;
     401                goto failure;
     402        }
     403
     404        child->name = child_name;
     405
     406        match_id = create_match_id();
     407        if (match_id == NULL) {
     408                rc = ENOMEM;
     409                goto failure;
     410        }
     411
     412        match_id->id = child_match_id;
     413        match_id->score = child_match_score;
     414        add_match_id(&child->match_ids, match_id);
     415
     416        rc = child_device_register(child, parent);
     417        if (EOK != rc)
     418                goto failure;
     419
     420        return EOK;
     421
     422failure:
     423        if (match_id != NULL) {
     424                match_id->id = NULL;
     425                delete_match_id(match_id);
     426        }
     427
     428        if (child != NULL) {
     429                child->name = NULL;
     430                delete_device(child);
     431        }
     432
     433        return rc;
     434}
     435
    379436int driver_main(driver_t *drv)
    380437{
  • uspace/lib/drv/include/driver.h

    rb38dfd8 r4006447  
    199199
    200200int child_device_register(device_t *, device_t *);
     201int child_device_register_wrapper(device_t *, const char *, const char *, int);
    201202
    202203
  • uspace/srv/devman/devman.c

    rb38dfd8 r4006447  
    508508/** Notify driver about the devices to which it was assigned.
    509509 *
    510  * The driver's mutex must be locked.
    511  *
    512510 * @param driver        The driver to which the devices are passed.
    513511 */
     
    518516        int phone;
    519517
    520         printf(NAME ": pass_devices_to_driver\n");
    521 
    522         phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
    523         if (phone > 0) {
    524                
     518        printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name);
     519
     520        fibril_mutex_lock(&driver->driver_mutex);
     521
     522        phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
     523
     524        if (phone < 0) {
     525                fibril_mutex_unlock(&driver->driver_mutex);
     526                return;
     527        }
     528
     529        /*
     530         * Go through devices list as long as there is some device
     531         * that has not been passed to the driver.
     532         */
     533        link = driver->devices.next;
     534        while (link != &driver->devices) {
     535                dev = list_get_instance(link, node_t, driver_devices);
     536                if (dev->passed_to_driver) {
     537                        link = link->next;
     538                        continue;
     539                }
     540
     541                /*
     542                 * We remove the device from the list to allow safe adding
     543                 * of new devices (no one will touch our item this way).
     544                 */
     545                list_remove(link);
     546
     547                /*
     548                 * Unlock to avoid deadlock when adding device
     549                 * handled by itself.
     550                 */
     551                fibril_mutex_unlock(&driver->driver_mutex);
     552
     553                add_device(phone, driver, dev, tree);
     554
     555                /*
     556                 * Lock again as we will work with driver's
     557                 * structure.
     558                 */
     559                fibril_mutex_lock(&driver->driver_mutex);
     560
     561                /*
     562                 * Insert the device back.
     563                 * The order is not relevant here so no harm is done
     564                 * (actually, the order would be preserved in most cases).
     565                 */
     566                list_append(link, &driver->devices);
     567
     568                /*
     569                 * Restart the cycle to go through all devices again.
     570                 */
    525571                link = driver->devices.next;
    526                 while (link != &driver->devices) {
    527                         dev = list_get_instance(link, node_t, driver_devices);
    528                         add_device(phone, driver, dev, tree);
    529                         link = link->next;
    530                 }
    531                
    532                 ipc_hangup(phone);
    533         }
     572        }
     573
     574        ipc_hangup(phone);
     575
     576        /*
     577         * Once we passed all devices to the driver, we need to mark the
     578         * driver as running.
     579         * It is vital to do it here and inside critical section.
     580         *
     581         * If we would change the state earlier, other devices added to
     582         * the driver would be added to the device list and started
     583         * immediately and possibly started here as well.
     584         */
     585        printf(NAME ": driver %s goes into running state.\n", driver->name);
     586        driver->state = DRIVER_RUNNING;
     587
     588        fibril_mutex_unlock(&driver->driver_mutex);
    534589}
    535590
     
    545600void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
    546601{
    547         printf(NAME ": initialize_running_driver\n");
    548         fibril_mutex_lock(&driver->driver_mutex);
     602        printf(NAME ": initialize_running_driver (`%s')\n", driver->name);
    549603       
    550604        /*
     
    553607         */
    554608        pass_devices_to_driver(driver, tree);
    555        
    556         /* Change driver's state to running. */
    557         driver->state = DRIVER_RUNNING;
    558        
    559         fibril_mutex_unlock(&driver->driver_mutex);
    560609}
    561610
     
    629678}
    630679
     680static FIBRIL_MUTEX_INITIALIZE(add_device_guard);
    631681
    632682/** Pass a device to running driver.
     
    637687void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
    638688{
    639         printf(NAME ": add_device\n");
     689        fibril_mutex_lock(&add_device_guard);
     690
     691        /*
     692         * We do not expect to have driver's mutex locked as we do not
     693         * access any structures that would affect driver_t.
     694         */
     695        printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
     696            node->name);
    640697       
    641698        ipcarg_t rc;
     
    643700       
    644701        /* Send the device to the driver. */
    645         aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle,
    646             &answer);
     702        devman_handle_t parent_handle;
     703        if (node->parent) {
     704                parent_handle = node->parent->handle;
     705        } else {
     706                parent_handle = 0;
     707        }
     708
     709        aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
     710            parent_handle, &answer);
    647711       
    648712        /* Send the device's name to the driver. */
     
    652716                /* TODO handle error */
    653717        }
    654        
     718
    655719        /* Wait for answer from the driver. */
    656720        async_wait_for(req, &rc);
     721
     722        fibril_mutex_unlock(&add_device_guard);
     723
    657724        switch(rc) {
    658725        case EOK:
     
    667734        }
    668735       
     736        node->passed_to_driver = true;
     737
    669738        return;
    670739}
     
    692761        attach_driver(node, drv);
    693762       
     763        fibril_mutex_lock(&drv->driver_mutex);
    694764        if (drv->state == DRIVER_NOT_STARTED) {
    695765                /* Start the driver. */
    696766                start_driver(drv);
    697767        }
    698        
    699         if (drv->state == DRIVER_RUNNING) {
     768        bool is_running = drv->state == DRIVER_RUNNING;
     769        fibril_mutex_unlock(&drv->driver_mutex);
     770
     771        if (is_running) {
    700772                /* Notify the driver about the new device. */
    701                 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     773                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
    702774                if (phone > 0) {
    703775                        add_device(phone, drv, node, tree);
     
    861933        node->name = dev_name;
    862934        if (!set_dev_path(node, parent)) {
    863                 fibril_rwlock_write_unlock(&tree->rwlock);
    864935                return false;
    865936        }
     
    10831154        while (link != &class_list->classes) {
    10841155                cl = list_get_instance(link, dev_class_t, link);
    1085                 if (str_cmp(cl->name, class_name) == 0)
     1156                if (str_cmp(cl->name, class_name) == 0) {
    10861157                        return cl;
     1158                }
     1159                link = link->next;
    10871160        }
    10881161       
  • uspace/srv/devman/devman.h

    rb38dfd8 r4006447  
    168168         */
    169169        link_t devmap_link;
     170
     171        /**
     172         * Whether this device was already passed to the driver.
     173         */
     174        bool passed_to_driver;
    170175};
    171176
  • uspace/srv/devman/main.c

    rb38dfd8 r4006447  
    197197}
    198198
     199static int assign_driver_fibril(void *arg)
     200{
     201        node_t *node = (node_t *) arg;
     202        assign_driver(node, &drivers_list, &device_tree);
     203        return EOK;
     204}
     205
    199206/** Handle child device registration.
    200207 *
     
    237244       
    238245        devman_receive_match_ids(match_count, &node->match_ids);
    239        
     246
     247        /*
     248         * Try to find a suitable driver and assign it to the device.  We do
     249         * not want to block the current fibril that is used for processing
     250         * incoming calls: we will launch a separate fibril to handle the
     251         * driver assigning. That is because assign_driver can actually include
     252         * task spawning which could take some time.
     253         */
     254        fid_t assign_fibril = fibril_create(assign_driver_fibril, node);
     255        if (assign_fibril == 0) {
     256                /*
     257                 * Fallback in case we are out of memory.
     258                 * Probably not needed as we will die soon anyway ;-).
     259                 */
     260                (void) assign_driver_fibril(node);
     261        } else {
     262                fibril_add_ready(assign_fibril);
     263        }
     264
    240265        /* Return device handle to parent's driver. */
    241266        ipc_answer_1(callid, EOK, node->handle);
    242        
    243         /* Try to find suitable driver and assign it to the device. */
    244         assign_driver(node, &drivers_list, &device_tree);
    245267}
    246268
     
    297319        printf(NAME ": device '%s' added to class '%s', class name '%s' was "
    298320            "asigned to it\n", dev->pathname, class_name, class_info->dev_name);
    299        
     321
    300322        ipc_answer_0(callid, EOK);
    301323}
  • uspace/srv/devman/match.c

    rb38dfd8 r4006447  
    3535#include "devman.h"
    3636
     37/** Compute compound score of driver and device.
     38 *
     39 * @param driver Match id of the driver.
     40 * @param device Match id of the device.
     41 * @return Compound score.
     42 * @retval 0 No match at all.
     43 */
     44static int compute_match_score(match_id_t *driver, match_id_t *device)
     45{
     46        if (str_cmp(driver->id, device->id) == 0) {
     47                /*
     48                 * The strings match, return the product of their scores.
     49                 */
     50                return driver->score * device->score;
     51        } else {
     52                /*
     53                 * Different strings, return zero.
     54                 */
     55                return 0;
     56        }
     57}
     58
    3759int get_match_score(driver_t *drv, node_t *dev)
    3860{
     
    4365                return 0;
    4466       
     67        /*
     68         * Go through all pairs, return the highest score obtained.
     69         */
     70        int highest_score = 0;
     71       
    4572        link_t *drv_link = drv->match_ids.ids.next;
    46         link_t *dev_link = dev->match_ids.ids.next;
    47        
    48         match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
    49         match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
    50        
    51         int score_next_drv = 0;
    52         int score_next_dev = 0;
    53        
    54         do {
    55                 match_id_t *tmp_ma_id;
    56        
    57                 if (str_cmp(drv_id->id, dev_id->id) == 0) {
    58                         /*
    59                          * We found a match.
    60                          * Return the score of the match.
    61                          */
    62                         return drv_id->score * dev_id->score;
     73        while (drv_link != drv_head) {
     74                link_t *dev_link = dev_head->next;
     75                while (dev_link != dev_head) {
     76                        match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
     77                        match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
     78                       
     79                        int score = compute_match_score(drv_id, dev_id);
     80                        if (score > highest_score) {
     81                                highest_score = score;
     82                        }
     83
     84                        dev_link = dev_link->next;
    6385                }
    6486               
    65                 /*
    66                  * Compute the next score we get, if we advance in the driver's
    67                  * list of match ids.
    68                  */
    69                 if (drv_link->next != drv_head) {
    70                         tmp_ma_id = list_get_instance(drv_link->next,
    71                             match_id_t, link);
    72                         score_next_drv = dev_id->score * tmp_ma_id->score;
    73                 } else {
    74                         score_next_drv = 0;
    75                 }
    76                
    77                 /*
    78                  * Compute the next score we get, if we advance in the device's
    79                  * list of match ids.
    80                  */
    81                 if (dev_link->next != dev_head) {
    82                         tmp_ma_id = list_get_instance(dev_link->next,
    83                             match_id_t, link);
    84                         score_next_dev = drv_id->score * tmp_ma_id->score;
    85                 } else {
    86                         score_next_dev = 0;
    87                 }
    88                
    89                 /*
    90                  * Advance in one of the two lists, so we get the next highest
    91                  * score.
    92                  */
    93                 if (score_next_drv > score_next_dev) {
    94                         drv_link = drv_link->next;
    95                         drv_id = list_get_instance(drv_link, match_id_t, link);
    96                 } else {
    97                         dev_link = dev_link->next;
    98                         dev_id = list_get_instance(dev_link, match_id_t, link);
    99                 }
    100                
    101         } while (drv_link->next != drv_head && dev_link->next != dev_head);
     87                drv_link = drv_link->next;
     88        }
    10289       
    103         return 0;
     90        return highest_score;
    10491}
    10592
Note: See TracChangeset for help on using the changeset viewer.