Changeset fe2333d in mainline


Ignore:
Timestamp:
2010-12-09T00:08:57Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0a5a950
Parents:
07b9203e (diff), c01f8e6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Files:
11 added
1 deleted
30 edited
2 moved

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r07b9203e rfe2333d  
    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
  • Makefile

    r07b9203e rfe2333d  
    4141CONFIG_HEADER = config.h
    4242
    43 .PHONY: all precheck cscope autotool config_default config distclean clean
     43.PHONY: all precheck cscope autotool config_auto config_default config distclean clean
    4444
    4545all: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER)
     
    6666
    6767config_default: $(CONFIG_RULES)
    68         $(CONFIG) $< default
     68ifeq ($(HANDS_OFF),y)
     69        $(CONFIG) $< hands-off $(PROFILE)
     70else
     71        $(CONFIG) $< default $(PROFILE)
     72endif
    6973
    7074config: $(CONFIG_RULES)
  • boot/Makefile.common

    r07b9203e rfe2333d  
    111111RD_DRVS = \
    112112        root \
     113        rootvirt \
     114        test1 \
     115        test2 \
    113116        vhc
    114117
  • boot/arch/amd64/Makefile.inc

    r07b9203e rfe2333d  
    3737
    3838RD_DRVS += \
    39         rootia32 \
     39        rootpc \
    4040        pciintel \
    4141        isa \
  • tools/config.py

    r07b9203e rfe2333d  
    4747
    4848def read_config(fname, config):
    49         "Read saved values from last configuration run"
     49        "Read saved values from last configuration run or a preset file"
    5050       
    5151        inf = open(fname, 'r')
     
    218218# and verify that all variables have a value (previously specified or inferred).
    219219#
    220 # @param config Configuration to work on
    221 # @param rules  Rules
    222 #
    223 # @return       True if configuration is complete and valid, False
    224 #               otherwise.
     220# @param config Configuration to work on
     221# @param rules  Rules
     222#
     223# @return True if configuration is complete and valid, False
     224#         otherwise.
    225225#
    226226def infer_verify_choices(config, rules):
     
    229229        for rule in rules:
    230230                varname, vartype, name, choices, cond = rule
    231 
     231               
    232232                if cond and (not check_condition(cond, config, rules)):
    233233                        continue
     
    237237                else:
    238238                        value = config[varname]
    239 
    240                 if not rule_value_is_valid(rule, value):
     239               
     240                if not validate_rule_value(rule, value):
    241241                        value = None
    242 
    243                 default = rule_get_default(rule)
    244                 if default != None:
     242               
     243                default = get_default_rule(rule)
     244
     245                #
     246                # If we don't have a value but we do have
     247                # a default, use it.
     248                #
     249                if value == None and default != None:
     250                        value = default
    245251                        config[varname] = default
    246 
     252               
    247253                if not varname in config:
    248254                        return False
     
    251257
    252258## Get default value from a rule.
    253 def rule_get_default(rule):
     259def get_default_rule(rule):
    254260        varname, vartype, name, choices, cond = rule
    255 
     261       
    256262        default = None
    257 
     263       
    258264        if vartype == 'choice':
    259265                # If there is just one option, use it
     
    270276        else:
    271277                raise RuntimeError("Unknown variable type: %s" % vartype)
    272 
     278       
    273279        return default
    274280
    275281## Get option from a rule.
    276282#
    277 # @param rule   Rule for a variable
    278 # @param value  Current value of the variable
     283# @param rule  Rule for a variable
     284# @param value Current value of the variable
    279285#
    280286# @return Option (string) to ask or None which means not to ask.
    281287#
    282 def rule_get_option(rule, value):
     288def get_rule_option(rule, value):
    283289        varname, vartype, name, choices, cond = rule
    284 
     290       
    285291        option = None
    286 
     292       
    287293        if vartype == 'choice':
    288294                # If there is just one option, don't ask
     
    302308        else:
    303309                raise RuntimeError("Unknown variable type: %s" % vartype)
    304 
     310       
    305311        return option
    306312
    307313## Check if variable value is valid.
    308314#
    309 # @param rule   Rule for the variable
    310 # @param value  Value of the variable
    311 #
    312 # @return       True if valid, False if not valid.
    313 #
    314 def rule_value_is_valid(rule, value):
     315# @param rule  Rule for the variable
     316# @param value Value of the variable
     317#
     318# @return True if valid, False if not valid.
     319#
     320def validate_rule_value(rule, value):
    315321        varname, vartype, name, choices, cond = rule
    316322       
    317323        if value == None:
    318324                return True
    319 
     325       
    320326        if vartype == 'choice':
    321327                if not value in [choice[0] for choice in choices]:
     
    335341        else:
    336342                raise RuntimeError("Unknown variable type: %s" % vartype)
    337 
     343       
    338344        return True
    339345
     
    413419        return list
    414420
    415 ## Choose a profile and load configuration presets.
    416 #
    417 def load_presets(root, fname, screen, config):
     421## Ask user to choose a configuration profile.
     422#
     423def choose_profile(root, fname, screen, config):
    418424        options = []
    419425        opt2path = {}
     
    436442                                        subprofile = True
    437443                                        options.append("%s (%s)" % (name, subname))
    438                                         opt2path[cnt] = (canon, subcanon)
     444                                        opt2path[cnt] = [name, subname]
    439445                                        cnt += 1
    440446                       
    441447                        if not subprofile:
    442448                                options.append(name)
    443                                 opt2path[cnt] = (canon, None)
     449                                opt2path[cnt] = [name]
    444450                                cnt += 1
    445451       
     
    449455                return None
    450456       
    451         read_config(opt2path[value][0], config)
    452         if opt2path[value][1] != None:
    453                 read_config(opt2path[value][1], config)
     457        return opt2path[value]
     458
     459## Read presets from a configuration profile.
     460#
     461# @param profile Profile to load from (a list of string components)
     462# @param config  Output configuration
     463#
     464def read_presets(profile, config):
     465        path = os.path.join(PRESETS_DIR, profile[0], MAKEFILE)
     466        read_config(path, config)
     467       
     468        if len(profile) > 1:
     469                path = os.path.join(PRESETS_DIR, profile[0], profile[1], MAKEFILE)
     470                read_config(path, config)
     471
     472## Parse profile name (relative OS path) into a list of components.
     473#
     474# @param profile_name Relative path (using OS separator)
     475# @return             List of components
     476#
     477def parse_profile_name(profile_name):
     478        profile = []
     479       
     480        head, tail = os.path.split(profile_name)
     481        if head != '':
     482                profile.append(head)
     483       
     484        profile.append(tail)
     485        return profile
    454486
    455487def main():
     488        profile = None
    456489        config = {}
    457490        rules = []
     
    460493        parse_rules(RULES_FILE, rules)
    461494       
    462         # Read configuration from previous run
    463         if os.path.exists(MAKEFILE):
     495        # Input configuration file can be specified on command line
     496        # otherwise configuration from previous run is used.
     497        if len(sys.argv) >= 4:
     498                profile = parse_profile_name(sys.argv[3])
     499                read_presets(profile, config)
     500        elif os.path.exists(MAKEFILE):
    464501                read_config(MAKEFILE, config)
    465502       
    466         # Default mode: only check values and regenerate configuration files
     503        # Default mode: check values and regenerate configuration files
    467504        if (len(sys.argv) >= 3) and (sys.argv[2] == 'default'):
    468505                if (infer_verify_choices(config, rules)):
    469506                        create_output(MAKEFILE, MACROS, config, rules)
    470507                        return 0
     508       
     509        # Hands-off mode: check values and regenerate configuration files,
     510        # but no interactive fallback
     511        if (len(sys.argv) >= 3) and (sys.argv[2] == 'hands-off'):
     512                # We deliberately test sys.argv >= 4 because we do not want
     513                # to read implicitly any possible previous run configuration
     514                if len(sys.argv) < 4:
     515                        sys.stderr.write("Configuration error: No presets specified\n")
     516                        return 2
     517               
     518                if (infer_verify_choices(config, rules)):
     519                        create_output(MAKEFILE, MACROS, config, rules)
     520                        return 0
     521               
     522                sys.stderr.write("Configuration error: The presets are ambiguous\n")
     523                return 1
    471524       
    472525        # Check mode: only check configuration
     
    507560                                        value = config[varname]
    508561                               
    509                                 if not rule_value_is_valid(rule, value):
     562                                if not validate_rule_value(rule, value):
    510563                                        value = None
    511 
    512                                 default = rule_get_default(rule)
    513                                 if default != None:
     564                               
     565                                default = get_default_rule(rule)
     566
     567                                #
     568                                # If we don't have a value but we do have
     569                                # a default, use it.
     570                                #
     571                                if value == None and default != None:
    514572                                        value = default
    515573                                        config[varname] = default
    516 
    517                                 option = rule_get_option(rule, value)
     574                               
     575                                option = get_rule_option(rule, value)
    518576                                if option != None:
    519577                                        options.append(option)
     578                                else:
     579                                        continue
    520580                               
    521581                                opt2row[cnt] = (varname, vartype, name, choices)
     
    539599                       
    540600                        if value == 0:
    541                                 load_presets(PRESETS_DIR, MAKEFILE, screen, config)
     601                                profile = choose_profile(PRESETS_DIR, MAKEFILE, screen, config)
     602                                if profile != None:
     603                                        read_presets(profile, config)
    542604                                position = 1
    543605                                continue
  • uspace/Makefile

    r07b9203e rfe2333d  
    8888        srv/net/net \
    8989        drv/root \
     90        drv/rootvirt \
     91        drv/test1 \
     92        drv/test2 \
    9093        drv/vhc
    9194
     
    111114
    112115ifeq ($(UARCH),amd64)
     116        DIRS += drv/rootpc
     117        DIRS += drv/pciintel
     118        DIRS += drv/isa
     119        DIRS += drv/ns8250
    113120endif
    114121
    115122ifeq ($(UARCH),ia32)
    116         DIRS += drv/rootia32
     123        DIRS += drv/rootpc
    117124        DIRS += drv/pciintel
    118125        DIRS += drv/isa
  • uspace/app/netecho/print_error.c

    r07b9203e rfe2333d  
    164164        case EDESTADDRREQ:
    165165                fprintf(output, "Destination address required (%d) error", error_code);
    166         case TRY_AGAIN:
     166        case EAGAIN:
    167167                fprintf(output, "Try again (%d) error", error_code);
    168168        default:
  • uspace/drv/isa/isa.c

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    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}
     
    184173            dev->handle);
    185174       
     175        /*
     176         * Register virtual devices root.
     177         * We ignore error occurrence because virtual devices shall not be
     178         * vital for the system.
     179         */
     180        add_virtual_root_child(dev);
     181
    186182        /* Register root device's children. */
    187183        int res = add_platform_child(dev);
  • uspace/drv/rootpc/Makefile

    r07b9203e rfe2333d  
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
    32 BINARY = rootia32
     32BINARY = rootpc
    3333
    3434SOURCES = \
    35         rootia32.c
     35        rootpc.c
    3636
    3737include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/rootpc/rootpc.c

    r07b9203e rfe2333d  
    2828
    2929/**
    30  * @defgroup root_ia32 Root HW device driver for ia32 platform.
    31  * @brief HelenOS root HW device driver for ia32 platform.
     30 * @defgroup root_pc Root HW device driver for ia32 and amd64 platform.
     31 * @brief HelenOS root HW device driver for ia32 and amd64 platform.
    3232 * @{
    3333 */
     
    5353#include <device/hw_res.h>
    5454
    55 #define NAME "rootia32"
    56 
    57 typedef struct rootia32_child_dev_data {
     55#define NAME "rootpc"
     56
     57typedef struct rootpc_child_dev_data {
    5858        hw_resource_list_t hw_resources;
    59 } rootia32_child_dev_data_t;
    60 
    61 static int rootia32_add_device(device_t *dev);
    62 static void root_ia32_init(void);
     59} rootpc_child_dev_data_t;
     60
     61static int rootpc_add_device(device_t *dev);
     62static void root_pc_init(void);
    6363
    6464/** The root device driver's standard operations. */
    65 static driver_ops_t rootia32_ops = {
    66         .add_device = &rootia32_add_device
     65static driver_ops_t rootpc_ops = {
     66        .add_device = &rootpc_add_device
    6767};
    6868
    6969/** The root device driver structure. */
    70 static driver_t rootia32_driver = {
     70static driver_t rootpc_driver = {
    7171        .name = NAME,
    72         .driver_ops = &rootia32_ops
     72        .driver_ops = &rootpc_ops
    7373};
    7474
     
    8282};
    8383
    84 static rootia32_child_dev_data_t pci_data = {
     84static rootpc_child_dev_data_t pci_data = {
    8585        .hw_resources = {
    8686                1,
     
    8989};
    9090
    91 static hw_resource_list_t *rootia32_get_child_resources(device_t *dev)
    92 {
    93         rootia32_child_dev_data_t *data;
    94        
    95         data = (rootia32_child_dev_data_t *) dev->driver_data;
     91static hw_resource_list_t *rootpc_get_child_resources(device_t *dev)
     92{
     93        rootpc_child_dev_data_t *data;
     94       
     95        data = (rootpc_child_dev_data_t *) dev->driver_data;
    9696        if (NULL == data)
    9797                return NULL;
     
    100100}
    101101
    102 static bool rootia32_enable_child_interrupt(device_t *dev)
     102static bool rootpc_enable_child_interrupt(device_t *dev)
    103103{
    104104        /* TODO */
     
    108108
    109109static resource_iface_t child_res_iface = {
    110         &rootia32_get_child_resources,
    111         &rootia32_enable_child_interrupt
    112 };
    113 
    114 /* Initialized in root_ia32_init() function. */
    115 static device_ops_t rootia32_child_ops;
     110        &rootpc_get_child_resources,
     111        &rootpc_enable_child_interrupt
     112};
     113
     114/* Initialized in root_pc_init() function. */
     115static device_ops_t rootpc_child_ops;
    116116
    117117static bool
    118 rootia32_add_child(device_t *parent, const char *name, const char *str_match_id,
    119     rootia32_child_dev_data_t *drv_data)
     118rootpc_add_child(device_t *parent, const char *name, const char *str_match_id,
     119    rootpc_child_dev_data_t *drv_data)
    120120{
    121121        printf(NAME ": adding new child device '%s'.\n", name);
     
    142142       
    143143        /* Set provided operations to the device. */
    144         child->ops = &rootia32_child_ops;
     144        child->ops = &rootpc_child_ops;
    145145       
    146146        /* Register child device. */
     
    164164}
    165165
    166 static bool rootia32_add_children(device_t *dev)
    167 {
    168         return rootia32_add_child(dev, "pci0", "intel_pci", &pci_data);
     166static bool rootpc_add_children(device_t *dev)
     167{
     168        return rootpc_add_child(dev, "pci0", "intel_pci", &pci_data);
    169169}
    170170
     
    175175 * @return              Zero on success, negative error number otherwise.
    176176 */
    177 static int rootia32_add_device(device_t *dev)
    178 {
    179         printf(NAME ": rootia32_add_device, device handle = %d\n", dev->handle);
     177static int rootpc_add_device(device_t *dev)
     178{
     179        printf(NAME ": rootpc_add_device, device handle = %d\n",
     180            (int)dev->handle);
    180181       
    181182        /* Register child devices. */
    182         if (!rootia32_add_children(dev)) {
     183        if (!rootpc_add_children(dev)) {
    183184                printf(NAME ": failed to add child devices for platform "
    184185                    "ia32.\n");
     
    188189}
    189190
    190 static void root_ia32_init(void)
    191 {
    192         rootia32_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
     191static void root_pc_init(void)
     192{
     193        rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
    193194}
    194195
    195196int main(int argc, char *argv[])
    196197{
    197         printf(NAME ": HelenOS rootia32 device driver\n");
    198         root_ia32_init();
    199         return driver_main(&rootia32_driver);
     198        printf(NAME ": HelenOS rootpc device driver\n");
     199        root_pc_init();
     200        return driver_main(&rootpc_driver);
    200201}
    201202
  • uspace/lib/c/generic/adt/char_map.c

    r07b9203e rfe2333d  
    9090        }
    9191
    92         map->items[map->next]->c = * identifier;
    93         ++ identifier;
    94         ++ map->next;
    95         if ((length > 1) || ((length == 0) && (*identifier))) {
     92        map->items[map->next]->c = *identifier;
     93        identifier++;
     94        map->next++;
     95        if ((length > 1) || ((length == 0) && *identifier)) {
    9696                map->items[map->next - 1]->value = CHAR_MAP_NULL;
    9797                return char_map_add_item(map->items[map->next - 1], identifier,
     
    142142    const int value)
    143143{
    144         if (char_map_is_valid(map) && (identifier) &&
    145             ((length) || (*identifier))) {
     144        if (char_map_is_valid(map) && identifier && (length || *identifier)) {
    146145                int index;
    147146
    148                 for (index = 0; index < map->next; ++ index) {
     147                for (index = 0; index < map->next; index++) {
    149148                        if (map->items[index]->c != *identifier)
    150149                                continue;
    151150                               
    152                         ++ identifier;
    153                         if((length > 1) || ((length == 0) && (*identifier))) {
     151                        identifier++;
     152                        if((length > 1) || ((length == 0) && *identifier)) {
    154153                                return char_map_add(map->items[index],
    155154                                    identifier, length ? length - 1 : 0, value);
     
    178177
    179178                map->magic = 0;
    180                 for (index = 0; index < map->next; ++index)
     179                for (index = 0; index < map->next; index++)
    181180                        char_map_destroy(map->items[index]);
    182181
     
    207206                return NULL;
    208207
    209         if (length || (*identifier)) {
     208        if (length || *identifier) {
    210209                int index;
    211210
    212                 for (index = 0; index < map->next; ++index) {
     211                for (index = 0; index < map->next; index++) {
    213212                        if (map->items[index]->c == *identifier) {
    214                                 ++identifier;
     213                                identifier++;
    215214                                if (length == 1)
    216215                                        return map->items[index];
  • uspace/lib/c/generic/devman.c

    r07b9203e rfe2333d  
    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/c/include/adt/generic_field.h

    r07b9203e rfe2333d  
    9191                        } \
    9292                        field->items[field->next] = value; \
    93                         ++field->next; \
     93                        field->next++; \
    9494                        field->items[field->next] = NULL; \
    9595                        return field->next - 1; \
     
    108108                        int index; \
    109109                        field->magic = 0; \
    110                         for (index = 0; index < field->next; ++ index) { \
     110                        for (index = 0; index < field->next; index++) { \
    111111                                if (field->items[index]) \
    112112                                        free(field->items[index]); \
  • uspace/lib/c/include/errno.h

    r07b9203e rfe2333d  
    8383#define ENOTCONN        (-10057)
    8484
    85 /** The requested operation was not performed.
    86  *  Try again later.
    87  */
    88 #define TRY_AGAIN       (-11002)
     85/** The requested operation was not performed. Try again later. */
     86#define EAGAIN          (-11002)
    8987
    9088/** No data.
  • uspace/lib/c/include/ipc/vfs.h

    r07b9203e rfe2333d  
    3636#define LIBC_IPC_VFS_H_
    3737
     38#include <ipc/ipc.h>
    3839#include <sys/types.h>
    39 #include <ipc/ipc.h>
     40#include <bool.h>
    4041
    4142#define FS_NAME_MAXLEN  20
     
    5556        /** Unique identifier of the fs. */
    5657        char name[FS_NAME_MAXLEN + 1];
     58        bool concurrent_read_write;
     59        bool write_retains_size;
    5760} vfs_info_t;
    5861
  • uspace/lib/drv/generic/driver.c

    r07b9203e rfe2333d  
    381381}
    382382
     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
    383436int driver_main(driver_t *drv)
    384437{
  • uspace/lib/drv/include/driver.h

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    516516/** Notify driver about the devices to which it was assigned.
    517517 *
    518  * The driver's mutex must be locked.
    519  *
    520518 * @param driver        The driver to which the devices are passed.
    521519 */
     
    526524        int phone;
    527525
    528         printf(NAME ": pass_devices_to_driver\n");
    529 
    530         phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
    531         if (phone > 0) {
    532                
     526        printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name);
     527
     528        fibril_mutex_lock(&driver->driver_mutex);
     529
     530        phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
     531
     532        if (phone < 0) {
     533                fibril_mutex_unlock(&driver->driver_mutex);
     534                return;
     535        }
     536
     537        /*
     538         * Go through devices list as long as there is some device
     539         * that has not been passed to the driver.
     540         */
     541        link = driver->devices.next;
     542        while (link != &driver->devices) {
     543                dev = list_get_instance(link, node_t, driver_devices);
     544                if (dev->passed_to_driver) {
     545                        link = link->next;
     546                        continue;
     547                }
     548
     549                /*
     550                 * We remove the device from the list to allow safe adding
     551                 * of new devices (no one will touch our item this way).
     552                 */
     553                list_remove(link);
     554
     555                /*
     556                 * Unlock to avoid deadlock when adding device
     557                 * handled by itself.
     558                 */
     559                fibril_mutex_unlock(&driver->driver_mutex);
     560
     561                add_device(phone, driver, dev, tree);
     562
     563                /*
     564                 * Lock again as we will work with driver's
     565                 * structure.
     566                 */
     567                fibril_mutex_lock(&driver->driver_mutex);
     568
     569                /*
     570                 * Insert the device back.
     571                 * The order is not relevant here so no harm is done
     572                 * (actually, the order would be preserved in most cases).
     573                 */
     574                list_append(link, &driver->devices);
     575
     576                /*
     577                 * Restart the cycle to go through all devices again.
     578                 */
    533579                link = driver->devices.next;
    534                 while (link != &driver->devices) {
    535                         dev = list_get_instance(link, node_t, driver_devices);
    536                         add_device(phone, driver, dev, tree);
    537                         link = link->next;
    538                 }
    539                
    540                 ipc_hangup(phone);
    541         }
     580        }
     581
     582        ipc_hangup(phone);
     583
     584        /*
     585         * Once we passed all devices to the driver, we need to mark the
     586         * driver as running.
     587         * It is vital to do it here and inside critical section.
     588         *
     589         * If we would change the state earlier, other devices added to
     590         * the driver would be added to the device list and started
     591         * immediately and possibly started here as well.
     592         */
     593        printf(NAME ": driver %s goes into running state.\n", driver->name);
     594        driver->state = DRIVER_RUNNING;
     595
     596        fibril_mutex_unlock(&driver->driver_mutex);
    542597}
    543598
     
    553608void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
    554609{
    555         printf(NAME ": initialize_running_driver\n");
    556         fibril_mutex_lock(&driver->driver_mutex);
     610        printf(NAME ": initialize_running_driver (`%s')\n", driver->name);
    557611       
    558612        /*
     
    561615         */
    562616        pass_devices_to_driver(driver, tree);
    563        
    564         /* Change driver's state to running. */
    565         driver->state = DRIVER_RUNNING;
    566        
    567         fibril_mutex_unlock(&driver->driver_mutex);
    568617}
    569618
     
    637686}
    638687
     688static FIBRIL_MUTEX_INITIALIZE(add_device_guard);
    639689
    640690/** Pass a device to running driver.
     
    645695void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
    646696{
    647         printf(NAME ": add_device\n");
     697        fibril_mutex_lock(&add_device_guard);
     698
     699        /*
     700         * We do not expect to have driver's mutex locked as we do not
     701         * access any structures that would affect driver_t.
     702         */
     703        printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
     704            node->name);
    648705       
    649706        ipcarg_t rc;
     
    657714                parent_handle = 0;
    658715        }
     716
    659717        aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
    660718            parent_handle, &answer);
     
    666724                /* TODO handle error */
    667725        }
    668        
     726
    669727        /* Wait for answer from the driver. */
    670728        async_wait_for(req, &rc);
     729
     730        fibril_mutex_unlock(&add_device_guard);
     731
    671732        switch(rc) {
    672733        case EOK:
     
    681742        }
    682743       
     744        node->passed_to_driver = true;
     745
    683746        return;
    684747}
     
    706769        attach_driver(node, drv);
    707770       
     771        fibril_mutex_lock(&drv->driver_mutex);
    708772        if (drv->state == DRIVER_NOT_STARTED) {
    709773                /* Start the driver. */
    710774                start_driver(drv);
    711775        }
    712        
    713         if (drv->state == DRIVER_RUNNING) {
     776        bool is_running = drv->state == DRIVER_RUNNING;
     777        fibril_mutex_unlock(&drv->driver_mutex);
     778
     779        if (is_running) {
    714780                /* Notify the driver about the new device. */
    715                 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     781                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
    716782                if (phone > 0) {
    717783                        add_device(phone, drv, node, tree);
     
    875941        node->name = dev_name;
    876942        if (!set_dev_path(node, parent)) {
    877                 fibril_rwlock_write_unlock(&tree->rwlock);
    878943                return false;
    879944        }
     
    10971162        while (link != &class_list->classes) {
    10981163                cl = list_get_instance(link, dev_class_t, link);
    1099                 if (str_cmp(cl->name, class_name) == 0)
     1164                if (str_cmp(cl->name, class_name) == 0) {
    11001165                        return cl;
     1166                }
     1167                link = link->next;
    11011168        }
    11021169       
  • uspace/srv/devman/devman.h

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    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

    r07b9203e rfe2333d  
    4646        if (str_cmp(driver->id, device->id) == 0) {
    4747                /*
    48                  * The strings matches, return their score multiplied.
     48                 * The strings match, return the product of their scores.
    4949                 */
    5050                return driver->score * device->score;
     
    6666       
    6767        /*
    68          * Go through all pairs, return the highest score obtainetd.
     68         * Go through all pairs, return the highest score obtained.
    6969         */
    7070        int highest_score = 0;
  • uspace/srv/fs/devfs/devfs.c

    r07b9203e rfe2333d  
    5353static vfs_info_t devfs_vfs_info = {
    5454        .name = NAME,
     55        .concurrent_read_write = false,
     56        .write_retains_size = false,
    5557};
    5658
  • uspace/srv/fs/fat/fat.c

    r07b9203e rfe2333d  
    5252vfs_info_t fat_vfs_info = {
    5353        .name = NAME,
     54        .concurrent_read_write = false,
     55        .write_retains_size = false,   
    5456};
    5557
  • uspace/srv/fs/tmpfs/tmpfs.c

    r07b9203e rfe2333d  
    5757vfs_info_t tmpfs_vfs_info = {
    5858        .name = NAME,
     59        .concurrent_read_write = false,
     60        .write_retains_size = false,
    5961};
    6062
  • uspace/srv/net/il/arp/arp.c

    r07b9203e rfe2333d  
    7272#define NAME  "arp"
    7373
     74/** Number of microseconds to wait for an ARP reply. */
     75#define ARP_TRANS_WAIT  1000000
     76
    7477/** ARP global data. */
    7578arp_globals_t arp_globals;
     
    7780DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t);
    7881INT_MAP_IMPLEMENT(arp_protos, arp_proto_t);
    79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t);
     82GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, arp_trans_t);
     83
     84static void arp_clear_trans(arp_trans_t *trans)
     85{
     86        if (trans->hw_addr) {
     87                free(trans->hw_addr);
     88                trans->hw_addr = NULL;
     89        }
     90        fibril_condvar_broadcast(&trans->cv);
     91}
     92
     93static void arp_clear_addr(arp_addr_t *addresses)
     94{
     95        int count;
     96        arp_trans_t *trans;
     97
     98        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
     99                trans = arp_addr_items_get_index(&addresses->values, count);
     100                if (trans)
     101                        arp_clear_trans(trans);
     102        }
     103}
     104
    80105
    81106/** Clears the device specific data.
     
    96121                        if (proto->addr_data)
    97122                                free(proto->addr_data);
     123                        arp_clear_addr(&proto->addresses);
    98124                        arp_addr_destroy(&proto->addresses);
    99125                }
     
    107133        arp_device_t *device;
    108134
    109         fibril_rwlock_write_lock(&arp_globals.lock);
     135        fibril_mutex_lock(&arp_globals.lock);
    110136        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    111137            count--) {
     
    120146        }
    121147        arp_cache_clear(&arp_globals.cache);
    122         fibril_rwlock_write_unlock(&arp_globals.lock);
     148        fibril_mutex_unlock(&arp_globals.lock);
    123149        printf("Cache cleaned\n");
    124150        return EOK;
     
    130156        arp_device_t *device;
    131157        arp_proto_t *proto;
    132 
    133         fibril_rwlock_write_lock(&arp_globals.lock);
     158        arp_trans_t *trans;
     159
     160        fibril_mutex_lock(&arp_globals.lock);
    134161        device = arp_cache_find(&arp_globals.cache, device_id);
    135162        if (!device) {
    136                 fibril_rwlock_write_unlock(&arp_globals.lock);
     163                fibril_mutex_unlock(&arp_globals.lock);
    137164                return ENOENT;
    138165        }
    139166        proto = arp_protos_find(&device->protos, protocol);
    140167        if (!proto) {
    141                 fibril_rwlock_write_unlock(&arp_globals.lock);
     168                fibril_mutex_unlock(&arp_globals.lock);
    142169                return ENOENT;
    143170        }
     171        trans = arp_addr_find(&proto->addresses, address->value, address->length);
     172        if (trans)
     173                arp_clear_trans(trans);
    144174        arp_addr_exclude(&proto->addresses, address->value, address->length);
    145         fibril_rwlock_write_unlock(&arp_globals.lock);
     175        fibril_mutex_unlock(&arp_globals.lock);
    146176        return EOK;
    147177}
     
    152182        arp_device_t *device;
    153183
    154         fibril_rwlock_write_lock(&arp_globals.lock);
     184        fibril_mutex_lock(&arp_globals.lock);
    155185        device = arp_cache_find(&arp_globals.cache, device_id);
    156186        if (!device) {
    157                 fibril_rwlock_write_unlock(&arp_globals.lock);
     187                fibril_mutex_unlock(&arp_globals.lock);
    158188                return ENOENT;
    159189        }
    160190        arp_clear_device(device);
    161191        printf("Device %d cleared\n", device_id);
    162         fibril_rwlock_write_unlock(&arp_globals.lock);
     192        fibril_mutex_unlock(&arp_globals.lock);
    163193        return EOK;
    164194}
     
    221251        int rc;
    222252
    223         fibril_rwlock_write_lock(&arp_globals.lock);
     253        fibril_mutex_lock(&arp_globals.lock);
    224254
    225255        /* An existing device? */
     
    229259                if (device->service != service) {
    230260                        printf("Device %d already exists\n", device->device_id);
    231                         fibril_rwlock_write_unlock(&arp_globals.lock);
     261                        fibril_mutex_unlock(&arp_globals.lock);
    232262                        return EEXIST;
    233263                }
     
    241271                        rc = arp_proto_create(&proto, protocol, address);
    242272                        if (rc != EOK) {
    243                                 fibril_rwlock_write_unlock(&arp_globals.lock);
     273                                fibril_mutex_unlock(&arp_globals.lock);
    244274                                return rc;
    245275                        }
     
    247277                            proto);
    248278                        if (index < 0) {
    249                                 fibril_rwlock_write_unlock(&arp_globals.lock);
     279                                fibril_mutex_unlock(&arp_globals.lock);
    250280                                free(proto);
    251281                                return index;
     
    262292                device = (arp_device_t *) malloc(sizeof(arp_device_t));
    263293                if (!device) {
    264                         fibril_rwlock_write_unlock(&arp_globals.lock);
     294                        fibril_mutex_unlock(&arp_globals.lock);
    265295                        return ENOMEM;
    266296                }
     
    269299                rc = arp_protos_initialize(&device->protos);
    270300                if (rc != EOK) {
    271                         fibril_rwlock_write_unlock(&arp_globals.lock);
     301                        fibril_mutex_unlock(&arp_globals.lock);
    272302                        free(device);
    273303                        return rc;
     
    275305                rc = arp_proto_create(&proto, protocol, address);
    276306                if (rc != EOK) {
    277                         fibril_rwlock_write_unlock(&arp_globals.lock);
     307                        fibril_mutex_unlock(&arp_globals.lock);
    278308                        free(device);
    279309                        return rc;
     
    281311                index = arp_protos_add(&device->protos, proto->service, proto);
    282312                if (index < 0) {
    283                         fibril_rwlock_write_unlock(&arp_globals.lock);
     313                        fibril_mutex_unlock(&arp_globals.lock);
    284314                        arp_protos_destroy(&device->protos);
    285315                        free(device);
     
    293323                    arp_globals.client_connection);
    294324                if (device->phone < 0) {
    295                         fibril_rwlock_write_unlock(&arp_globals.lock);
     325                        fibril_mutex_unlock(&arp_globals.lock);
    296326                        arp_protos_destroy(&device->protos);
    297327                        free(device);
     
    303333                    &device->packet_dimension);
    304334                if (rc != EOK) {
    305                         fibril_rwlock_write_unlock(&arp_globals.lock);
     335                        fibril_mutex_unlock(&arp_globals.lock);
    306336                        arp_protos_destroy(&device->protos);
    307337                        free(device);
     
    313343                    &device->addr_data);
    314344                if (rc != EOK) {
    315                         fibril_rwlock_write_unlock(&arp_globals.lock);
     345                        fibril_mutex_unlock(&arp_globals.lock);
    316346                        arp_protos_destroy(&device->protos);
    317347                        free(device);
     
    323353                    &device->broadcast_addr, &device->broadcast_data);
    324354                if (rc != EOK) {
    325                         fibril_rwlock_write_unlock(&arp_globals.lock);
     355                        fibril_mutex_unlock(&arp_globals.lock);
    326356                        free(device->addr);
    327357                        free(device->addr_data);
     
    334364                    device);
    335365                if (rc != EOK) {
    336                         fibril_rwlock_write_unlock(&arp_globals.lock);
     366                        fibril_mutex_unlock(&arp_globals.lock);
    337367                        free(device->addr);
    338368                        free(device->addr_data);
     
    347377                    device->service, protocol);
    348378        }
    349         fibril_rwlock_write_unlock(&arp_globals.lock);
     379        fibril_mutex_unlock(&arp_globals.lock);
    350380       
    351381        return EOK;
     
    363393        int rc;
    364394
    365         fibril_rwlock_initialize(&arp_globals.lock);
    366         fibril_rwlock_write_lock(&arp_globals.lock);
     395        fibril_mutex_initialize(&arp_globals.lock);
     396        fibril_mutex_lock(&arp_globals.lock);
    367397        arp_globals.client_connection = client_connection;
    368398        rc = arp_cache_initialize(&arp_globals.cache);
    369         fibril_rwlock_write_unlock(&arp_globals.lock);
     399        fibril_mutex_unlock(&arp_globals.lock);
    370400       
    371401        return rc;
     
    383413        arp_device_t *device;
    384414
    385         fibril_rwlock_write_lock(&arp_globals.lock);
     415        fibril_mutex_lock(&arp_globals.lock);
    386416        device = arp_cache_find(&arp_globals.cache, device_id);
    387417        if (!device) {
    388                 fibril_rwlock_write_unlock(&arp_globals.lock);
     418                fibril_mutex_unlock(&arp_globals.lock);
    389419                return ENOENT;
    390420        }
    391421        device->packet_dimension.content = mtu;
    392         fibril_rwlock_write_unlock(&arp_globals.lock);
     422        fibril_mutex_unlock(&arp_globals.lock);
    393423        printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu);
    394424        return EOK;
     
    421451        arp_device_t *device;
    422452        arp_proto_t *proto;
    423         measured_string_t *hw_source;
     453        arp_trans_t *trans;
    424454        uint8_t *src_hw;
    425455        uint8_t *src_proto;
     
    452482        des_hw = src_proto + header->protocol_length;
    453483        des_proto = des_hw + header->hardware_length;
    454         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto,
     484        trans = arp_addr_find(&proto->addresses, (char *) src_proto,
    455485            CONVERT_SIZE(uint8_t, char, header->protocol_length));
    456486        /* Exists? */
    457         if (hw_source) {
    458                 if (hw_source->length != CONVERT_SIZE(uint8_t, char,
     487        if (trans && trans->hw_addr) {
     488                if (trans->hw_addr->length != CONVERT_SIZE(uint8_t, char,
    459489                    header->hardware_length)) {
    460490                        return EINVAL;
    461491                }
    462                 memcpy(hw_source->value, src_hw, hw_source->length);
     492                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    463493        }
    464494        /* Is my protocol address? */
     
    470500            proto->addr->length)) {
    471501                /* Not already updated? */
    472                 if (!hw_source) {
    473                         hw_source = measured_string_create_bulk((char *) src_hw,
    474                             CONVERT_SIZE(uint8_t, char,
     502                if (!trans) {
     503                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     504                        if (!trans)
     505                                return ENOMEM;
     506                        trans->hw_addr = NULL;
     507                        fibril_condvar_initialize(&trans->cv);
     508                        rc = arp_addr_add(&proto->addresses, (char *) src_proto,
     509                            CONVERT_SIZE(uint8_t, char, header->protocol_length),
     510                            trans);
     511                        if (rc != EOK) {
     512                                /* The generic char map has already freed trans! */
     513                                return rc;
     514                        }
     515                }
     516                if (!trans->hw_addr) {
     517                        trans->hw_addr = measured_string_create_bulk(
     518                            (char *) src_hw, CONVERT_SIZE(uint8_t, char,
    475519                            header->hardware_length));
    476                         if (!hw_source)
     520                        if (!trans->hw_addr)
    477521                                return ENOMEM;
    478522
    479                         rc = arp_addr_add(&proto->addresses, (char *) src_proto,
    480                             CONVERT_SIZE(uint8_t, char,
    481                             header->protocol_length), hw_source);
    482                         if (rc != EOK)
    483                                 return rc;
     523                        /* Notify the fibrils that wait for the translation. */
     524                        fibril_condvar_broadcast(&trans->cv);
    484525                }
    485526                if (ntohs(header->operation) == ARPOP_REQUEST) {
     
    490531                        memcpy(src_hw, device->addr->value,
    491532                            device->packet_dimension.addr_len);
    492                         memcpy(des_hw, hw_source->value,
     533                        memcpy(des_hw, trans->hw_addr->value,
    493534                            header->hardware_length);
    494535                       
     
    516557 * @param[in] protocol  The protocol service.
    517558 * @param[in] target    The target protocol address.
    518  * @return              The hardware address of the target.
    519  * @return              NULL if the target parameter is NULL.
    520  * @return              NULL if the device is not found.
    521  * @return              NULL if the device packet is too small to send a
    522  *                      request.
    523  * @return              NULL if the hardware address is not found in the cache.
    524  */
    525 static measured_string_t *
     559 * @param[out] translation Where the hardware address of the target is stored.
     560 * @return              EOK on success.
     561 * @return              EAGAIN if the caller should try again.
     562 * @return              Other error codes in case of error.
     563 */
     564static int
    526565arp_translate_message(device_id_t device_id, services_t protocol,
    527     measured_string_t *target)
     566    measured_string_t *target, measured_string_t **translation)
    528567{
    529568        arp_device_t *device;
    530569        arp_proto_t *proto;
    531         measured_string_t *addr;
     570        arp_trans_t *trans;
    532571        size_t length;
    533572        packet_t *packet;
    534573        arp_header_t *header;
    535 
    536         if (!target)
    537                 return NULL;
     574        bool retry = false;
     575        int rc;
     576
     577restart:
     578        if (!target || !translation)
     579                return EBADMEM;
    538580
    539581        device = arp_cache_find(&arp_globals.cache, device_id);
    540582        if (!device)
    541                 return NULL;
     583                return ENOENT;
    542584
    543585        proto = arp_protos_find(&device->protos, protocol);
    544586        if (!proto || (proto->addr->length != target->length))
    545                 return NULL;
    546 
    547         addr = arp_addr_find(&proto->addresses, target->value, target->length);
    548         if (addr)
    549                 return addr;
     587                return ENOENT;
     588
     589        trans = arp_addr_find(&proto->addresses, target->value, target->length);
     590        if (trans) {
     591                if (trans->hw_addr) {
     592                        *translation = trans->hw_addr;
     593                        return EOK;
     594                }
     595                if (retry)
     596                        return EAGAIN;
     597                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     598                    ARP_TRANS_WAIT);
     599                if (rc == ETIMEOUT)
     600                        return ENOENT;
     601                retry = true;
     602                goto restart;
     603        }
     604        if (retry)
     605                return EAGAIN;
    550606
    551607        /* ARP packet content size = header + (address + translation) * 2 */
     
    553609            CONVERT_SIZE(char, uint8_t, device->addr->length));
    554610        if (length > device->packet_dimension.content)
    555                 return NULL;
     611                return ELIMIT;
    556612
    557613        packet = packet_get_4_remote(arp_globals.net_phone,
     
    559615            length, device->packet_dimension.suffix);
    560616        if (!packet)
    561                 return NULL;
     617                return ENOMEM;
    562618
    563619        header = (arp_header_t *) packet_suffix(packet, length);
    564620        if (!header) {
    565621                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    566                 return NULL;
     622                return ENOMEM;
    567623        }
    568624
     
    583639        memcpy(((uint8_t *) header) + length, target->value, target->length);
    584640
    585         if (packet_set_addr(packet, (uint8_t *) device->addr->value,
     641        rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
    586642            (uint8_t *) device->broadcast_addr->value,
    587             CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) {
     643            CONVERT_SIZE(char, uint8_t, device->addr->length));
     644        if (rc != EOK) {
    588645                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    589                 return NULL;
     646                return rc;
    590647        }
    591648
    592649        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    593         return NULL;
     650
     651        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     652        if (!trans)
     653                return ENOMEM;
     654        trans->hw_addr = NULL;
     655        fibril_condvar_initialize(&trans->cv);
     656        rc = arp_addr_add(&proto->addresses, target->value, target->length,
     657            trans);
     658        if (rc != EOK) {
     659                /* The generic char map has already freed trans! */
     660                return rc;
     661        }
     662       
     663        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     664            ARP_TRANS_WAIT);
     665        if (rc == ETIMEOUT)
     666                return ENOENT;
     667        retry = true;
     668        goto restart;
    594669}
    595670
     
    642717                        return rc;
    643718               
    644                 fibril_rwlock_read_lock(&arp_globals.lock);
    645                 translation = arp_translate_message(IPC_GET_DEVICE(call),
    646                     IPC_GET_SERVICE(call), address);
     719                fibril_mutex_lock(&arp_globals.lock);
     720                rc = arp_translate_message(IPC_GET_DEVICE(call),
     721                    IPC_GET_SERVICE(call), address, &translation);
    647722                free(address);
    648723                free(data);
     724                if (rc != EOK) {
     725                        fibril_mutex_unlock(&arp_globals.lock);
     726                        return rc;
     727                }
    649728                if (!translation) {
    650                         fibril_rwlock_read_unlock(&arp_globals.lock);
     729                        fibril_mutex_unlock(&arp_globals.lock);
    651730                        return ENOENT;
    652731                }
    653732                rc = measured_strings_reply(translation, 1);
    654                 fibril_rwlock_read_unlock(&arp_globals.lock);
     733                fibril_mutex_unlock(&arp_globals.lock);
    655734                return rc;
    656735
     
    682761                        return rc;
    683762               
    684                 fibril_rwlock_read_lock(&arp_globals.lock);
     763                fibril_mutex_lock(&arp_globals.lock);
    685764                do {
    686765                        next = pq_detach(packet);
     
    692771                        packet = next;
    693772                } while (packet);
    694                 fibril_rwlock_read_unlock(&arp_globals.lock);
     773                fibril_mutex_unlock(&arp_globals.lock);
    695774               
    696775                return EOK;
  • uspace/srv/net/il/arp/arp.h

    r07b9203e rfe2333d  
    6565typedef struct arp_proto arp_proto_t;
    6666
     67/** Type definition of the ARP address translation record.
     68 * @see arp_trans
     69 */
     70typedef struct arp_trans arp_trans_t;
     71
    6772/** ARP address map.
    6873 *
     
    7075 * @see generic_char_map.h
    7176 */
    72 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t);
     77GENERIC_CHAR_MAP_DECLARE(arp_addr, arp_trans_t);
    7378
    7479/** ARP address cache.
     
    8994struct arp_device {
    9095        /** Actual device hardware address. */
    91         measured_string_t * addr;
     96        measured_string_t *addr;
    9297        /** Actual device hardware address data. */
    9398        char *addr_data;
    9499        /** Broadcast device hardware address. */
    95         measured_string_t * broadcast_addr;
     100        measured_string_t *broadcast_addr;
    96101        /** Broadcast device hardware address data. */
    97102        char *broadcast_data;
     
    129134        int net_phone;
    130135        /** Safety lock. */
    131         fibril_rwlock_t lock;
     136        fibril_mutex_t lock;
    132137};
    133138
     
    144149};
    145150
     151/** ARP address translation record. */
     152struct arp_trans {
     153        /**
     154         * Hardware address for the translation. NULL denotes an incomplete
     155         * record with possible waiters.
     156         */
     157        measured_string_t *hw_addr;
     158        /** Condition variable used for waiting for completion of the record. */
     159        fibril_condvar_t cv;
     160};
     161
    146162#endif
    147163
    148164/** @}
    149165 */
     166
  • uspace/srv/vfs/vfs.h

    r07b9203e rfe2333d  
    172172
    173173extern fs_handle_t fs_name_to_handle(char *, bool);
     174extern vfs_info_t *fs_handle_to_info(fs_handle_t);
    174175
    175176extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
  • uspace/srv/vfs/vfs_ops.c

    r07b9203e rfe2333d  
    781781static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    782782{
     783        vfs_info_t *vi;
    783784
    784785        /*
     
    807808        fibril_mutex_lock(&file->lock);
    808809
     810        vi = fs_handle_to_info(file->node->fs_handle);
     811        assert(vi);
     812
    809813        /*
    810814         * Lock the file's node so that no other client can read/write to it at
    811          * the same time.
    812          */
    813         if (read)
     815         * the same time unless the FS supports concurrent reads/writes and its
     816         * write implementation does not modify the file size.
     817         */
     818        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    814819                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    815820        else
     
    857862       
    858863        /* Unlock the VFS node. */
    859         if (read)
     864        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    860865                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    861866        else {
  • uspace/srv/vfs/vfs_register.c

    r07b9203e rfe2333d  
    333333}
    334334
     335/** Find the VFS info structure.
     336 *
     337 * @param handle        FS handle for which the VFS info structure is sought.
     338 * @return              VFS info structure on success or NULL otherwise.
     339 */
     340vfs_info_t *fs_handle_to_info(fs_handle_t handle)
     341{
     342        vfs_info_t *info = NULL;
     343        link_t *cur;
     344
     345        fibril_mutex_lock(&fs_head_lock);
     346        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     347                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
     348                if (fs->fs_handle == handle) {
     349                        info = &fs->vfs_info;
     350                        break;
     351                }
     352        }
     353        fibril_mutex_unlock(&fs_head_lock);
     354
     355        return info;
     356}
     357
    335358/**
    336359 * @}
Note: See TracChangeset for help on using the changeset viewer.