Changeset 1a5b252 in mainline for uspace/drv


Ignore:
Timestamp:
2011-08-21T11:54:15Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8cc4ddb
Parents:
e64df9a
Message:

DDF support for function offlining and onlining. This allows
(anticipated) hot removal — support needs to be added in individual
drivers, currently there is support in test1 and partially in rootvirt.
Surprise removal is not supported. TODO synchronization.

Location:
uspace/drv
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/infrastructure/rootvirt/rootvirt.c

    re64df9a r1a5b252  
    6363
    6464static int rootvirt_add_device(ddf_dev_t *dev);
     65static int rootvirt_fun_online(ddf_fun_t *fun);
     66static int rootvirt_fun_offline(ddf_fun_t *fun);
    6567
    6668static driver_ops_t rootvirt_ops = {
    67         .add_device = &rootvirt_add_device
     69        .add_device = &rootvirt_add_device,
     70        .fun_online = &rootvirt_fun_online,
     71        .fun_offline = &rootvirt_fun_offline
    6872};
    6973
     
    140144}
    141145
     146static int rootvirt_fun_online(ddf_fun_t *fun)
     147{
     148        ddf_msg(LVL_DEBUG, "rootvirt_fun_online()");
     149        return ddf_fun_online(fun);
     150}
     151
     152static int rootvirt_fun_offline(ddf_fun_t *fun)
     153{
     154        ddf_msg(LVL_DEBUG, "rootvirt_fun_offline()");
     155        return ddf_fun_offline(fun);
     156}
     157
    142158int main(int argc, char *argv[])
    143159{
  • uspace/drv/test/test1/test1.c

    re64df9a r1a5b252  
    11/*
    22 * Copyright (c) 2010 Vojtech Horky
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4041
    4142static int test1_add_device(ddf_dev_t *dev);
     43static int test1_dev_remove(ddf_dev_t *dev);
     44static int test1_fun_online(ddf_fun_t *fun);
     45static int test1_fun_offline(ddf_fun_t *fun);
    4246
    4347static driver_ops_t driver_ops = {
    44         .add_device = &test1_add_device
     48        .add_device = &test1_add_device,
     49        .dev_remove = &test1_dev_remove,
     50        .fun_online = &test1_fun_online,
     51        .fun_offline = &test1_fun_offline
    4552};
    4653
     
    4956        .driver_ops = &driver_ops
    5057};
     58
     59typedef struct {
     60        ddf_fun_t *fun_a;
     61        ddf_fun_t *clone;
     62        ddf_fun_t *child;
     63} test1_t;
    5164
    5265/** Register child and inform user about it.
     
    6073static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    6174    const char *name, const char *match_id, int match_score,
    62     int expected_rc)
     75    int expected_rc, ddf_fun_t **pfun)
    6376{
    6477        ddf_fun_t *fun = NULL;
     
    103116        }
    104117
     118        if (pfun != NULL)
     119                *pfun = fun;
     120
    105121        return rc;
    106122}
     
    126142{
    127143        ddf_fun_t *fun_a;
     144        test1_t *test1;
    128145        int rc;
    129146
    130147        ddf_msg(LVL_DEBUG, "add_device(name=\"%s\", handle=%d)",
    131148            dev->name, (int) dev->handle);
     149
     150        test1 = calloc(1, sizeof(test1_t));
     151        if (test1 == NULL) {
     152                ddf_msg(LVL_ERROR, "Failed allocating softstate.\n");
     153                return ENOMEM;
     154        }
    132155
    133156        fun_a = ddf_fun_create(dev, fun_exposed, "a");
     
    140163        if (rc != EOK) {
    141164                ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
     165                ddf_fun_destroy(fun_a);
    142166                return rc;
    143167        }
     
    151175                (void) register_fun_verbose(dev,
    152176                    "cloning myself ;-)", "clone",
    153                     "virtual&test1", 10, EOK);
     177                    "virtual&test1", 10, EOK, &test1->clone);
    154178                (void) register_fun_verbose(dev,
    155179                    "cloning myself twice ;-)", "clone",
    156                     "virtual&test1", 10, EEXISTS);
     180                    "virtual&test1", 10, EEXISTS, NULL);
    157181        } else if (str_cmp(dev->name, "clone") == 0) {
    158182                (void) register_fun_verbose(dev,
    159183                    "run by the same task", "child",
    160                     "virtual&test1&child", 10, EOK);
     184                    "virtual&test1&child", 10, EOK, &test1->child);
    161185        }
    162186
    163187        ddf_msg(LVL_DEBUG, "Device `%s' accepted.", dev->name);
    164188
     189        test1->fun_a = fun_a;
     190        dev->driver_data = test1;
    165191        return EOK;
     192}
     193
     194static int fun_remove(ddf_fun_t *fun, const char *name)
     195{
     196        int rc;
     197
     198        ddf_msg(LVL_DEBUG, "fun_remove(%p, '%s')\n", fun, name);
     199        rc = ddf_fun_offline(fun);
     200        if (rc != EOK) {
     201                ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name);
     202                return rc;
     203        }
     204
     205        rc = ddf_fun_unbind(fun);
     206        if (rc != EOK) {
     207                ddf_msg(LVL_ERROR, "Failed offlining function '%s'.", name);
     208                return rc;
     209        }
     210
     211        ddf_fun_destroy(fun);
     212        return EOK;
     213}
     214
     215static int test1_dev_remove(ddf_dev_t *dev)
     216{
     217        test1_t *test1 = (test1_t *)dev->driver_data;
     218        int rc;
     219
     220        ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev);
     221
     222        if (test1->fun_a != NULL) {
     223                rc = fun_remove(test1->fun_a, "a");
     224                if (rc != EOK)
     225                        return rc;
     226        }
     227
     228        if (test1->clone != NULL) {
     229                rc = fun_remove(test1->clone, "clone");
     230                if (rc != EOK)
     231                        return rc;
     232        }
     233
     234        if (test1->child != NULL) {
     235                rc = fun_remove(test1->child, "child");
     236                if (rc != EOK)
     237                        return rc;
     238        }
     239
     240        return EOK;
     241}
     242
     243static int test1_fun_online(ddf_fun_t *fun)
     244{
     245        ddf_msg(LVL_DEBUG, "test1_fun_online()");
     246        return ddf_fun_online(fun);
     247}
     248
     249static int test1_fun_offline(ddf_fun_t *fun)
     250{
     251        ddf_msg(LVL_DEBUG, "test1_fun_offline()");
     252        return ddf_fun_offline(fun);
    166253}
    167254
Note: See TracChangeset for help on using the changeset viewer.