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/infrastructure/rootvirt/rootvirt.c

    rbb74dabe rc05642d  
    6363
    6464static int rootvirt_add_device(ddf_dev_t *dev);
     65static int rootvirt_dev_remove(ddf_dev_t *dev);
     66static int rootvirt_fun_online(ddf_fun_t *fun);
     67static int rootvirt_fun_offline(ddf_fun_t *fun);
    6568
    6669static driver_ops_t rootvirt_ops = {
    67         .add_device = &rootvirt_add_device
     70        .add_device = &rootvirt_add_device,
     71        .dev_remove = &rootvirt_dev_remove,
     72        .fun_online = &rootvirt_fun_online,
     73        .fun_offline = &rootvirt_fun_offline
    6874};
    6975
     
    7379};
    7480
     81/* Device soft state */
     82typedef struct {
     83        ddf_dev_t *dev;
     84        list_t functions;
     85} rootvirt_t;
     86
     87/* Function soft state */
     88typedef struct {
     89        ddf_fun_t *fun;
     90        link_t dev_link;
     91} rootvirt_fun_t;
     92
     93static int instances = 0;
     94
     95
    7596/** Add function to the virtual device.
    7697 *
     
    79100 * @return              EOK on success or negative error code.
    80101 */
    81 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun)
    82 {
     102static int rootvirt_add_fun(rootvirt_t *rootvirt, virtual_function_t *vfun)
     103{
     104        ddf_dev_t *vdev = rootvirt->dev;
    83105        ddf_fun_t *fun;
     106        rootvirt_fun_t *rvfun;
    84107        int rc;
    85108
     
    93116        }
    94117
     118        rvfun = ddf_fun_data_alloc(fun, sizeof(rootvirt_fun_t));
     119        if (rvfun == NULL) {
     120                ddf_msg(LVL_ERROR, "Failed allocating soft state for %s.",
     121                    vfun->name);
     122                ddf_fun_destroy(fun);
     123                return ENOMEM;
     124        }
     125
     126        rvfun->fun = fun;
     127
    95128        rc = ddf_fun_add_match_id(fun, vfun->match_id, 10);
    96129        if (rc != EOK) {
     
    109142        }
    110143
     144        list_append(&rvfun->dev_link, &rootvirt->functions);
     145
    111146        ddf_msg(LVL_NOTE, "Registered child device `%s'", vfun->name);
    112147        return EOK;
    113148}
    114149
     150static int rootvirt_fun_remove(rootvirt_fun_t *rvfun)
     151{
     152        int rc;
     153        const char *name = rvfun->fun->name;
     154
     155        ddf_msg(LVL_DEBUG, "rootvirt_fun_remove('%s')", name);
     156        rc = ddf_fun_offline(rvfun->fun);
     157        if (rc != EOK) {
     158                ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name);
     159                return rc;
     160        }
     161
     162        rc = ddf_fun_unbind(rvfun->fun);
     163        if (rc != EOK) {
     164                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
     165                return rc;
     166        }
     167
     168        list_remove(&rvfun->dev_link);
     169        ddf_fun_destroy(rvfun->fun);
     170        return EOK;
     171}
     172
     173
    115174static int rootvirt_add_device(ddf_dev_t *dev)
    116175{
    117         static int instances = 0;
     176        rootvirt_t *rootvirt;
    118177
    119178        /*
    120179         * Allow only single instance of root virtual device.
    121180         */
    122         instances++;
    123         if (instances > 1) {
     181        if (++instances > 1) {
    124182                return ELIMIT;
    125183        }
    126184
    127185        ddf_msg(LVL_DEBUG, "add_device(handle=%d)", (int)dev->handle);
     186
     187        rootvirt = ddf_dev_data_alloc(dev, sizeof(rootvirt_t));
     188        if (rootvirt == NULL)
     189                return ENOMEM;
     190
     191        rootvirt->dev = dev;
     192        list_initialize(&rootvirt->functions);
    128193
    129194        /*
     
    133198        virtual_function_t *vfun = virtual_functions;
    134199        while (vfun->name != NULL) {
    135                 (void) rootvirt_add_fun(dev, vfun);
     200                (void) rootvirt_add_fun(rootvirt, vfun);
    136201                vfun++;
    137202        }
    138203
    139204        return EOK;
     205}
     206
     207static int rootvirt_dev_remove(ddf_dev_t *dev)
     208{
     209        rootvirt_t *rootvirt = (rootvirt_t *)dev->driver_data;
     210        int rc;
     211
     212        while (!list_empty(&rootvirt->functions)) {
     213                rootvirt_fun_t *rvfun = list_get_instance(
     214                    list_first(&rootvirt->functions), rootvirt_fun_t,
     215                        dev_link);
     216
     217                rc = rootvirt_fun_remove(rvfun);
     218                if (rc != EOK)
     219                        return rc;
     220        }
     221
     222        --instances;
     223        return EOK;
     224}
     225
     226static int rootvirt_fun_online(ddf_fun_t *fun)
     227{
     228        ddf_msg(LVL_DEBUG, "rootvirt_fun_online()");
     229        return ddf_fun_online(fun);
     230}
     231
     232static int rootvirt_fun_offline(ddf_fun_t *fun)
     233{
     234        ddf_msg(LVL_DEBUG, "rootvirt_fun_offline()");
     235        return ddf_fun_offline(fun);
    140236}
    141237
Note: See TracChangeset for help on using the changeset viewer.