Changeset c05642d in mainline for uspace/drv/test/test2/test2.c


Ignore:
Timestamp:
2011-09-07T00:03:26Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5081276
Parents:
bb74dabe (diff), 038b289 (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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/test/test2/test2.c

    rbb74dabe rc05642d  
    4141
    4242static int test2_add_device(ddf_dev_t *dev);
     43static int test2_dev_remove(ddf_dev_t *dev);
     44static int test2_dev_gone(ddf_dev_t *dev);
     45static int test2_fun_online(ddf_fun_t *fun);
     46static int test2_fun_offline(ddf_fun_t *fun);
    4347
    4448static driver_ops_t driver_ops = {
    45         .add_device = &test2_add_device
     49        .add_device = &test2_add_device,
     50        .dev_remove = &test2_dev_remove,
     51        .dev_gone = &test2_dev_gone,
     52        .fun_online = &test2_fun_online,
     53        .fun_offline = &test2_fun_offline
    4654};
    4755
     
    5058        .driver_ops = &driver_ops
    5159};
     60
     61/* Device soft state */
     62typedef struct {
     63        ddf_dev_t *dev;
     64
     65        ddf_fun_t *fun_a;
     66        ddf_fun_t *fun_err;
     67        ddf_fun_t *child;
     68        ddf_fun_t *test1;
     69} test2_t;
    5270
    5371/** Register child and inform user about it.
     
    6078 */
    6179static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    62     const char *name, const char *match_id, int match_score)
     80    const char *name, const char *match_id, int match_score, ddf_fun_t **pfun)
    6381{
    6482        ddf_fun_t *fun;
     
    89107        }
    90108
     109        *pfun = fun;
     110
    91111        ddf_msg(LVL_NOTE, "Registered child device `%s'", name);
    92112        return EOK;
    93113}
    94114
    95 /** Add child devices after some sleep.
     115/** Simulate plugging and surprise unplugging.
    96116 *
    97117 * @param arg Parent device structure (ddf_dev_t *).
    98118 * @return Always EOK.
    99119 */
    100 static int postponed_birth(void *arg)
    101 {
    102         ddf_dev_t *dev = (ddf_dev_t *) arg;
     120static int plug_unplug(void *arg)
     121{
     122        test2_t *test2 = (test2_t *) arg;
    103123        ddf_fun_t *fun_a;
    104124        int rc;
     
    106126        async_usleep(1000);
    107127
    108         (void) register_fun_verbose(dev, "child driven by the same task",
    109             "child", "virtual&test2", 10);
    110         (void) register_fun_verbose(dev, "child driven by test1",
    111             "test1", "virtual&test1", 10);
    112 
    113         fun_a = ddf_fun_create(dev, fun_exposed, "a");
     128        (void) register_fun_verbose(test2->dev, "child driven by the same task",
     129            "child", "virtual&test2", 10, &test2->child);
     130        (void) register_fun_verbose(test2->dev, "child driven by test1",
     131            "test1", "virtual&test1", 10, &test2->test1);
     132
     133        fun_a = ddf_fun_create(test2->dev, fun_exposed, "a");
    114134        if (fun_a == NULL) {
    115135                ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
     
    124144
    125145        ddf_fun_add_to_category(fun_a, "virtual");
    126 
     146        test2->fun_a = fun_a;
     147
     148        async_usleep(10000000);
     149
     150        ddf_msg(LVL_NOTE, "Unbinding function test1.");
     151        ddf_fun_unbind(test2->test1);
     152        async_usleep(1000000);
     153        ddf_msg(LVL_NOTE, "Unbinding function child.");
     154        ddf_fun_unbind(test2->child);
     155
     156        return EOK;
     157}
     158
     159static int fun_remove(ddf_fun_t *fun, const char *name)
     160{
     161        int rc;
     162
     163        ddf_msg(LVL_DEBUG, "fun_remove(%p, '%s')", fun, name);
     164        rc = ddf_fun_offline(fun);
     165        if (rc != EOK) {
     166                ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name);
     167                return rc;
     168        }
     169
     170        rc = ddf_fun_unbind(fun);
     171        if (rc != EOK) {
     172                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
     173                return rc;
     174        }
     175
     176        ddf_fun_destroy(fun);
     177        return EOK;
     178}
     179
     180static int fun_unbind(ddf_fun_t *fun, const char *name)
     181{
     182        int rc;
     183
     184        ddf_msg(LVL_DEBUG, "fun_unbind(%p, '%s')", fun, name);
     185        rc = ddf_fun_unbind(fun);
     186        if (rc != EOK) {
     187                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
     188                return rc;
     189        }
     190
     191        ddf_fun_destroy(fun);
    127192        return EOK;
    128193}
     
    130195static int test2_add_device(ddf_dev_t *dev)
    131196{
     197        test2_t *test2;
     198
    132199        ddf_msg(LVL_DEBUG, "test2_add_device(name=\"%s\", handle=%d)",
    133200            dev->name, (int) dev->handle);
    134201
     202        test2 = ddf_dev_data_alloc(dev, sizeof(test2_t));
     203        if (test2 == NULL) {
     204                ddf_msg(LVL_ERROR, "Failed allocating soft state.");
     205                return ENOMEM;
     206        }
     207
     208        test2->dev = dev;
     209
    135210        if (str_cmp(dev->name, "child") != 0) {
    136                 fid_t postpone = fibril_create(postponed_birth, dev);
     211                fid_t postpone = fibril_create(plug_unplug, test2);
    137212                if (postpone == 0) {
    138213                        ddf_msg(LVL_ERROR, "fibril_create() failed.");
     
    142217        } else {
    143218                (void) register_fun_verbose(dev, "child without available driver",
    144                     "ERROR", "non-existent.match.id", 10);
    145         }
    146 
    147         return EOK;
     219                    "ERROR", "non-existent.match.id", 10, &test2->fun_err);
     220        }
     221
     222        return EOK;
     223}
     224
     225static int test2_dev_remove(ddf_dev_t *dev)
     226{
     227        test2_t *test2 = (test2_t *)dev->driver_data;
     228        int rc;
     229
     230        ddf_msg(LVL_DEBUG, "test2_dev_remove(%p)", dev);
     231
     232        if (test2->fun_a != NULL) {
     233                rc = fun_remove(test2->fun_a, "a");
     234                if (rc != EOK)
     235                        return rc;
     236        }
     237
     238        if (test2->fun_err != NULL) {
     239                rc = fun_remove(test2->fun_err, "ERROR");
     240                if (rc != EOK)
     241                        return rc;
     242        }
     243
     244        if (test2->child != NULL) {
     245                rc = fun_remove(test2->child, "child");
     246                if (rc != EOK)
     247                        return rc;
     248        }
     249
     250        if (test2->test1 != NULL) {
     251                rc = fun_remove(test2->test1, "test1");
     252                if (rc != EOK)
     253                        return rc;
     254        }
     255
     256        return EOK;
     257}
     258
     259static int test2_dev_gone(ddf_dev_t *dev)
     260{
     261        test2_t *test2 = (test2_t *)dev->driver_data;
     262        int rc;
     263
     264        ddf_msg(LVL_DEBUG, "test2_dev_gone(%p)", dev);
     265
     266        if (test2->fun_a != NULL) {
     267                rc = fun_unbind(test2->fun_a, "a");
     268                if (rc != EOK)
     269                        return rc;
     270        }
     271
     272        if (test2->fun_err != NULL) {
     273                rc = fun_unbind(test2->fun_err, "ERROR");
     274                if (rc != EOK)
     275                        return rc;
     276        }
     277
     278        if (test2->child != NULL) {
     279                rc = fun_unbind(test2->child, "child");
     280                if (rc != EOK)
     281                        return rc;
     282        }
     283
     284        if (test2->test1 != NULL) {
     285                rc = fun_unbind(test2->test1, "test1");
     286                if (rc != EOK)
     287                        return rc;
     288        }
     289
     290        return EOK;
     291}
     292
     293
     294static int test2_fun_online(ddf_fun_t *fun)
     295{
     296        ddf_msg(LVL_DEBUG, "test2_fun_online()");
     297        return ddf_fun_online(fun);
     298}
     299
     300static int test2_fun_offline(ddf_fun_t *fun)
     301{
     302        ddf_msg(LVL_DEBUG, "test2_fun_offline()");
     303        return ddf_fun_offline(fun);
    148304}
    149305
     
    151307{
    152308        printf(NAME ": HelenOS test2 virtual device driver\n");
    153         ddf_log_init(NAME, LVL_ERROR);
     309        ddf_log_init(NAME, LVL_NOTE);
    154310        return ddf_driver_main(&test2_driver);
    155311}
Note: See TracChangeset for help on using the changeset viewer.