Changeset ec7f8b1 in mainline


Ignore:
Timestamp:
2011-08-21T15:35:03Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb74dabe
Parents:
c4a8e4a (diff), 5935c079 (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:
3 added
19 edited
1 moved

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/asm.h

    rc4a8e4a rec7f8b1  
    4141#include <trace.h>
    4242
     43#define IO_SPACE_BOUNDARY       ((void *) (64 * 1024))
     44
    4345/** Return base address of current stack.
    4446 *
     
    7779}
    7880
    79 #define IO_SPACE_BOUNDARY       ((void *) (64 * 1024))
    80 
    8181/** Byte from port
    8282 *
     
    9191        if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
    9292                uint8_t val;
     93               
    9394                asm volatile (
    9495                        "inb %w[port], %b[val]\n"
     
    9697                        : [port] "d" (port)
    9798                );
     99               
    98100                return val;
    99         } else {
     101        } else
    100102                return (uint8_t) *port;
    101         }
    102103}
    103104
     
    114115        if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
    115116                uint16_t val;
     117               
    116118                asm volatile (
    117119                        "inw %w[port], %w[val]\n"
     
    119121                        : [port] "d" (port)
    120122                );
     123               
    121124                return val;
    122         } else {
     125        } else
    123126                return (uint16_t) *port;
    124         }
    125127}
    126128
     
    137139        if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
    138140                uint32_t val;
     141               
    139142                asm volatile (
    140143                        "inl %w[port], %[val]\n"
     
    142145                        : [port] "d" (port)
    143146                );
     147               
    144148                return val;
    145         } else {
     149        } else
    146150                return (uint32_t) *port;
    147         }
    148151}
    149152
     
    163166                        :: [val] "a" (val), [port] "d" (port)
    164167                );     
    165         } else {
     168        } else
    166169                *port = val;
    167         }
    168170}
    169171
     
    183185                        :: [val] "a" (val), [port] "d" (port)
    184186                );
    185         } else {
     187        } else
    186188                *port = val;
    187         }
    188189}
    189190
     
    203204                        :: [val] "a" (val), [port] "d" (port)
    204205                );
    205         } else {
     206        } else
    206207                *port = val;
    207         }
    208208}
    209209
  • kernel/arch/ia32/include/asm.h

    rc4a8e4a rec7f8b1  
    118118                        :: [val] "a" (val), [port] "d" (port)
    119119                );     
    120         } else {
     120        } else
    121121                *port = val;
    122         }
    123122}
    124123
     
    138137                        :: [val] "a" (val), [port] "d" (port)
    139138                );
    140         } else {
     139        } else
    141140                *port = val;
    142         }
    143141}
    144142
     
    158156                        :: [val] "a" (val), [port] "d" (port)
    159157                );
    160         } else {
     158        } else
    161159                *port = val;
    162         }
    163160}
    164161
     
    175172        if (((void *)port) < IO_SPACE_BOUNDARY) {
    176173                uint8_t val;
     174               
    177175                asm volatile (
    178176                        "inb %w[port], %b[val]\n"
     
    180178                        : [port] "d" (port)
    181179                );
     180               
    182181                return val;
    183         } else {
     182        } else
    184183                return (uint8_t) *port;
    185         }
    186184}
    187185
     
    198196        if (((void *)port) < IO_SPACE_BOUNDARY) {
    199197                uint16_t val;
     198               
    200199                asm volatile (
    201200                        "inw %w[port], %w[val]\n"
     
    203202                        : [port] "d" (port)
    204203                );
     204               
    205205                return val;
    206         } else {
     206        } else
    207207                return (uint16_t) *port;
    208         }
    209208}
    210209
     
    221220        if (((void *)port) < IO_SPACE_BOUNDARY) {
    222221                uint32_t val;
     222               
    223223                asm volatile (
    224224                        "inl %w[port], %[val]\n"
     
    226226                        : [port] "d" (port)
    227227                );
     228               
    228229                return val;
    229         } else {
     230        } else
    230231                return (uint32_t) *port;
    231         }
    232232}
    233233
  • uspace/Makefile

    rc4a8e4a rec7f8b1  
    176176        lib/block \
    177177        lib/clui \
     178        lib/fmtutil \
    178179        lib/scsi \
    179180        lib/softint \
  • uspace/Makefile.common

    rc4a8e4a rec7f8b1  
    112112LIBIMGMAP_PREFIX = $(LIB_PREFIX)/imgmap
    113113LIBCLUI_PREFIX = $(LIB_PREFIX)/clui
     114LIBFMTUTIL_PREFIX = $(LIB_PREFIX)/fmtutil
    114115
    115116LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
  • uspace/app/bdsh/Makefile

    rc4a8e4a rec7f8b1  
    2929
    3030USPACE_PREFIX = ../..
    31 LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBCLUI_PREFIX)/libclui.a
    32 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBCLUI_PREFIX) -I. -Icmds/ \
    33         -Icmds/builtins -Icmds/modules
     31LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBCLUI_PREFIX)/libclui.a \
     32        $(LIBFMTUTIL_PREFIX)/libfmtutil.a
     33EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBCLUI_PREFIX) \
     34        -I$(LIBFMTUTIL_PREFIX) -I. -Icmds/ -Icmds/builtins -Icmds/modules
    3435BINARY = bdsh
    3536
  • uspace/app/bdsh/cmds/modules/help/help.c

    rc4a8e4a rec7f8b1  
    11/*
    22 * Copyright (c) 2008 Tim Post
     3 * Copyright (c) 2011 Martin Sucha
    34 * All rights reserved.
    45 *
     
    3031#include <stdlib.h>
    3132#include <str.h>
     33#include <fmtutil.h>
    3234
    3335#include "config.h"
     
    128130static void help_survival(void)
    129131{
    130         printf("Don't panic!\n\n");
    131 
    132         printf("This is Bdsh, the Brain dead shell, currently "
     132        print_wrapped_console(
     133            "Don't panic!\n\n"
     134
     135            "This is Bdsh, the Brain dead shell, currently "
    133136            "the primary user interface to HelenOS. Bdsh allows you to enter "
    134137            "commands and supports history (Up, Down arrow keys), "
    135138            "line editing (Left Arrow, Right Arrow, Home, End, Backspace), "
    136139            "selection (Shift + movement keys), copy and paste (Ctrl-C, "
    137             "Ctrl-V), similar to common desktop environments.\n\n");
    138 
    139         printf("The most basic filesystem commands are Bdsh builtins. Type "
     140            "Ctrl-V), similar to common desktop environments.\n\n"
     141
     142            "The most basic filesystem commands are Bdsh builtins. Type "
    140143            "'help commands' [Enter] to see the list of Bdsh builtin commands. "
    141144            "Other commands are external executables located in the /app and "
    142145            "/srv directories. Type 'ls /app' [Enter] and 'ls /srv' [Enter] "
    143146            "to see their list. You can execute an external command simply "
    144             "by entering its name (e.g. type 'tetris' [Enter]).\n\n");
    145 
    146         printf("HelenOS has virtual consoles (VCs). You can switch between "
    147             "these using the F1-F11 keys.\n\n");
    148 
    149         printf("This is but a small glimpse of what you can do with HelenOS. "
     147            "by entering its name (e.g. type 'tetris' [Enter]).\n\n"
     148
     149            "HelenOS has virtual consoles (VCs). You can switch between "
     150            "these using the F1-F11 keys.\n\n"
     151
     152            "This is but a small glimpse of what you can do with HelenOS. "
    150153            "To learn more please point your browser to the HelenOS User's "
    151             "Guide: http://trac.helenos.org/trac.fcgi/wiki/UsersGuide\n\n");
     154            "Guide: http://trac.helenos.org/wiki/UsersGuide\n\n",
     155            ALIGN_LEFT);
    152156}
    153157
  • uspace/app/bdsh/compl.c

    rc4a8e4a rec7f8b1  
    9090{
    9191        compl_t *cs = NULL;
    92         size_t pref_size;
    9392        char *stext = NULL;
    9493        char *prefix = NULL;
    9594        char *dirname = NULL;
     95        int retval;
     96       
     97        token_t *tokens = calloc(WORD_MAX, sizeof(token_t));
     98        if (tokens == NULL) {
     99                retval = ENOMEM;
     100                goto error;
     101        }
     102       
     103        size_t pref_size;
    96104        char *rpath_sep;
    97105        static const char *dirlist_arg[] = { ".", NULL };
    98         int retval;
    99106        tokenizer_t tok;
    100         token_t tokens[WORD_MAX];
    101         unsigned int current_token;
     107        ssize_t current_token;
    102108        size_t tokens_length;
    103 
     109       
    104110        cs = calloc(1, sizeof(compl_t));
    105111        if (!cs) {
     
    107113                goto error;
    108114        }
    109 
     115       
    110116        /* Convert text buffer to string */
    111117        stext = wstr_to_astr(text);
     
    127133       
    128134        /* Find the current token */
    129         for (current_token = 0; current_token < tokens_length; current_token++) {
     135        for (current_token = 0; current_token < (ssize_t) tokens_length;
     136            current_token++) {
    130137                token_t *t = &tokens[current_token];
    131138                size_t end = t->char_start + t->char_length;
    132                 /* Check if the caret lies inside the token or immediately
     139               
     140                /*
     141                 * Check if the caret lies inside the token or immediately
    133142                 * after it
    134143                 */
     
    138147        }
    139148       
    140         if (tokens[current_token].type != TOKTYPE_SPACE) {
     149        if (tokens_length == 0)
     150                current_token = -1;
     151       
     152        if ((current_token >= 0) && (tokens[current_token].type != TOKTYPE_SPACE))
    141153                *cstart = tokens[current_token].char_start;
    142         }
    143         else {
     154        else
    144155                *cstart = pos;
    145         }
    146        
    147         /* Extract the prefix being completed
     156       
     157        /*
     158         * Extract the prefix being completed
    148159         * XXX: handle strings, etc.
    149160         */
     
    154165                goto error;
    155166        }
    156 
    157         str_ncpy(prefix, pref_size + 1, stext +
    158             tokens[current_token].byte_start, pref_size);
     167        prefix[pref_size] = 0;
     168
     169        if (current_token >= 0) {
     170                str_ncpy(prefix, pref_size + 1, stext +
     171                    tokens[current_token].byte_start, pref_size);
     172        }
    159173
    160174        /*
     
    165179
    166180        /* Skip any whitespace before current token */
    167         int prev_token = current_token - 1;
    168         if (prev_token != -1 && tokens[prev_token].type == TOKTYPE_SPACE) {
     181        ssize_t prev_token = current_token - 1;
     182        if ((prev_token >= 0) && (tokens[prev_token].type == TOKTYPE_SPACE))
    169183                prev_token--;
    170         }
    171 
     184       
    172185        /*
    173186         * It is a command if it is the first token or if it immediately
    174187         * follows a pipe token.
    175188         */
    176         if (prev_token == -1 || tokens[prev_token].type == TOKTYPE_SPACE)
     189        if ((prev_token < 0) || (tokens[prev_token].type == TOKTYPE_SPACE))
    177190                cs->is_command = true;
    178191        else
     
    249262        if (cs != NULL)
    250263                free(cs);
     264        if (tokens != NULL)
     265                free(tokens);
    251266
    252267        return retval;
  • uspace/app/bdsh/input.c

    rc4a8e4a rec7f8b1  
    6767int process_input(cliuser_t *usr)
    6868{
     69        token_t *tokens = calloc(WORD_MAX, sizeof(token_t));
     70        if (tokens == NULL)
     71                return ENOMEM;
     72       
    6973        char *cmd[WORD_MAX];
    70         token_t tokens_space[WORD_MAX];
    71         token_t *tokens = tokens_space;
    7274        int rc = 0;
    7375        tokenizer_t tok;
     
    7779        char *redir_to = NULL;
    7880
    79         if (NULL == usr->line)
     81        if (usr->line == NULL) {
     82                free(tokens);
    8083                return CL_EFAIL;
     84        }
    8185
    8286        rc = tok_init(&tok, usr->line, tokens, WORD_MAX);
     
    209213        }
    210214        tok_fini(&tok);
     215        free(tokens);
    211216
    212217        return rc;
  • uspace/app/tester/stdio/stdio1.c

    rc4a8e4a rec7f8b1  
    3939{
    4040        FILE *file;
    41         const char *file_name = "/readme";
     41        const char *file_name = "/textdemo";
    4242       
    4343        TPRINTF("Open file \"%s\"...", file_name);
  • uspace/dist/src/sysel/demos/htxtfile.sy

    rc4a8e4a rec7f8b1  
    3535                var out_file : TextFile;
    3636
    37                 name = "/readme";
     37                name = "/textdemo";
    3838
    3939                in_file = new TextFile();
  • uspace/lib/c/arch/ia32/include/ddi.h

    rc4a8e4a rec7f8b1  
    4343        if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
    4444                uint8_t val;
     45               
    4546                asm volatile (
    4647                        "inb %w[port], %b[val]\n"
     
    4849                        : [port] "d" (port)
    4950                );
     51               
    5052                return val;
    51         } else {
     53        } else
    5254                return (uint8_t) *port;
    53         }
    5455}
    5556
     
    5859        if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
    5960                uint16_t val;
     61               
    6062                asm volatile (
    6163                        "inw %w[port], %w[val]\n"
     
    6365                        : [port] "d" (port)
    6466                );
     67               
    6568                return val;
    66         } else {
     69        } else
    6770                return (uint16_t) *port;
    68         }
    6971}
    7072
     
    7375        if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
    7476                uint32_t val;
     77               
    7578                asm volatile (
    7679                        "inl %w[port], %[val]\n"
     
    7881                        : [port] "d" (port)
    7982                );
     83               
    8084                return val;
    81         } else {
     85        } else
    8286                return (uint32_t) *port;
    83         }
    8487}
    8588
     
    9194                        :: [val] "a" (val), [port] "d" (port)
    9295                );     
    93         } else {
     96        } else
    9497                *port = val;
    95         }
    9698}
    9799
     
    103105                        :: [val] "a" (val), [port] "d" (port)
    104106                );
    105         } else {
     107        } else
    106108                *port = val;
    107         }
    108109}
    109110
     
    115116                        :: [val] "a" (val), [port] "d" (port)
    116117                );
    117         } else {
     118        } else
    118119                *port = val;
    119         }
    120120}
    121121
  • uspace/lib/c/generic/async.c

    rc4a8e4a rec7f8b1  
    16561656       
    16571657        return sess;
     1658}
     1659
     1660/** Set arguments for new connections.
     1661 *
     1662 * FIXME This is an ugly hack to work around the problem that parallel
     1663 * exchanges are implemented using parallel connections. When we create
     1664 * a callback session, the framework does not know arguments for the new
     1665 * connections.
     1666 *
     1667 * The proper solution seems to be to implement parallel exchanges using
     1668 * tagging.
     1669 */
     1670void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2,
     1671    sysarg_t arg3)
     1672{
     1673        sess->arg1 = arg1;
     1674        sess->arg2 = arg2;
     1675        sess->arg3 = arg3;
    16581676}
    16591677
  • uspace/lib/c/generic/devman.c

    rc4a8e4a rec7f8b1  
    8989                        if (devman_driver_block_sess == NULL)
    9090                                devman_driver_block_sess =
    91                                     service_connect_blocking(EXCHANGE_SERIALIZE,
     91                                    service_connect_blocking(EXCHANGE_PARALLEL,
    9292                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9393                }
     
    138138                if (devman_driver_sess == NULL)
    139139                        devman_driver_sess =
    140                             service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     140                            service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
    141141                            DEVMAN_DRIVER, 0);
    142142               
  • uspace/lib/c/generic/ns.c

    rc4a8e4a rec7f8b1  
    5656        async_exchange_end(exch);
    5757       
     58        /*
     59         * FIXME Ugly hack to work around limitation of implementing
     60         * parallel exchanges using multiple connections. Shift out
     61         * first argument for non-initial connections.
     62         */
     63        async_sess_args_set(sess, arg2, arg3, 0);
     64       
    5865        return sess;
    5966}
     
    6673            async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3);
    6774        async_exchange_end(exch);
     75       
     76        /*
     77         * FIXME Ugly hack to work around limitation of implementing
     78         * parallel exchanges using multiple connections. Shift out
     79         * first argument for non-initial connections.
     80         */
     81        async_sess_args_set(sess, arg2, arg3, 0);
    6882       
    6983        return sess;
  • uspace/lib/c/generic/str.c

    rc4a8e4a rec7f8b1  
    22 * Copyright (c) 2005 Martin Decky
    33 * Copyright (c) 2008 Jiri Svoboda
     4 * Copyright (c) 2011 Martin Sucha
    45 * All rights reserved.
    56 *
     
    718719
    719720        dest[dlen - 1] = '\0';
     721}
     722
     723/** Convert string to wide string.
     724 *
     725 * Convert string @a src to wide string. A new wide NULL-terminated
     726 * string will be allocated on the heap.
     727 *
     728 * @param src   Source string.
     729 */
     730wchar_t *str_to_awstr(const char *str)
     731{
     732        size_t len = str_length(str);
     733       
     734        wchar_t *wstr = calloc(len+1, sizeof(wchar_t));
     735        if (wstr == NULL)
     736                return NULL;
     737       
     738        str_to_wstr(wstr, len + 1, str);
     739        return wstr;
    720740}
    721741
  • uspace/lib/c/include/async.h

    rc4a8e4a rec7f8b1  
    337337
    338338/*
     339 * FIXME These functions just work around problems with parallel exchange
     340 * management. Proper solution needs to be implemented.
     341 */
     342void async_sess_args_set(async_sess_t *sess, sysarg_t, sysarg_t, sysarg_t);
     343
     344/*
    339345 * User-friendly wrappers for async_share_in_start().
    340346 */
  • uspace/lib/c/include/str.h

    rc4a8e4a rec7f8b1  
    8383extern char *wstr_to_astr(const wchar_t *src);
    8484extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
     85extern wchar_t *str_to_awstr(const char *src);
    8586
    8687extern char *str_chr(const char *str, wchar_t ch);
  • uspace/srv/devman/devman.h

    rc4a8e4a rec7f8b1  
    6363typedef struct fun_node fun_node_t;
    6464
     65typedef struct {
     66        fibril_mutex_t mutex;
     67        struct driver *driver;
     68} client_t;
     69
    6570typedef enum {
    6671        /** Driver has not been started. */
  • uspace/srv/devman/main.c

    rc4a8e4a rec7f8b1  
    6565static dev_tree_t device_tree;
    6666
     67static int init_running_drv(void *drv);
     68
    6769/** Register running driver. */
    68 static driver_t *devman_driver_register(void)
    69 {
    70         ipc_call_t icall;
    71         ipc_callid_t iid;
     70static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call)
     71{
    7272        driver_t *driver = NULL;
     73        char *drv_name = NULL;
    7374
    7475        log_msg(LVL_DEBUG, "devman_driver_register");
    75        
    76         iid = async_get_call(&icall);
    77         if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
    78                 async_answer_0(iid, EREFUSED);
    79                 return NULL;
    80         }
    81        
    82         char *drv_name = NULL;
    8376       
    8477        /* Get driver name. */
    8578        int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
    8679        if (rc != EOK) {
    87                 async_answer_0(iid, rc);
     80                async_answer_0(callid, rc);
    8881                return NULL;
    8982        }
     
    9891                free(drv_name);
    9992                drv_name = NULL;
    100                 async_answer_0(iid, ENOENT);
     93                async_answer_0(callid, ENOENT);
    10194                return NULL;
    10295        }
     
    112105                    driver->name);
    113106                fibril_mutex_unlock(&driver->driver_mutex);
    114                 async_answer_0(iid, EEXISTS);
     107                async_answer_0(callid, EEXISTS);
    115108                return NULL;
    116109        }
     
    134127        log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
    135128            driver->name);
    136         driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
     129        driver->sess = async_callback_receive(EXCHANGE_PARALLEL);
    137130        if (!driver->sess) {
    138131                fibril_mutex_unlock(&driver->driver_mutex);
    139                 async_answer_0(iid, ENOTSUP);
     132                async_answer_0(callid, ENOTSUP);
    140133                return NULL;
    141134        }
    142        
    143         fibril_mutex_unlock(&driver->driver_mutex);
     135        /* FIXME: Work around problem with callback sessions */
     136        async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);
    144137       
    145138        log_msg(LVL_NOTE,
     
    147140            driver->name);
    148141       
    149         async_answer_0(iid, EOK);
    150        
     142        /*
     143         * Initialize the driver as running (e.g. pass assigned devices to it)
     144         * in a separate fibril; the separate fibril is used to enable the
     145         * driver to use devman service during the driver's initialization.
     146         */
     147        fid_t fid = fibril_create(init_running_drv, driver);
     148        if (fid == 0) {
     149                log_msg(LVL_ERROR, "Failed to create initialization fibril " \
     150                    "for driver `%s'.", driver->name);
     151                fibril_mutex_unlock(&driver->driver_mutex);
     152                async_answer_0(callid, ENOMEM);
     153                return NULL;
     154        }
     155       
     156        fibril_add_ready(fid);
     157        fibril_mutex_unlock(&driver->driver_mutex);
     158       
     159        async_answer_0(callid, EOK);
    151160        return driver;
    152161}
     
    429438static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    430439{
     440        client_t *client;
     441        driver_t *driver;
     442       
    431443        /* Accept the connection. */
    432444        async_answer_0(iid, EOK);
    433445       
    434         driver_t *driver = devman_driver_register();
    435         if (driver == NULL)
    436                 return;
    437        
    438         /*
    439          * Initialize the driver as running (e.g. pass assigned devices to it)
    440          * in a separate fibril; the separate fibril is used to enable the
    441          * driver to use devman service during the driver's initialization.
    442          */
    443         fid_t fid = fibril_create(init_running_drv, driver);
    444         if (fid == 0) {
    445                 log_msg(LVL_ERROR, "Failed to create initialization fibril " \
    446                     "for driver `%s'.", driver->name);
    447                 return;
    448         }
    449         fibril_add_ready(fid);
     446        client = async_get_client_data();
     447        if (client == NULL) {
     448                log_msg(LVL_ERROR, "Failed to allocate client data.");
     449                return;
     450        }
    450451       
    451452        while (true) {
     
    456457                        break;
    457458               
     459                if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
     460                        fibril_mutex_lock(&client->mutex);
     461                        driver = client->driver;
     462                        fibril_mutex_unlock(&client->mutex);
     463                        if (driver == NULL) {
     464                                /* First call must be to DEVMAN_DRIVER_REGISTER */
     465                                async_answer_0(callid, ENOTSUP);
     466                                continue;
     467                        }
     468                }
     469               
    458470                switch (IPC_GET_IMETHOD(call)) {
     471                case DEVMAN_DRIVER_REGISTER:
     472                        fibril_mutex_lock(&client->mutex);
     473                        if (client->driver != NULL) {
     474                                fibril_mutex_unlock(&client->mutex);
     475                                async_answer_0(callid, EINVAL);
     476                                continue;
     477                        }
     478                        client->driver = devman_driver_register(callid, &call);
     479                        fibril_mutex_unlock(&client->mutex);
     480                        break;
    459481                case DEVMAN_ADD_FUNCTION:
    460482                        devman_add_function(callid, &call);
     
    814836static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    815837{
    816         /* Select interface. */
     838        /* Select port. */
    817839        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    818840        case DEVMAN_DRIVER:
     
    840862}
    841863
     864static void *devman_client_data_create(void)
     865{
     866        client_t *client;
     867       
     868        client = calloc(1, sizeof(client_t));
     869        if (client == NULL)
     870                return NULL;
     871       
     872        fibril_mutex_initialize(&client->mutex);
     873        return client;
     874}
     875
     876static void devman_client_data_destroy(void *data)
     877{
     878        free(data);
     879}
     880
    842881/** Initialize device manager internal structures. */
    843882static bool devman_init(void)
     
    886925        }
    887926       
    888         /* Set a handler of incomming connections. */
     927        /* Set handlers for incoming connections. */
     928        async_set_client_data_constructor(devman_client_data_create);
     929        async_set_client_data_destructor(devman_client_data_destroy);
    889930        async_set_client_connection(devman_connection);
    890931
Note: See TracChangeset for help on using the changeset viewer.